takuya-takeuchi / FaceRecognitionDotNet

The world's simplest facial recognition api for .NET on Windows, MacOS and Linux
MIT License
1.27k stars 308 forks source link

False face recognition #107

Closed MilindThakkar closed 3 years ago

MilindThakkar commented 4 years ago

Hi, I am trying to use this library to recognize photo (to match) from list of photos having in a folder (consider a corporate profile photos). First, I am saving faceencodings in a array (as shown below)

Dictionary<string, FaceEncoding> trainedImages = new Dictionary<string, FaceEncoding>();
foreach (var imageFile in ImageFilesInFolder(trainImagePath))
            {
                var img = FaceRecognition.LoadImageFile(imageFile);
                var faceEncodings = _FaceRecognition.FaceEncodings(img);
                if (faceEncodings != null && faceEncodings.Count() > 0)
                {
                    trainedImages.Add(imageFile, faceEncodings.ToArray()[0]);
                }
            }

Then for a new image, I am comparing with this encodings as below.

var img = FaceRecognition.LoadImageFile(pathImageCheck);
var faceEncodingToRecognize = _FaceRecognition.FaceEncodings(img);
string result = trainedImages.FirstOrDefault(x => FaceRecognition.CompareFace(x.Value, faceEncodingToRecognize.ToArray()[0])).Key;

However, it's giving false match. The image are 96 * 96 pixels. Am I missing something? Also, is there a way to "train" with multiple images of single person (something similar to what 's there in OpenCV or EmguEV)?

Please help me understand.

takuya-takeuchi commented 4 years ago

@MilindThakkar CompareFace use 0.6 as tolerance. Could you check the dustance by using FaceDistance? It tells a reference value to decide torelance. And this threshold may be high. Because 96x96 size is not large. Small face may lose an important feature.

Also, is there a way to "train" with multiple images of single person (something similar to what 's there in OpenCV or EmguEV)?

FaceRecognition does not give functionallity to train face recognition. And we must know face recognition does not equal to image classification. Face recognition uses metrics learning and there is in opencv. But I haven't used it and opencv's looks like classical technology.

MilindThakkar commented 4 years ago

@takuya-takeuchi Thanks for the response. That was the exact thought I had after I posted the message. I was taking "First" which was having distance less than 0.6 but marginally. Then I tried getting all matches and it gave me four faces for one face to compare.

Then I tried to get one with minimum distances and it gave me the correct one (I have tested just couple it for now). The other three had value like 0.59,0.597 and 0.55 while the matching one had distance 0.45.

What is the ideal distance? And how do I calculate or find it?

Also, do you think a method which returns encoding with minimum distance would help the consumer of this API?

takuya-takeuchi commented 4 years ago

@MilindThakkar I think we can not determine perfect value to avoid false positive and true negative. This value could be determined from database quality and situation you hope.

Higher threshold is avoiding false negative. Lower threshold is avoiding false positive.

Which types do you prefer?

Also, do you think a method which returns encoding with minimum distance would help the consumer of this API?

Sorry. What does it mean? You hope I provide new API to return encoding with minimum distance, right?

MilindThakkar commented 4 years ago

You hope I provide new API to return encoding with minimum distance, right?

Yes, that would simplify the user who is trying to recognize a face from list saved encoding. Thanks !

takuya-takeuchi commented 4 years ago

@MilindThakkar Umm.. I think you can use only FaceDistance method to achieve your requirement.

FaceEncoding targetFaceEncoding;
var saveEncodings = new List<FaceEncoding>();
var minEncoding = saveEncoding.Min( e => FaceRecognition.FaceEncoding(e, targetFaceEncoding));

Is there any problem for above snipet?