如何在Android上使用FaceDetector.Face进行脸部识别

这是我在这里的第一篇文章,所以如果我的问题不清楚或者没有足够的信息提供,我很抱歉。

我目前正在研究可以识别图片中的脸部的Android应用程序。

我的第一个方法是使用JavaCV,并且一切正常,除了脸部检测需要花费太多时间才能完成!

之后,我尝试使用FaceDetector.Face检测脸部。 然后我使用检测到的脸部来训练我的脸部识别器模型。 到目前为止没有发现任何错误。

我的问题是我的模型无法识别FaceDetector.Face给出的任何检测到的面部。 我总是从预测函数中得到-1。 有人可以告诉可能有什么问题吗? 先谢谢你!

这就是我在检测后裁剪脸部的方式:

    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);
    }

这是训练模型的主要部分。

    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());
    }

最后,我用以下代码识别了面部:

    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;
}

这只有在您没有适当设置阈值时才会发生,请参阅文档:

  • http://docs.opencv.org/trunk/modules/contrib/doc/facerec/facerec_api.html#createlbphfacerecognizer
  • 创建LBPHFaceRecognizer的方法是:

    Ptr<FaceRecognizer> createLBPHFaceRecognizer(int radius=1, int neighbors=8, int grid_x=8, int grid_y=8, double threshold=DBL_MAX)
    

    ,其中:

  • 阈值 - 预测中应用的阈值。 如果到最近邻居的距离大于阈值,则此方法返回-1。
  • 因此,在上面的方法签名中,默认情况下,阈值设置为DBL_MAX 。 所以,如果你只是放弃这个门槛,那么它永远不会屈服-1 。 另一方面,如果将阈值设置得太低,FaceRecognizer总是会产生-1 。 也就是说,检查你在代码中设置了binaryTreshold 。 为您的数据找到适当的决策门槛是一个经典的优化问题,您必须根据给定的标准(例如基于错误接受率/错误拒绝率)优化最佳阈值。


    我知道这真的很晚,但是尝试使用来自JavaCV的Haar级联分类器而不是Android本身的facedetector

    链接地址: http://www.djcxy.com/p/11683.html

    上一篇: How to use FaceDetector.Face for face recognition on Android

    下一篇: Custom Alerts for Real