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