这是我在这里的第一篇文章,所以如果我的问题不明确或者提供的信息不足,我很抱歉.
我目前正在研究一种可以识别图片中脸部的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,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()); }
最后我用以下代码识别face:
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)
,其中:
> threshold – 预测中应用的阈值.如果到最近邻居的距离大于阈值,则此方法返回-1.
因此,在上面的方法签名中,您会看到默认情况下阈值设置为DBL_MAX.因此,如果您只是将阈值排除在外,那么它永远不会产生-1.另一方面,如果将阈值设置得太低,FaceRecognizer总是会产生-1.也就是说,检查你在代码中设置了binaryTreshold的内容.为您的数据找到合适的决策阈值是一个典型的优化问题,您必须根据给定的标准(例如基于错误接受率/错误拒绝率)优化最佳阈值.