Проблема невозможности выполнить распознавание лиц в интерфейсе

#python #tkinter #face-recognition

Вопрос:

 from tkinter import *
import dlib
import face_recognition
import cv2
import PIL.Image, PIL.ImageTk
import time

class App:
    def __init__(self, window, window_title, video_source=0):
        self.window = window
        self.window.geometry("800x470")
        self.window.title(window_title)
        self.video_source = video_source

        # open video source (by default this will try to open the computer webcam)
        self.vid = MyVideoCapture(self.video_source)

        # Create a canvas that can fit the above video source size
        self.canvas = tkinter.Canvas(window, width = self.vid.width, height = self.vid.height)
        self.canvas.place(x=10,y=10)

        

        # After it is called once, the update method will be automatically called every delay milliseconds
        self.delay = 15
        self.update()

        self.window.mainloop()

    def snapshot(self):
        # Get a frame from the video source
        ret, frame = self.vid.get_frame()

        if ret:
            cv2.imwrite("frame-"   time.strftime("%d-%m-%Y-%H-%M-%S")   ".jpg", cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))

    def update(self):
        # Get a frame from the video source
        ret, frame = self.vid.get_frame()

        if ret:
            self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(frame))
            self.canvas.create_image(0, 0, image = self.photo, anchor = tkinter.NW)

        self.window.after(self.delay, self.update)


class MyVideoCapture:
    def __init__(self, video_source=0):
        # Open the video source
        self.vid = cv2.VideoCapture(video_source,cv2.CAP_DSHOW)
        if not self.vid.isOpened():
            raise ValueError("Video Kaynağı (Kamera) Bulunamadı!", video_source)

        # Get video source width and height
        self.width = 450
        self.height = 450

    def get_frame(self):
        if self.vid.isOpened():
            ret, frame = self.vid.read()
            if ret:
                obama_image = face_recognition.load_image_file("./faces/birinci.jpg")
                obama_face_encoding = face_recognition.face_encodings(obama_image)[0]
                known_face_encodings = [
                    obama_face_encoding
                ]
                known_face_names = [
                    "Birinci Tanınan Kişi"
                ]

                face_locations = []
                face_encodings = []
                face_names = []
                process_this_frame = True
                #======================================================
                small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)

                rgb_small_frame = small_frame[:, :, ::-1]

                if process_this_frame:
                    face_locations = face_recognition.face_locations(rgb_small_frame)
                    face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)

                    face_names = []
                    for face_encoding in face_encodings:
                        matches = face_recognition.compare_faces(known_face_encodings, face_encoding)
                        name = "Tanınmayan"


                        face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
                        best_match_index = np.argmin(face_distances)
                        if matches[best_match_index]:
                            name = known_face_names[best_match_index]

                        face_names.append(name)

                process_this_frame = not process_this_frame


                for (top, right, bottom, left), name in zip(face_locations, face_names):
                    top *= 4
                    right *= 4
                    bottom *= 4
                    left *= 4

                    cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)

                    cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
                    font = cv2.FONT_HERSHEY_DUPLEX
                    cv2.putText(frame, name, (left   6, bottom - 6), font, 1.0, (255, 255, 255), 1)
                    return frame
            else:
                return (ret, None)
        else:
            return (ret, None)

    # Release the video source when the object is destroyed
    def __del__(self):
        if self.vid.isOpened():
            self.vid.release()  
#Create a window and pass it to the Application object
App(tkinter.Tk(), "Yüz Tanıma")

 

Приветствую, я получил коды распознавания лиц из источника, затем я хотел перенести их в интерфейс. Но я не мог распознать лица в интерфейсе. И это дало эту ошибку.

     Traceback (most recent call last):
  File "interface.py", line 124, in <module>
    App(tkinter.Tk(), "Yüz Tanıma")
  File "interface.py", line 27, in __init__
    self.update()
  File "interface.py", line 40, in update
    ret, frame = self.vid.get_frame()
TypeError: cannot unpack non-iterable NoneType object
 

(Примечание: Я уверен, что в моем коде больше ошибок. Пожалуйста, расскажите мне об ошибках в моем коде или попробуйте сами и поделитесь решением.)

Комментарии:

1. Посмотрите на return frame внутреннюю сторону вашего get_frame метода. Это может вызвать у вас головную боль позже. Также что делать, если zip(face_locations, face_names) пусто? Что бы вернула ваша функция?

2. Также было бы плохой идеей добавить self.canvas.delete("all") перед тем self.canvas.create_image(...) , как очистить холст, прежде чем показывать следующий кадр.