hyung ook An
hyung ook An

Reputation: 711

multithreading- face recognition from streaming of ip-camera

I am trying to make ipcamera face recognition program. For reducing the delay of FPS, separated capture.read() part from the main thread. However strangely, an error is occurring in the looping block. How can I correct the codes?

----error messages----


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'

----codes----

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()

Upvotes: 0

Views: 202

Answers (1)

lenik
lenik

Reputation: 23556

in detect_face() you have a line gray = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY) -- and self.frame is not declared anywhere in the code. you may want to fix that. usually the best place for the class variable declaration is __init__() function.

Upvotes: 1

Related Questions