运用Opencv实现人脸的检测和识别是非常方便的,也比较常用。对于人脸检测可以用Opencv自带的分类器实现,而人脸识别需要自建训练分类器,以及收集人脸数据。本文重点讲讲人脸数据的训练以及人脸识别的实现,识别功能的实现也结合了MFC这个基础类库,界面更加美观。

1.人脸数据训练

关于数据的训练以及识别的教程可以参考博客:,在这篇博文里作者已经把流程说的很详细了,本文参照这个流程实现了人脸识别。

        在人脸模型的训练时,可以通过CSV文件来读取。人脸数据为The AT&TFacedatabase,其中有40个人的人脸数据,每人10张。训练时可加入自己的人脸图片集,编号可记为41。关于人脸的提取可用ROI感兴趣区域分割即可。CSV文件主要保存人脸图片的路径和人脸的标签。例如本文生成的CSV文件at.txt,如图所示:

opencv人脸老化 opencv人脸训练_MFC

得到上述at.txt文件后进行数据的训练。训练时用到了Opencv中提供的Facerecognixzer这个类,并且Opencv自带了三个人脸识别的算法:Eigenfaces,Fisherfaces以及局部二值模式直方图(LBPH)。这三个算法训练可得到三个XML文件,具体的训练格式如下:


Ptr<FaceRecognizer> model = createEigenFaceRecognizer();
model->train(images, labels);  
model->save("MyFacePCAModel.xml");
 Ptr<FaceRecognizer> model1 = createFisherFaceRecognizer(); 
model1->train(images, labels); 
model1->save("MyFaceFisherModel.xml");
 Ptr<FaceRecognizer> model2 = createLBPHFaceRecognizer();
 model2->train(images, labels);
 model2->save("MyFaceLBPHModel.xml");


具体的完整代码可参考引用的博文,可以实现人脸数据集的训练。


2.人脸的识别


    人脸识别的资料比较多了,网上开源的代码也很多,前面引用的博文里有具体的代码,也可以运行实现,这里就不贴了。人脸识别过程中主要用到haarcascade_frontalface_alt.xml这个文件,使用该文件主要实现人脸的检测,框出人脸位置,再使用训练得到的文件(比如本文选用MyFacePCAModel.xml)来预测识别结果。测试的程序一般格式如下:



//建立用于存放人脸的向量容器  
vector<Rect> faces(0);  
cvtColor(frame, gray, CV_BGR2GRAY);
//改变图像大小,使用双线性差值   
//变换后的图像进行直方图均值化处理  
equalizeHist(gray, gray);  
  
cascade.detectMultiScale(gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE,Size(30, 30));


得到预测的识别结果,参考的博文中直接用modelPCA->predict(face_test),但本文测试得到的识别结果并不理想;



Mat face_test; 
int predictPCA = 0; 
if (face.rows >= 120) 
{ 
 resize(face, face_test, Size(92, 112)); }
 if (!face_test.empty()) { 
 predictPCA = modelPCA->predict(face_test); 
}


后来考虑加入predicted_confidence的阈值判断,发现通过调整该阈值的值可以提高识别的效果。因此本文采用如下格式,并框出人脸附上名字信息:


if (!face_test.empty())  
  {  
            //测试图像应该是灰度图 
            modelPCA->predict(face_test,predictedLabel,predicted_confidence);
            //predictPCA = modelPCA->predict(face_test);  
  }  
        cout << predictPCA << endl;  
        if (predictedLabel == 0)//predictPCA == 40  
  {  
            string name = "HuFuping";  
            putText(frame, name, text_lb, FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255));  
  }


具体实现的效果图如下(结合MFC):


opencv人脸老化 opencv人脸训练_opencv人脸老化_02



关于的MFC的使用与实现本文暂不具体介绍,不是很复杂,谢谢支持~