运用Opencv实现人脸的检测和识别是非常方便的,也比较常用。对于人脸检测可以用Opencv自带的分类器实现,而人脸识别需要自建训练分类器,以及收集人脸数据。本文重点讲讲人脸数据的训练以及人脸识别的实现,识别功能的实现也结合了MFC这个基础类库,界面更加美观。
1.人脸数据训练
关于数据的训练以及识别的教程可以参考博客:,在这篇博文里作者已经把流程说的很详细了,本文参照这个流程实现了人脸识别。
在人脸模型的训练时,可以通过CSV文件来读取。人脸数据为The AT&TFacedatabase,其中有40个人的人脸数据,每人10张。训练时可加入自己的人脸图片集,编号可记为41。关于人脸的提取可用ROI感兴趣区域分割即可。CSV文件主要保存人脸图片的路径和人脸的标签。例如本文生成的CSV文件at.txt,如图所示:
得到上述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):
关于的MFC的使用与实现本文暂不具体介绍,不是很复杂,谢谢支持~