微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将CV2图像正确转换为wxImage以在wxPython中显示

如何解决如何将CV2图像正确转换为wxImage以在wxPython中显示

我试图创建使用Python的面部识别库来识别图像中的面部,然后在使用wxPython制作的GUI应用程序中显示该图像。为了显示图像,我想我需要将cv2图像转换为wxImage,以便可以在界面中显示它。这是我的代码,用于转换图像并将其设置为面板中的wx.StaticBitmap:

# Convert the image
img = wx.Image(500,500) # Declare a wxImage
img.SetData(image.tobytes()) # image is a OpenCV iamge,set the data to the wxImage
self.imageCtrl.SetBitmap(wx.Bitmap(img)) # imageCtrl is a wx.StaticImage
self.Refresh() # Refresh the panel with the new image

运行代码时,它不会返回任何错误,但这是结果:resulting image

如果我只是使用cv2.imshow打开cv2图像,则会得到该图像的外观:expected image

这是我的完整程序:

import face_recognition  # Library that is actually going to let us recognize faces
import wx  # Used to create
import cv2  # Used to draw rectangles and label images
import os  # Used to iterate over directories


class FaceRecPanel(wx.Panel):
    def __init__(self,parent):
        super().__init__(parent)

        self.createWidgets()

    '''
    CREATE ALL ELEMENTS FOR FaceRecPanel
    '''

    def createWidgets(self):
        form_sizer = wx.BoxSizer(wx.VERTICAL)
        image_path_sizer = wx.BoxSizer(wx.HORIZONTAL)
        model_sizer = wx.BoxSizer(wx.HORIZONTAL)
        tolerance_sizer = wx.BoxSizer(wx.HORIZONTAL)
        run_sizer = wx.BoxSizer(wx.HORIZONTAL)

        # Declare image path elements
        self.image_path_button = wx.Button(self,label='Select Path')
        self.image_path_button.Bind(wx.EVT_BUTTON,self.select_image)
        self.image_path_text = wx.TextCtrl(self,size=(200,-1))

        # Declare model elements
        self.model_label = wx.StaticText(self,label='Model: ')
        self.model_radio1 = wx.RadioButton(
            self,label='hog',style=wx.RB_GROUP)
        self.model_radio2 = wx.RadioButton(self,label='cnn')

        # Declare tolerance elements
        self.tolerance_label = wx.StaticText(self,label='Tolerance: ')
        self.tolerance_input = wx.TextCtrl(self)
        self.tolerance_input.write('0.6')

        # Declare run button
        self.run_button = wx.Button(self,label='Run')
        self.run_button.Bind(wx.EVT_BUTTON,self.run_face_rec)

        # Declare run message label
        self.message_text = wx.StaticText(self,label='')

        img = wx.Image(500,500)
        self.imageCtrl = wx.StaticBitmap(self,wx.ID_ANY,wx.Bitmap(img))

        # Add elements to the sizers
        image_path_sizer.Add(self.image_path_button,wx.ALL,5)
        image_path_sizer.Add(self.image_path_text,5)

        model_sizer.Add(self.model_label,5)
        model_sizer.Add(self.model_radio1,5)
        model_sizer.Add(self.model_radio2,5)

        tolerance_sizer.Add(self.tolerance_label,5)
        tolerance_sizer.Add(self.tolerance_input,5)

        run_sizer.Add(self.run_button,5)
        run_sizer.Add(self.message_text,5)

        form_sizer.Add(image_path_sizer,5)
        form_sizer.Add(model_sizer,5)
        form_sizer.Add(tolerance_sizer,5)
        form_sizer.Add(run_sizer,5)
        form_sizer.Add(self.imageCtrl,5)
        #form_sizer.Add(self.result_image,5)

        self.SetSizer(form_sizer)

    '''
    SET IMAGE PATH TO SELECTION FROM THE USER
    '''

    def select_image(self,event):
        # browse for a file

        # Change this to wx.DirDialog to browse for a directory instead of file
        dlg = wx.FileDialog(None,'Choose a file',style=wx.DD_DEFAULT_STYLE)

        if dlg.ShowModal() == wx.ID_OK:
            self.image_path_text.SetValue(dlg.GetPath())
        dlg.Destroy()

    '''
    RUN FACE RECOGNITION ON SELECTED IMAGE
    '''

    def run_face_rec(self,event):

        # Set the model according to user input
        if self.model_radio1.GetValue():
            model = 'hog'
        else:
            model = 'cnn'

        KNowN_FACES_DIR = "kNown_faces"  # All of our kNown faces
        FRAME_THICKnesS = 3 # How many pixels the thickness of the frame is
        FONT_THICKnesS = 2 # The thickness of the 
        # Set unkown image to the path entered by the user
        unkNown_image = self.image_path_text.GetLineText(0)

        # Set tolerance as entered by the user
        tolerance = self.tolerance_input.GetLineText(0)
        
        kNown_faces = []
        kNown_names = []

        # Organize kNown faces as subfolders of KNowN_FACES_DIR
        # Each subforder's name becomes our label name
        for name in os.listdir(KNowN_FACES_DIR):

            # Next we load every file of faces of kNown person
            for filename in os.listdir(f'{KNowN_FACES_DIR}/{name}'):

                # Load an image
                image = face_recognition.load_image_file(
                    f"{KNowN_FACES_DIR}/{name}/{filename}")

                # Get 128-dimension face encoding
                # Always returns a list of found faces,for this purpose we take the
                #   first face only. (assuming one face per image as you can't be
                #   twice on the same image.)
                encoding = face_recognition.face_encodings(image)[0]

                # Add the kNown faces and names to our lists
                
                kNown_faces.append(encoding)
                kNown_names.append(name)
        
        # Load in the filename
        image = face_recognition.load_image_file(f"{unkNown_image}")
        # find the locations/coordinates of the faces using face_recognition
        locations = face_recognition.face_locations(image,model=model)
        # create the encodings using the locations we just founds
        encodings = face_recognition.face_encodings(image,locations)
        #Convert the image so we can use it with opencv
        image = cv2.cvtColor(image,cv2.COLOR_RGB2BGR)

        # Iterate over the locations and encodings of the unkNown faces that were found
        for face_encoding,face_location in zip(encodings,locations):
            # Compare the kNown faces agaisnt the current face encoding
            results = face_recognition.compare_faces(kNown_faces,face_encoding,0.6)
            match = None

            # Check to see if there was a match found in unkNown faces agaisnt kNown faces
            if True in results:
                match = kNown_names[results.index(True)]
                print(f"Match found: {match}")

                # Get the coordinates for the match
                # To draw a rectangle,you only need the top left coordinate and the bottom right coordinate
                top_left = (face_location[3],face_location[0])
                bottom_right = (face_location[1],face_location[2])

                # This is the color of the rectangle. We call the function name_to_color and pass the name of
                # the match as an argument so we can color code the frame based on the name of the person.
                color = [200,200]
                # Draw the rectangle on the image
                cv2.rectangle(image,top_left,bottom_right,color,FRAME_THICKnesS)

                # Label the rectangle
                # Set the coordinates for the labeled rectangle
                top_left = (face_location[3],face_location[2])
                bottom_right = (face_location[1],face_location[2]+22)

                # Create a fileld rectangle so we can label it
                cv2.rectangle(image,cv2.FILLED)
                # Add the text to the image based on what the match was
                cv2.putText(image,match,(face_location[3]+10,face_location[2]+15),cv2.FONT_HERShey_SIMPLEX,0.5,(255,255,255),FONT_THICKnesS)
        
        # Test the resulting image by opening it with cv2
        cv2.imshow(filename,image)
        
        
        # Convert the image and show it using wxPython
        img = wx.Image(500,500) # Declare a wxImage
        img.SetData(image.tobytes()) # image is a OpenCV iamge,set the data to the wxImage
        self.imageCtrl.SetBitmap(wx.Bitmap(img)) # imageCtrl is a wx.StaticImage
        self.Refresh() # Refresh the panel with the new image


class FaceRecFrame(wx.Frame):
    # Constructor for Mp3Frame
    def __init__(self):
        super().__init__(parent=None,title='Face Recognition App',size=(500,700))

        self.panel = FaceRecPanel(self)

        self.Show()


if __name__ == '__main__':
    app = wx.App(False)
    frame = FaceRecFrame()
    app.MainLoop()

如何在wxPython中正确显示生成的CV2图像?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。