Currently, I'm making a face recognition program where I have a KNOWN_FACES folder that is accessed by program to recognise known faces in an unidentified image. I test the program on a image that should return 'Unknown' on all faces, but I'm having trouble with getting rectangles on all the faces, and then saving the image in an image_output folder.
FOLDER STRUCTURE.
Known images: my_project//KNOWN_FACES//"ALL FACES HERE"
Output folder: my_project//image_output//
And I have a faces.jpg in the directory, where my program is located. In my code, I'm pretty sure that there's something wrong with how I try to draw rectangles around each face and display their name right under the rectangle. (Almost at the bottom of the program.)
I only have this one program, which is a modification of THIS piece of code from the maker of the face_recognition module.
Here is image_face_recognition.py:
from PIL import Image
import face_recognition
import cv2
# Load Unidentified faces
image = face_recognition.load_image_file("faces.jpg")
# face1
face1_image = face_recognition.load_image_file("KNOWN_FACES//face1.jpg")
face1_face_encoding = face_recognition.face_encodings(face1_image)[0]
# face2
face2_image = face_recognition.load_image_file("KNOWN_FACES//face2.jpg")
face2_face_encoding = face_recognition.face_encodings(face2_image)[0]
# face3
face3_image = face_recognition.load_image_file("KNOWN_FACES//face3.jpg")
face3_face_encoding = face_recognition.face_encodings(face3_image)[0]
# face4
face4_image = face_recognition.load_image_file("KNOWN_FACES//face4.jpg")
face4_face_encoding = face_recognition.face_encodings(face4_image)[0]
# Create arrays of known face encodings and their names
known_face_encodings = [
face1_face_encoding,
face2_face_encoding,
face3_face_encoding,
face4_face_encoding
]
known_face_names = [
"FACE1",
"FACE2",
"FACE3",
"FACE4"
]
# Find all the faces in the image using the default HOG-based model.
# This method is fairly accurate, but not as accurate as the CNN model and not GPU accelerated.
face_locations = face_recognition.face_locations(image)
print("I found {} face(s) in this photograph.".format(len(face_locations)))
# Then compare faces with known faces, and save an image that contains
# rectangles around EACH face.
# Find all the face encodings in the image.
face_encodings = face_recognition.face_encodings(image, face_locations)
face_names = []
for face_encoding in face_encodings:
# See if the face is a match for the known face(s)
matches = face_recognition.compare_faces(known_face_encodings, face_encoding)
name = "Unknown"
# If a match was found in known_face_encodings, just use the first one.
if True in matches:
first_match_index = matches.index(True)
name = known_face_names[first_match_index]
face_names.append(name)
# Return final image.
for (top, right, bottom, left), name in zip(face_locations, face_names):
# Scale back up face locations since the image was scaled to 1/5 size.
top *= 5
right *= 5
bottom *= 5
left *= 5
# Draw a box around the face.
cv2.rectangle(image, (left, top), (right, bottom), (0, 0, 255), 2)
# Draw a label with a name below the face.
# See, this is where I think I messed up.
# DOESN'T WORK (I think).
cv2.rectangle(image, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
font = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(image, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
# Finally, save the image to image_output folder.
final_image = Image.fromarray(image)
final_image.save("image_output/FACE_REC_PICTURE.png")
You forgot to resize image before drawing rectangle
#resize image TOO
image = cv2.resize(image,(0,0),fx=5,fy=5)
for (top, right, bottom, left), name in zip(face_locations, face_names):
# Scale back up face locations since the image was scaled to 1/5 size.
top *= 5
right *= 5
bottom *= 5
left *= 5
# Draw a box around the face.
cv2.rectangle(image, (left, top), (right, bottom), (0, 0, 255), 2)
cv2.rectangle(image, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
font = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(image, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
Besides that, you have twice this line
face_locations = face_recognition.face_locations(image)
in your script. In general I wouldnt mention that, but this one is pretty slow function, so you dont want to do it twice.
In my humble opinion, and from my experience, you do this rescaling because finding face locations with Face_recognition library is god damn slow. If I may intervene,
Look at Haar cascades - for finding frontal and side face locations.
It does the same job, but you need to integrate it in your program, which is not problem at all. Its basicly the same like
face_recognition.face_locations(image)
While face_recognition library can find face locations up to 60s.. Haar cascades, even though little bit less accurate and reliable, can do it up to 1s. You will not need to rescale you image and play with coordinates