This is my first post here so I am sorry if my question is not clear or there is not enough information provided.
I am currently working on an Android application that could recognize faces from pictures.
My first approach was to use JavaCV and everything works fine, except the fact that face detection takes too much of time to finish!
After that, I tried to detect faces by using FaceDetector.Face. Then I used the detected faces for training my face recognizer model. There was no error found so far.
My problem is that my model could not recognize any detected face given by FaceDetector.Face. I always get -1 from the predict function. Could anybody tell what might be wrong? Thank you in advance!
This is how I crop faces after detection:
for(int count=0;count<NUMBER_OF_FACE_DETECTED;count++)
{
Face face=detectedFaces[count];
PointF midPoint=new PointF();
face.getMidPoint(midPoint);
eyeDistance=face.eyesDistance();
left = midPoint.x - (float)(1.4 * eyeDistance);
top = midPoint.y - (float)(1.8 * eyeDistance);
bmFace = Bitmap.createBitmap(origiImage, (int) left, (int) top, (int) (2.8 * eyeDistance), (int) (3.6 * eyeDistance));
bmFaces.add(bmFace);
}
Here is a main part of training the model.
MatVector images = new MatVector(imageFiles.length);
int[] labels = new int[imageFiles.length];
IplImage img;
IplImage grayImage;
FaceRecognizer faceRecognizer = createLBPHFaceRecognizer(1, 8, 8, 8, binaryTreshold);
try
{
FileInputStream fstream = new FileInputStream(working_Dir.getAbsolutePath()+"/csv.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String imgInfo;
for (int i = 0; (imgInfo = br.readLine()) != null; i++)
{
String info[] = imgInfo.split(";");
String imagePath = info[0];
img = cvLoadImage(imagePath);
grayImage = IplImage.create(img.width(),img.height(), IPL_DEPTH_8U, 1);
cvCvtColor(img, grayImage, CV_BGR2GRAY);
images.put(i, grayImage);
labels[i] = Integer.parseInt(info[1]);;
}
in.close();
//train the FaceRecognizer model
faceRecognizer.train(images, labels);
}catch (Exception e)
{
System.err.println("Error: " + e.getMessage());
}
Finally I recognize face with the following code:
public static String identifyFace(IplImage grayImg)
{
String predictedName = "";
//identify face from the image
int predictedLabel = faceRecognizer.predict(grayImg);
if(predictedLabel != -1 )
{
predictedName = new String(idToName.get(predictedLabel));
}
return predictedName;
}
From Settings, tap Biometrics and security, and then tap Face recognition. Tap Continue. If you don't already have a secure screen lock, you will need to set one up. Hold the phone 8-20 inches away and position your face inside the circle.
However, Android also has a version of facial recognition that can unlock your phone without entering a passcode or pattern — and may work if you're wearing a mask. To enable it, you have to set up an alternate appearance similar to the steps for the iPhone noted above.
This can only happen if you don't set the threshold appropriately, see the documentation:
The method to create a LBPHFaceRecognizer
is:
Ptr<FaceRecognizer> createLBPHFaceRecognizer(int radius=1, int neighbors=8, int grid_x=8, int grid_y=8, double threshold=DBL_MAX)
, where:
So in the above method signature you see, that the threshold is set to DBL_MAX
by default. So if you simply leave the threshold out, then it'll never yield -1
. On the other hand, if you set the threshold too low, the FaceRecognizer is always going to yield -1
. That said, check what you have set binaryTreshold
in your code to. Finding the appropriate decision threshold for your data is a classic optimization problem, where you have to optimize for the best threshold by a given criteria (for example based on False Acceptance Rate/False Rejection Rate).
I know this is really late, but try using Haar cascade classifier from JavaCV instead of facedetector from Android itself
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With