Face_recognition: Unable to identify matched image

Created on 6 Jun 2017  Ā·  7Comments  Ā·  Source: ageitgey/face_recognition

  • face_recognition version:
  • Python version: 2.7
  • Operating System: Linux Mint (Sarah)

Description

I’m trying to create an application to recognize any of the known faces from a video stream. I have a directory ā€œtraining_imagesā€ which contains one image for each known face. I’m following the example code given by you and slightly modified it to add multiple known faces.
In the response of face_recognition .compare_faces(), I was expecting a list of matched results, containing a set of 128 boolean values for each training image. Instead of that it returns only one set of 128 boolean values. While which training_image_encoding was matched is still unknown.

Can you help me, where I’m doing wrong?

What I Did

import face_recognition
import cv2
import numpy
import os

video_capture = cv2.VideoCapture(0)


files= os.listdir("training_images")
print files
training_face_encoding=[]
for file in files:
    print file
    training_image = face_recognition.load_image_file('training_images/'+file)
    training_face_encoding.append(face_recognition.face_encodings(training_image)[0])

face_locations = []
face_encodings = []
face_names = []
process_this_frame = True
i =0
while True:
    ret, frame = video_capture.read()
    frame=cv2.flip(frame,1)
    small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)

    if i < 4:
        process_this_frame=False
        i +=1
    else:
        i=0
    if process_this_frame:
        face_locations = face_recognition.face_locations(small_frame)
        face_encodings = face_recognition.face_encodings(small_frame, face_locations)

        face_names = []
        for face_encoding in face_encodings:
            match = face_recognition.compare_faces([training_face_encoding], face_encoding)
            name = "Unknown"
            print match[0]
            print files

            i =0
            for m in match[0]:
                # print m
                # print i
                if m.all():
                    name = files[i]
                    face_names.append(name)
                i +=1




    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)

    cv2.imshow('Video', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

video_capture.release()
cv2.destroyAllWindows()

All 7 comments

The application should read all training images from "training_images" directory, then match each frame of video stream to these images and in the end tell the name of most appropriately matched image file.

It will be more suitable if I can add multiple images of same person and application tells the name of the person in video frame.

Instead of that it returns only one set of 128 boolean values.

Isn't this what it should be? Each boolean value, match[i], says if training_face_encoding[i] is within the threshold (default=0.6) of face_encoding.

face_recognition.compare_faces([training_face_encoding], face_encoding)

This should just be face_recognition.compare_faces(training_face_encoding, face_encoding). If you were just copying the example, the obama_face_encoding is a lone encoding and needed to be placed in a list for the function, you don't have to do that.

With that change you should just be able to iterate over match looking for the True values.

Here's a fixed version of your code. However I only tested it in Python 3 (not Python 2):

import face_recognition
import cv2
import numpy
import os

video_capture = cv2.VideoCapture(0)

files = os.listdir("training_images")
print(files)
training_face_encoding=[]
for file in files:
    print(file)
    training_image = face_recognition.load_image_file('training_images/'+file)
    training_face_encoding.append(face_recognition.face_encodings(training_image)[0])

face_locations = []
face_encodings = []
face_names = []
process_this_frame = True
i = 0
while True:
    ret, frame = video_capture.read()
    frame=cv2.flip(frame, 1)
    small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)

    if i < 4:
        process_this_frame=False
        i += 1
    else:
        i = 0
    if process_this_frame:
        face_locations = face_recognition.face_locations(small_frame)
        face_encodings = face_recognition.face_encodings(small_frame, face_locations)

        face_names = []
        for face_encoding in face_encodings:
            match = face_recognition.compare_faces(training_face_encoding, face_encoding)
            name = "Unknown"
            print(match)
            print(files)

            i = 0
            for m in match:
                if m:
                    name = files[i]
                i += 1

            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)

    cv2.imshow('Video', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

video_capture.release()
cv2.destroyAllWindows()

Output:

$ python3 test.py
['Adam.jpg', 'biden.jpg', 'obama.jpg', 'obama2.jpg', 'obama_small.jpg']
Adam.jpg
biden.jpg
obama.jpg
obama2.jpg
obama_small.jpg
[True, False, False, False, False]
['Adam.jpg', 'biden.jpg', 'obama.jpg', 'obama2.jpg', 'obama_small.jpg']

The biggest issue was that you are were accidentally passing in an array of an array to face_recognition.compare_faces() instead of just passing in a normal array like @hellopatrick said.

Thank you for this wonderful model.
I am using

  • face_recognition version:

  • Python version: 2.7.5

  • Operating System: ubuntu(16.04)
    I had collected few faces and created my dataset .
    Does the accuracy of recognizing people reduce if we increase the size of the dataset by any chance?

@31893 No, the accuracy isn't based on the number of photos you are testing against (if I understand your question correctly)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dickyj picture dickyj  Ā·  3Comments

damey2011 picture damey2011  Ā·  3Comments

paulaceccon picture paulaceccon  Ā·  5Comments

Sparviero-Sughero picture Sparviero-Sughero  Ā·  4Comments

carlhung picture carlhung  Ā·  6Comments