Home > other >  How to list lowest values in numpy array
How to list lowest values in numpy array

Time:11-01

I'm working on a facial recognition project which creates a database of face encodings, then upon selection of a target photo will encode that photo as well and match it against the known encodings.

The program works correctly except it only provides the best match, if one is found within the set tolerance. The problem is that it is not always correct, even when i know that the target face is in my database, but the target picture is different enough that it can cause a false positive.

Because of this, I would like to list the top 3 or 5 results to hopefully get the correct result within those top 5.

Here's the code.

def recognize():
#define path for target photo
path=tkinter.filedialog.askopenfilename(filetypes=[("Image File",'.jpg .png')])

with open('dataset_faces.dat', 'rb') as f:
    encoding = pickle.load(f)

def classify_face(im):
    faces = encoding
    faces_encoded = list(faces.values())
    known_face_names = list(faces.keys())

    img = cv2.imread(im, 1)
    img = cv2.resize(img, (600, 600), fx=0.5, fy=0.5)
    #img = img[:,:,::-1]

    face_locations = face_recognition.face_locations(img, number_of_times_to_upsample=2, model="cnn")
    unknown_face_encodings = face_recognition.face_encodings(img, face_locations, num_jitters=100)

    face_names = []
    for face_encoding in unknown_face_encodings:
    # See if the face is a match for the known face(s)
        name = "Unknown"

    # use the known face with the smallest distance to the new face
        face_distances = face_recognition.face_distance(faces_encoded, face_encoding)
        best_match_index = np.argmin(face_distances)
    
    #set distance between known faces and target face. The lower the distance between them the lower the match. Higher dist = more error.
        if  face_distances[best_match_index] < 0.60:
            name = known_face_names[best_match_index]
            
        face_names.append(name)
        print(name)

I have tried adding code like

            top_3_matches = np.argsort(face_distances)[:3]
        top3 =  face_names.append(top_3_matches)
        print(top3)

However this gives me no hits.

Any ideas?

CodePudding user response:

list.append does not return anything, so you should not try to affect that expression to a variable.

names = known_face_names[top_3_matches]
face_names.append(names)
print(names)

should do the same thing as

name = known_face_names[best_match_index]
face_names.append(name)
print(name)

for three elements instead of one.

CodePudding user response:

The following code solves the issue. The issue was that I was using a numpy functions on a list that hadn't been converted into a numpy array, as per Aubergine's answer.

def classify_face(im):
    faces = encoding
    faces_encoded = list(faces.values())
    known_face_names = list(faces.keys())
    #make lists into numpy arrays
    n_faces_encoded = np.array(faces_encoded)
    n_known_face_names = np.array(known_face_names)

and to sort the numpy array for the 3 lowest values:

n_face_distances = face_recognition.face_distance(n_faces_encoded, face_encoding)
top_3_matches = np.argsort(n_face_distances)[:3]

printing the best 3 matches:

other_matches = n_known_face_names[top_3_matches]
print(other_matches)
  • Related