opencv识别自己的脸
本篇记录使用训练好的人脸识别模型来识别自己的脸。环境:VS2015,版本:opencv3.3.0。
过程
- 加载opencv人脸检测的分类器;
- 加载人脸识别模型;
- 打开摄像头,读取图像;
- 对读取的图像进行人脸检测,检测到就调整到与训练集图片相同的大小;
- 把人脸与人类识别模型中的做对比,输出标签值;
其中关于得到人脸识别模型可以参考:http://blog.csdn.net/wanghz999/article/details/78773643
代码
#include<iostream>
#include<fstream>
#include<sstream>
#include<math.h>
#include<opencv2\opencv.hpp>
#include<opencv2\highgui.hpp>
#include<cv.h>
#include<objdetect.hpp>
#include<opencv2/face.hpp>
using namespace cv::face;
using namespace std;
using namespace cv;
CascadeClassifier cascade;
string cascade_xml_path = "F:/software/MyOpencv-3.3.0/install/etc/haarcascades/haarcascade_frontalface_alt.xml";
int main()
{
VideoCapture cap(0);
assert(!cap.isOpened());
cap.set(CV_CAP_PROP_FPS, 25.0);
Mat test_img = imread("./data/whz.jpg", IMREAD_GRAYSCALE);
Mat frame,img_gray,faceROI;
Size my_size(92, 112);
int test_label = 35; //测试人脸的标签,35是我的标签值
int p_label;
vector<Rect> faces;
namedWindow("View");
cascade.load(cascade_xml_path);
/*读取人脸识别模型*/
//Ptr<EigenFaceRecognizer> model = Algorithm::load<EigenFaceRecognizer> \
("./data/my_eigen_face_model.xml"); //Eigen Faces算法
//Ptr<FisherFaceRecognizer> model = Algorithm::load<FisherFaceRecognizer> \
("./data/my_fisher_face_model.xml");//Fisher Faces算法
Ptr<LBPHFaceRecognizer> model = Algorithm::load<LBPHFaceRecognizer> \
("./data/my_lbph_face_model.xml"); //Local Binary Pattern Histograms
while (1)
{
cap >> frame;
cvtColor(frame, img_gray, CV_RGB2GRAY);
equalizeHist(img_gray, img_gray);
//人脸检测
cascade.detectMultiScale(frame, faces, 1.1, 3, \
CV_HAAR_SCALE_IMAGE, Size(30, 30));
if (faces.size() > 0)
{
for (int i = 0; i < faces.size(); ++i)
{
faceROI = img_gray(faces[i]); //灰度图才能与人脸识别模型中的进行对比
resize(faceROI, faceROI, my_size); //调整成训练集一样的大小
rectangle(frame, faces[i], Scalar(255, 0, 0), 2, 8, 0);
p_label = model->predict(faceROI);
cout << "Test label:" << test_label << ",predict lable:" \
<< p_label << endl;
imshow("View", frame);
waitKey(100);
}
}
}
return 0;
}
结果与说明
得到的结果截图如下(我长得比较丑就不放自己的人脸了):
可以看到,人脸识别模型能够正确地识别我的脸。
但是,也是会出现误判的情况,主要原因是训练集中的图片太少。刚开始时我自己也只采集了10张图,与The ORL Database of Faces’数据库中的400张图作为训练集来训练,发现面部表情比较剧烈时就容易出现误判。然后将自己的人脸图加到100张左右,程序识别的正确率就有了一个很大提高。下面附上快速获取人脸训练集的程序:
快速获取人脸训练集程序
#include<iostream>
#include<fstream>
#include<sstream>
#include<math.h>
#include<opencv2\opencv.hpp>
#include<opencv2\highgui.hpp>
#include<cv.h>
#include<objdetect.hpp>
#include<opencv2/face.hpp>
using namespace cv::face;
using namespace std;
using namespace cv;
CascadeClassifier cascade;
//人脸检测分类器模型
string cascade_xml_path = "F:/software/MyOpencv-3.3.0/install/etc/haarcascades/haarcascade_frontalface_alt.xml";
int main()
{
VideoCapture cap(0);
assert(!cap.isOpened());
cap.set(CV_CAP_PROP_FPS, 25.0);
Mat frame, img_gray, faceROI;
Size my_size(92, 112); //训练集图像大小
string keep_path = "./data/"; //存放采集后图像的人脸训练集目录
string my_path,tmp_path;
vector<Rect> faces;
namedWindow("View");
int count = 0;
if(!cascade.load(cascade_xml_path))
cout<<"Load haarcascade_frontalface_alt.xml error!"<<endl;
while (1)
{
cap >> frame;
cvtColor(frame, img_gray, CV_RGB2GRAY);
equalizeHist(img_gray, img_gray);
cascade.detectMultiScale(frame, faces, 1.1, 6, CV_HAAR_SCALE_IMAGE, Size(30, 30));
if (faces.size() > 0)
{
for (int i = 0; i < faces.size(); ++i)
{
faceROI = frame(faces[i]);
resize(faceROI, faceROI, my_size);
rectangle(frame, faces[i], Scalar(255, 0, 0), 2, 8, 0);
imshow("View", frame);
waitKey(100);
tmp_path = format("%d.jpg", count++);
my_path = keep_path + tmp_path;
imwrite(my_path, faceROI);
}
}
}
return 0;
}
采集完成之后,对一些模糊不清的人脸进行删除之后就可以加入到训练集中了。