Search code examples
pythonface-recognitiondlibpybind11

TypeError: __init__(): incompatible constructor arguments with face_recognition call


I was trying to develop a face recognition attendance system, I coded 100% just like the tutorial, but I still got some errors, here's the code:

from face_recognition.api import face_distance
import face_recognition as fr
import os
import cv2
import face_recognition
import numpy as np
import time
from PIL import ImageFont

def getEncodedFaces():
    encoded = {}
    for dirPath, dNames, fNames in os.walk("./faces"):
        for f in fNames:
            if f.endswith(".jpg") or f.endswith(".png"):
                face = fr.load_image_file("faces/" + f)
                encoding = fr.face_encodings(face)[0]
                encoded[f.split(".")[0]] + encoding
    return encoded

def unknownImageEncoded(img):
    face = fr.load_image_file("faces/" + img)
    encoding = fr.face_encodings(face)[0]
    return encoding

def classifyFace(im):
    faces = getEncodedFaces()
    facesEncoded = list(faces.values())
    knownFaceNames = list(faces.keys())
    img = cv2.imread(im, 1)
    faceLocations = face_recognition.face_encodings(img)
    unknownFaceEncodings = face_recognition.face_encodings(img, faceLocations)
    faceNames = []
    for faceEncoding in unknownFaceEncodings:
        matches = face_recognition.compare_faces()
        name = "Unknown"
        faceDistances = face_recognition.face_distance(facesEncoded, faceEncoding)
        bestMatchIndex = np.argmin(face_distance)
        if matches[bestMatchIndex]:
            name = knownFaceNames[bestMatchIndex]
        faceNames.append(name)
        for (top, right, bottom, left), name in zip(faceLocations, faceNames):
            cv2.rectangle(img, (left-20, top-20, right+20, bottom+20), (255, 0, 0), cv2.FILLED)
            font = ImageFont.truetype("./NotoSansTC-Black.ttf")
            cv2.putText(img, name, (left-20, bottom+15), font, 1.0, (255, 255, 255), 2)
    
    while True:
        cv2.imshow("Attendance System", img)
        if cv2.waitkey(1) & 0xFF == ord("q"):
            return faceNames

print(classifyFace("test.jpg"))

And here's the error:

Traceback (most recent call last):
  File "main.py", line 51, in <module>
    print(classifyFace("test.jpg"))
  File "main.py", line 31, in classifyFace
    unknownFaceEncodings = face_recognition.face_encodings(img, faceLocations)
  File "C:\Users\family\AppData\Local\Programs\Python\Python36\lib\site-packages\face_recognition\api.py", line 213, in face_encodings
    raw_landmarks = _raw_face_landmarks(face_image, known_face_locations, model)
  File "C:\Users\family\AppData\Local\Programs\Python\Python36\lib\site-packages\face_recognition\api.py", line 158, in _raw_face_landmarks
    face_locations = [_css_to_rect(face_location) for face_location in face_locations]
  File "C:\Users\family\AppData\Local\Programs\Python\Python36\lib\site-packages\face_recognition\api.py", line 158, in <listcomp>
    face_locations = [_css_to_rect(face_location) for face_location in face_locations]
  File "C:\Users\family\AppData\Local\Programs\Python\Python36\lib\site-packages\face_recognition\api.py", line 49, in _css_to_rect
    return dlib.rectangle(css[3], css[0], css[1], css[2])
TypeError: __init__(): incompatible constructor arguments. The following argument types are supported:
    1. _dlib_pybind11.rectangle(left: int, top: int, right: int, bottom: int)
    2. _dlib_pybind11.rectangle(rect: dlib::drectangle)
    3. _dlib_pybind11.rectangle(rect: _dlib_pybind11.rectangle)
    4. _dlib_pybind11.rectangle()

Invoked with: -0.035434916615486145, -0.12049627304077148, 0.08377307653427124, 0.062198664993047714

Here's the directory structure:

test.JPG
main.py
NotoSansTC-Black.otf
faces
|- 呂AA.jpg
|- 呂BB.jpg

Can someone tell me what does it mean and how to fix it? I have tried installing many different versions of dlib and face-recognition. I've also installed pybind11, but it is still giving me the same error. I'm in a hurry and I really need some help. Thank you!


Solution

  • Why are you importing face_recognition 2 times? It is not proper way to import face_recognition 2 times.

    compare_faces() takes 2 arguments, already encoded vector list and unknown encoded vector.

    And now focusing on your main error, you have not used face_locations which means it wont locate your face from the image.

    Your error is here:

    faceLocations = face_recognition.face_encodings(img)
    

    Instead use this:

    faceLocations = face_recognition.face_locations(img)
    

    full code:

    from face_recognition.api import face_distance
    import face_recognition as fr
    import os
    import cv2
    import numpy as np
    import time
    from PIL import ImageFont
    
    def getEncodedFaces():
        encoded = {}
        for f in os.listdir(os.path.join('faces')):
            face = fr.load_image_file(os.path.join('faces',f))
            encoding = fr.face_encodings(face)
            if not len(encoding):
               continue
            encoding = encoding[0]
            encoded[f.split(".")[0]] = encoding
        return encoded
    
    def unknownImageEncoded(img):
        face = fr.load_image_file("faces/" + img)
        encoding = fr.face_encodings(face)[0]
        return encoding
    
    def classifyFace(im):
        faces = getEncodedFaces()
        facesEncoded = list(faces.values())
        knownFaceNames = list(faces.keys())
        img = cv2.imread(im, 1)
        faceLocations = fr.face_locations(img)
        unknownFaceEncodings = fr.face_encodings(img, faceLocations)
        faceNames = []
        for faceEncoding, faceloc in zip(unknownFaceEncodings, faceLocations):
            top, right, bottom, left = faceloc
            matches = fr.compare_faces(facesEncoded, faceEncoding)
            name = "Unknown"
            faceDistances = fr.face_distance(facesEncoded, faceEncoding)
            bestMatchIndex = np.argmin(faceDistances)
            if matches[bestMatchIndex]:
                name = knownFaceNames[bestMatchIndex]
                faceNames.append(name)
                cv2.rectangle(img, (left-20, top-20, right+20, bottom+20), (255, 0, 0), cv2.FILLED)
                font = ImageFont.truetype("./NotoSansTC-Black.ttf")
                cv2.putText(img, name, (left-20, bottom+15), font, 1.0, (255, 255, 255), 2)
        
    
        image = img[:, :, ::-1]
        cv2.imwrite("result.jpg", image)
        return faceNames
    
    print(classifyFace("test.jpg"))