ageitgey / face_recognition

The world's simplest facial recognition api for Python and the command line
MIT License
52.98k stars 13.45k forks source link

Storing face-encoding in database #599

Open ghost opened 6 years ago

ghost commented 6 years ago

Description

@ageitgey, I am working with your module using django and need to store the face-encodings in a database field to optimize comparison. I used a character field and converted it to both numpy array and list before comparing, but had issues comparing the face encodings retrieved from database with the one created from an image. Any advice?

Was getting error ufunc 'subtract' did not contain a loop with signature matching types dtype('<U1848') dtype('<U1848') dtype('<U1848')

i printed both face encodings (from database and from image) and they looked alike and were of the same type, i also changed the types to lists and numpy arrays yet it did not work. Did alot of crazy stuff including list comprehension and regex just to hack up a solution. My guess is probably the difference in shape of the matrix because each data in both matrices were of type float and looked alike.

ghost commented 6 years ago

Any help will be appreciated. I am completely clueless

starlai21 commented 6 years ago

I was using sqlalchemy, there is a type named "PickleType", you can store the encodings in this type.

ghost commented 6 years ago

Thanks. I will try it out. Will get back to you guys

AndreWicked commented 6 years ago

It is not necessary to store encodings in the database, you can store them in a file, using a pickle module or json module.

AndreWicked commented 6 years ago

Mini example if you interested:

import cv2
import face_recognition as fr
import pickle
import time

encodingsBox = []
namesBox = []
cap = cv2.VideoCapture(0)
name = input("Please, input your name: ")
time.sleep(1)
while True:
    ret, frame = cap.read()
    if ret == True:
        rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        boxes = fr.face_locations(rgb_frame, model="hog")
        encodings = fr.face_encodings(rgb_frame, boxes)
        for encoding in encodings:
            encodingsBox.append(encoding)
            namesBox.append(name)
    cv2.imshow("Frame", frame)
    if cv2.waitKey(1) == 27 & 0xff:
        break
data = {"encodings": encodingsBox, "names": namesBox}
f = open("encodings.pickle", "wb")
f.write(pickle.dumps(data))
f.close()
print(data)
cap.release()
cv2.destroyAllWindows()
hazxone commented 6 years ago

Thanks @AndreWicked . But if we were to run that code again, will the previous saved faces get overwrite or it will append to the pickle?

AndreWicked commented 6 years ago

Yes, they will be rewritten, to avoid this, you must first to load them, a small example:

data = pickle.loads(open("encodings.pickle", "rb").read())
encodingsBox = data["encodings"]
namesBox = data["names"]
Pepepy commented 6 years ago

Effectively, you can save the data encapsulated with 'pickle', in a field type 'Bold' of your database and when you need to read it again normally unzipping it with Pickle.

from pickle import loads, dumps

To save it in your 'Bold' field you can use: 'dumps (Image_face_encoding)' And then read it with: 'loads (YOURDATA)'

In this way you will not overwrite the data, save it in your database and access it in the way that best suits you Excuse me for my English ;)

ghost commented 6 years ago

Thanks alot sir. It is a final year project so i am forced to use a database and i need to cache that row in the database to increase speed when the row is accessed even if its unnecessary just to impress. So any example of storing it in a database , i heard of modules like django-matrix-field and django-numpy, can they help?

ghost commented 6 years ago

Each face is added and the encoding generated and stored in face-print row in database from admin side when the user is created. I just need to fetch it and compare to identify the face via browser as a who-is-this feature just like that of the web-service example done with flask and in real time from face-print row in user data.