I have a number of images that I would like to train. And instead of re-training every time I started the program, I would like to save the face_encodings into a datafile that can just be reloaded (which should take less time)
source_image = face_recognition.load_image_file(face_photos[i])
dataset_face_encoding = face_recognition.face_encodings(source_image)[0]
This is command I use to save it to a text file
with open('dataset_faces.txt', 'w') as outfile:
yaml.dump(dataset_face_encoding, outfile, default_flow_style=False)
Is there any better way for me do this and also I would like to associate the face_encodings to the name.
Python has a built-in way to save and load objects to a file called pickle.
import face_recognition
import pickle
all_face_encodings = {}
img1 = face_recognition.load_image_file("obama.jpg")
all_face_encodings["obama"] = face_recognition.face_encodings(img1)[0]
img2 = face_recognition.load_image_file("biden.jpg")
all_face_encodings["biden"] = face_recognition.face_encodings(img2)[0]
# ... etc ...
with open('dataset_faces.dat', 'wb') as f:
pickle.dump(all_face_encodings, f)
That creates the file. Then later you could do this to use it:
import face_recognition
import pickle
import numpy as np
# Load face encodings
with open('dataset_faces.dat', 'rb') as f:
all_face_encodings = pickle.load(f)
# Grab the list of names and the list of encodings
face_names = list(all_face_encodings.keys())
face_encodings = np.array(list(all_face_encodings.values()))
# Try comparing an unknown image
unknown_image = face_recognition.load_image_file("obama_small.jpg")
unknown_face = face_recognition.face_encodings(unknown_image)
result = face_recognition.compare_faces(face_encodings, unknown_face)
# Print the result as a list of names with True/False
names_with_result = list(zip(face_names, result))
print(names_with_result)
Which should print:
[('obama', True), ('biden', False)]
Thank you for the update.
I tried your method of using pickle. For similar photos of 5 persons, using YAML my output dataset file is 9kb and pickle 18kb.
Based on your example, I have modified my code to
To write to dataset
source_image = face_recognition.load_image_file(face_photos[i])
dataset_faces[name_photos[i]] = face_recognition.face_encodings(source_image)[0]
with open('dataset_faces2.txt', 'w') as outfile:
yaml.dump(dataset_faces, outfile, default_flow_style=False)
To read the dataset
with open('dataset_faces2.txt', 'r') as stream:
all_face_encodings = yaml.load(stream)
dataset_faces_name = list(all_face_encodings.keys())
dataset_faces = np.array(list(all_face_encodings.values()))
Another thing that I have yet to try is updating a dataset without re-writing the whole values again.
Because my YAML code seems to re-write the whole value when an update is required.
Another basic question: what algorithm does this library uses? As I only found "euclidean distance". Does it belong to any family like: Viola-Jones, Eigenfaces, etc?
BTW, one of the advantages of Pickle is that you would have to cast loaded data into list/array. When you load Pickled file, it is exactly what you put in which can be quite convenient.
If i want to append new encoded image, can I do it like this?
with open("dataset_faces2.txt", "a+b") as file:
pickle.dump(all_face_encodings, file, pickle.HIGHEST_PROTOCOL)
Another thing that I have yet to try is updating a dataset without re-writing the whole values again.
If i want to append new encoded image, can I do it like this?
No. A pickle file is just a copy of a python object saved to disk. You can't just append extra stuff to the file like that. If you want something closer to a real database with more functionality like adding records without loading everything into memory, just use a real database instead like postgresql.
Another basic question: what algorithm does this library uses? As I only found "euclidean distance". Does it belong to any family like: Viola-Jones, Eigenfaces, etc?
It's a newer deep-learning approach. Neither Viola-Jones or Eigenfaces are used. It's actually a pipeline with several steps using multiple algorithms (face detection, face feature detection, face encoding, face encoding comparison with euclidean distance). You can learn all about the kinds of algorithms and steps here in my detailed write-up: https://medium.com/@ageitgey/machine-learning-is-fun-part-4-modern-face-recognition-with-deep-learning-c3cffc121d78
Hello,
This code below doesn't work for me for multiple known faces. It only compares first face in the array.
face_encodings = numpy.array(list(my_face_encodings.values()))
...
...
results = face_recognition.compare_faces(face_encodings, unknown_face_encoding)
unless i do this. use a for loop.
face_encodings = numpy.array(list(my_face_encodings.values()))
...
...
for kface in face_encodings:
results = face_recognition.compare_faces([kface], unknown_face_encoding)
what might be wrong that compare_faces does not accept my array?
Hello guys,
The problem I have is to encoding different images in the directory of images, only encoding the new image when new image added to my ImageFolder directory,
How to do it?? Please help me thank you so much in advance,
for file in os.listdir("Imagefolder"):
try:
known_person.append(file.replace(".jpg", ""))
file=os.path.join("Imagefolder", file)
known_image = face_recognition.load_image_file(file)
known_face_encoding.append(face_recognition.face_encodings(known_image)[0])
except Exception as e:
pass
face_locations = []
face_encodings = []
face_names = []
process_this_frame = 0
If i want to append new encoded image, can I do it like this?
with open("dataset_faces2.txt", "a+b") as file: pickle.dump(all_face_encodings, file, pickle.HIGHEST_PROTOCOL)
You can just load the file and then just append you new face_encoding to your all_face_encodings and dump back.
Python has a built-in way to save and load objects to a file called
pickle.import face_recognition import pickle all_face_encodings = {} img1 = face_recognition.load_image_file("obama.jpg") all_face_encodings["obama"] = face_recognition.face_encodings(img1)[0] img2 = face_recognition.load_image_file("biden.jpg") all_face_encodings["biden"] = face_recognition.face_encodings(img2)[0] # ... etc ... with open('dataset_faces.dat', 'wb') as f: pickle.dump(all_face_encodings, f)That creates the file. Then later you could do this to use it:
import face_recognition import pickle import numpy as np # Load face encodings with open('dataset_faces.dat', 'rb') as f: all_face_encodings = pickle.load(f) # Grab the list of names and the list of encodings face_names = list(all_face_encodings.keys()) face_encodings = np.array(list(all_face_encodings.values())) # Try comparing an unknown image unknown_image = face_recognition.load_image_file("obama_small.jpg") unknown_face = face_recognition.face_encodings(unknown_image) result = face_recognition.compare_faces(face_encodings, unknown_face) # Print the result as a list of names with True/False names_with_result = list(zip(face_names, result)) print(names_with_result)Which should print:
[('obama', True), ('biden', False)]
Can you please suggest same thing in cpp ?
Most helpful comment
Python has a built-in way to save and load objects to a file called
pickle.That creates the file. Then later you could do this to use it:
Which should print: