ageitgey / face_recognition

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

error with getting multiple matches using KNN module #1269

Open ferasawadi opened 3 years ago

ferasawadi commented 3 years ago

Description

after a lot of digging trying to get multiple results for an unknown person am getting the same results for everyone. my dataset is 26 person about 170 images for all of them

What I Did

# Find encodings for faces in the in_stream image
    face_encodings = face_recognition.face_encodings(X_img, known_face_locations=X_face_locations, num_jitters=5)
    distance, index = knn_clf.kneighbors(face_encodings, n_neighbors=4)
    training_labels_indices = knn_clf._y
    class_labels = knn_clf.classes_
    user_id = class_labels[training_labels_indices[index]]
    for us, i in zip(user_id[0], range(len(index[0]))):
        # print(user)
        # user = class_labels[training_labels_indices[i]]
        percentage = "{:.0%}".format(face_distance_to_conf(face_distance=distance[0][i],
                                                           face_match_threshold=distance_threshold))
        # print(user)
        # print(percentage)
        if not any(u.user_id == us for u in results):
            results.append(DetectionResultsModule(us, percentage))

I would appreciate any help

omerasif57 commented 3 years ago

You problem definition is much vague though but I will drop a couple of suggestion here.

If you are following the example available here then you need to follow it through the end.

Here encodings are extracted:

# Find encodings for faces in the test iamge
  faces_encodings = face_recognition.face_encodings(X_img, known_face_locations=X_face_locations)

This line of code get 1-nn (in your case: 4-nn).

# Use the KNN model to find the best matches for the test face
closest_distances = knn_clf.kneighbors(faces_encodings, n_neighbors=1)

Next, The points below a threshold are being discarded. (Which you are doing in your code) are_matches = [closest_distances[0][i][0] <= distance_threshold for i in range(len(X_face_locations))]

Now, knn_clf.predict(faces_encodings) is being called to predict the label of encodings here.

# Predict classes and remove classifications that aren't within the threshold
 return [(pred, loc) if rec else ("unknown", loc) for pred, loc, rec in zip(knn_clf.predict(faces_encodings), X_face_locations, are_matches)]

knn_classifier.predict gives the expected label for a given encoding. You can also try knn_classifier.predict_prob() function to get probability estimates for each neighbor.

ferasawadi commented 3 years ago

That's Seems to be awesome @omerasif57 warm regards Feras