我在代码中使用特征脸(PCA)进行人脸识别。我使用OpenCV网站上的教程作为参考。虽然这对于识别面部非常有效(即它可以告诉您谁是正确的),但基于置信度分数的面部验证(或冒号检测 - 验证面部是否在训练集中注册)根本不起作用。
我计算欧几里德距离并将其用作置信度阈值。还有其他方法可以计算置信度阈值吗?我尝试使用http://www.cognotics.com/opencv/servo_2007_series/part_5/page_5.html中提到的Mahalanobis距离,但它产生了非常奇怪的值。
PS:像face.com这样的解决方案可能不适合我,因为我需要在本地做所有事情。
答案 0 :(得分:3)
您可以使用subspaceProject()
函数将新输入面投影到Eigenspace上,然后使用subspaceReconstruct()
从特征空间生成重建面,然后比较 input_face 的相似程度并且 reconstructed_face 是。已知面部(训练数据集中的面部)将使重建图像与冒名者面部更加类似于 input_face 。
您可以设置相似性阈值以进行验证。
这是代码:
// Project the input face onto the eigenspace.
Mat projection = subspaceProject(eigenvectors, FaceRow,input_face.reshape(1,1));
//Generate the reconstructed face
Mat reconstructionRow = subspaceReconstruct(eigenvectors,FaceRow, projection);
// Reshape the row mat to an image mat
Mat reconstructionMat = reconstructionRow.reshape(1,faceHeight);
// Convert the floating-point pixels to regular 8-bit uchar.
Mat reconstructed_face = Mat(reconstructionMat.size(), CV_8U);
reconstructionMat.convertTo(reconstructed_face, CV_8U, 1, 0);
然后,您可以使用cv::norm()
比较输入面和重建面部。例如:
// Calculate the L2 relative error between the 2 images.
double err = norm(input_face,reconstructed_face, CV_L2);
// Convert to a reasonable scale
double similarity = error / (double)(input_face.rows * input_face.cols);
答案 1 :(得分:1)
您可以查看除PCA之外的特征提取算法,如LDA(线性判别分析)或局部二进制模式(LBP)。
LDA模型的类间变化和LBP是光照不变描述符。您可以在OpenCV中实现这两种算法。请查看以下链接。
http://docs.opencv.org/trunk/modules/contrib/doc/facerec/facerec_api.html