многопоточность - распознавание лиц из потоковой ip-камеры - PullRequest
0 голосов
/ 23 октября 2019

Я пытаюсь сделать программу распознавания лиц ipcamera. Для уменьшения задержки FPS отделена часть capture.read () от основного потока. Как ни странно, в цикле повторяется ошибка. Как я могу исправить коды?

---- сообщения об ошибках ----


AttributeError                            Traceback (most recent call last)
<ipython-input-1-9057dfacb896> in <module>
    149 
    150 if __name__ == "__main__":
--> 151     main()

<ipython-input-1-9057dfacb896> in main()
    146 def main():
    147     face = FaceIdentify(precompute_features_file="./data/precompute_features.pickle")
--> 148     face.detect_face()
    149 
    150 if __name__ == "__main__":

<ipython-input-1-9057dfacb896> in detect_face(self)
    111 
    112 
--> 113             gray = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY)
    114             faces = face_cascade.detectMultiScale(
    115                 gray,

AttributeError: 'FaceIdentify' object has no attribute 'frame'

---- коды ----

class FaceIdentify(object):

    CASE_PATH = "haarcascade_frontalface_alt.xml"

    def __new__(cls, precompute_features_file=None):
        if not hasattr(cls, 'instance'):
            cls.instance = super(FaceIdentify, cls).__new__(cls)
        return cls.instance

    def __init__(self, precompute_features_file=None, src=0):
        self.face_size = 224
        self.precompute_features_map = load_stuff(precompute_features_file)
        print("Loading VGG Face model...")
        self.model = VGGFace(model='resnet50',
                             include_top=False,
                             input_shape=(224, 224, 3),
                             pooling='avg')  # pooling: None, avg or max
        print("Loading VGG Face model done")
        self.capture=cv2.VideoCapture(src)
        self.thread=Thread(target=self.update)
        self.thread.daemon=True
        self.thread.start()

    def update(self):
        while True:
            if self.capture.isOpened():
                (self.status, self.frame) = self.capture.read()
            time.sleep(.01)





    def draw_label(cls, image, point, label, font=cv2.FONT_HERSHEY_SIMPLEX,
                   font_scale=1, thickness=2):
        size = cv2.getTextSize(label, font, font_scale, thickness)[0]
        x, y = point
        cv2.rectangle(image, (x, y - size[1]), (x + size[0], y), (255, 0, 0), cv2.FILLED)
        cv2.putText(image, label, point, font, font_scale, (255, 255, 255), thickness)

    def crop_face(self, imgarray, section, margin=20, size=224):

        img_h, img_w, _ = imgarray.shape
        if section is None:
            section = [0, 0, img_w, img_h]
        (x, y, w, h) = section
        margin = int(min(w, h) * margin / 100)
        x_a = x - margin
        y_a = y - margin
        x_b = x + w + margin
        y_b = y + h + margin
        if x_a < 0:
            x_b = min(x_b - x_a, img_w - 1)
            x_a = 0
        if y_a < 0:
            y_b = min(y_b - y_a, img_h - 1)
            y_a = 0
        if x_b > img_w:
            x_a = max(x_a - (x_b - img_w), 0)
            x_b = img_w
        if y_b > img_h:
            y_a = max(y_a - (y_b - img_h), 0)
            y_b = img_h
        cropped = imgarray[y_a: y_b, x_a: x_b]
        resized_img = cv2.resize(cropped, (size, size), interpolation=cv2.INTER_AREA)
        resized_img = np.array(resized_img)
        return resized_img, (x_a, y_a, x_b - x_a, y_b - y_a)

    def identify_face(self, features, threshold=100):
        distances = []
        for person in self.precompute_features_map:
            person_features = person.get("features")
            distance = sp.spatial.distance.euclidean(person_features, features)
            distances.append(distance)
        min_distance_value = min(distances)
        min_distance_index = distances.index(min_distance_value)
        if min_distance_value < threshold:
            return self.precompute_features_map[min_distance_index].get("name")
        else:
            return "Unknown person"

    def detect_face(self):
        face_cascade = cv2.CascadeClassifier(self.CASE_PATH)


        while True:


            gray = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY)
            faces = face_cascade.detectMultiScale(
                gray,
                scaleFactor=1.2,
                minNeighbors=10,
                minSize=(64, 64)
            )

            face_imgs = np.empty((len(faces), self.face_size, self.face_size, 3))
            for i, face in enumerate(faces):
                face_img, cropped = self.crop_face(self.frame, face, margin=10, size=self.face_size)
                (x, y, w, h) = cropped
                cv2.rectangle(self.frame, (x, y), (x + w, y + h), (255, 200, 0), 2)
                face_imgs[i, :, :, :] = face_img
            if len(face_imgs) > 0:
                # generate features for each face
                features_faces = self.model.predict(face_imgs)
                predicted_names = [self.identify_face(features_face) for features_face in features_faces]
            # draw results
            for i, face in enumerate(faces):
                label = "{}".format(predicted_names[i])
                self.draw_label(self.frame, (face[0], face[1]), label)

            cv2.imshow('Keras Faces', self.frame)
            if cv2.waitKey(5) == 27:  # ESC key press
                break
        # When everything is done, release the capture
        video_capture.release()
        cv2.destroyAllWindows()
        cv2.waitKey(1)



def main():
    face = FaceIdentify(precompute_features_file="./data/precompute_features.pickle")
    face.detect_face()

if __name__ == "__main__":
    main()

1 Ответ

1 голос
/ 23 октября 2019

в detect_face() у вас есть строка gray = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY) - и self.frame не объявлено нигде в коде. Вы можете исправить это. обычно лучшее место для объявления переменной класса - __init__() функция.

...