人脸识别包括人脸检测和识别两个部分
一般的逻辑是先检测人脸位置,然后再识别。
具体的流程是
准备要识别的人脸数据->检测人脸->学习人脸特征并生成模型
检测人脸->对比检测出来的人脸和模型的相识度->给出识别结果
本篇文章用OpenCV实现了这两个过程,具体的代码有参考网上的代码,如有雷同,绝非巧合
具体的检测和识别原理不在本篇文章的范畴之内,望见谅
人脸检测
#include <time.h>
#include <opencv2/opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
void getfaceimg()
{
CascadeClassifier ccf;
string cascadeName = "haarcascade_frontalface_alt2.xml";
ccf.load(cascadeName);
vector<Rect> faces;
long time = clock();
string path;
for (size_t i = 0; i < 5; i++)
{
path = to_string(i + 1);
path.append(".jpg");
Mat img = imread(path, 0);
equalizeHist(img, img);
ccf.detectMultiScale(img, faces, 1.1, 3, CV_HAAR_DO_CANNY_PRUNING, Size(50, 50), Size(500, 500));
for (vector<Rect>::const_iterator iter = faces.begin(); iter != faces.end(); iter++)
{
rectangle(img, *iter, Scalar(0), 2, 8);
}
Mat faceimg;
for (vector<Rect>::const_iterator iter = faces.begin(); iter != faces.end(); iter++)
{
faceimg = img(*iter);
imshow("脸部图像", faceimg);
imwrite("faceImg//" + path, faceimg);
}
imshow("检测结果", img);
waitKey(1000);
}
cout << "花费时间:" << clock() - time << "ms" << endl;
}
void main()
{
getfaceimg();
}
分类器训练
void TrainFaceImg()
{
std::vector<Mat> images;
std::vector<int> labels;
for (size_t s = 0; s <= 40; s++)
{
String path = "att_faces//s"+ to_string(s)+"//";
for (size_t i = 1; i <= 10; i++)
{
String imgpath = path + to_string(i) + ".pgm";
Mat trainfaceimg = imread(imgpath, CV_LOAD_IMAGE_GRAYSCALE);
resize(trainfaceimg, trainfaceimg, Size(128, 128));
images.push_back(trainfaceimg);
labels.push_back(s);
}
}
Ptr<FaceRecognizer> faceClass = createEigenFaceRecognizer();
Ptr<FaceRecognizer> fisherClass = createFisherFaceRecognizer();
Ptr<FaceRecognizer> lpbhClass = createLBPHFaceRecognizer();
faceClass->train(images, labels);
fisherClass->train(images, labels);
lpbhClass->train(images, labels);
faceClass->save("faceClass.xml");
fisherClass->save("fisherClass.xml");
lpbhClass->save("lpbhClass.xml");
cout << "分类器训练完成"<< endl;
}
人脸识别(注意要放进去识别的图片是先经过检测、裁剪和尺度变换后的图片)
void FaceDetect()
{
Ptr<FaceRecognizer> faceClass = createEigenFaceRecognizer();
Ptr<FaceRecognizer> fisherClass = createFisherFaceRecognizer();
Ptr<FaceRecognizer> lpbhClass = createLBPHFaceRecognizer();
faceClass->load("faceClass.xml");
fisherClass->load("fisherClass.xml");
lpbhClass->load("lpbhClass.xml");
Mat detectimg = imread("faceImg//14.pgm", 0);
resize(detectimg, detectimg, Size(128, 128));
int faceResult = faceClass->predict(detectimg);
cout << String("faceClass标签类别:") << faceResult << endl;;
int fisherResult = -1;
double fisherConfidence = 0.0;
fisherClass->predict(detectimg, fisherResult, fisherConfidence);
cout << String("fisherClass标签类别:") << fisherResult << String("置信度:") << fisherConfidence << endl;
int lpbhResult = lpbhClass->predict(detectimg);
cout << String("lpbhResult标签类别:") << lpbhResult << endl;;
}
通过上面的步骤基本上就完成了一个普通的人脸识别流程,但其缺点是准确率还不是很高,要提高准确率可以考虑用深度学习的方法,后面研究到的话会写出来跟大家交流。