C/C++ 图像处理(18)------人脸检测
2018-02-01 18:00
357 查看
人脸识别包括人脸检测和识别两个部分
一般的逻辑是先检测人脸位置,然后再识别。
具体的流程是
准备要识别的人脸数据->检测人脸->学习人脸特征并生成模型
检测人脸->对比检测出来的人脸和模型的相识度->给出识别结果
本篇文章用OpenCV实现了这两个过程,具体的代码有参考网上的代码,如有雷同,绝非巧合
具体的检测和识别原理不在本篇文章的范畴之内,望见谅
人脸检测
#include <time.h> #include <opencv2/opencv.hpp> #include <vector>//容器头文件 using namespace std; using namespace cv; //关键函数 /* void detectMultiScale( const Mat& image, CV_OUT vector<Rect>& objects, double scaleFactor = 1.1, int minNeighbors = 3, int flags = 0, Size minSize = Size(), Size maxSize = Size() ); */ //参数1:image--待检测图片,一般为灰度图像加快检测速度; //参数2:objects--被检测物体的矩形框向量组; //参数3:scaleFactor--表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1即每次搜索窗口依次扩大10%; //参数4:minNeighbors--表示构成检测目标的相邻矩形的最小个数(默认为3个)。 //如果组成检测目标的小矩形的个数和小于 min_neighbors - 1 都会被排除。 //如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框 //参数5:flags--要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING //CV_HAAR_DO_CANNY_PRUNING--函数将会使用Canny边缘检测来排除边缘过多或过少的区域,因为这些区域通常不会是人脸所在区域; //参数6、7:minSize和maxSize用来限制得到的目标区域的范围。 void getfaceimg()//人脸图像获取 { CascadeClassifier ccf;//创建脸部对象 string cascadeName = "haarcascade_frontalface_alt2.xml";//人脸检测模型,请在OpenCV文件夹中搜索 ccf.load(cascadeName);//读取opencv人脸检测模型 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); //imshow("原图", img); equalizeHist(img, img);//直方图均衡化 //imshow("直方图均衡化", 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();//人脸图像获取 }
分类器训练
//人脸分类器训练,数据库用的ORL人脸数据库,并加入了要识别的人脸放在"S0"文件夹中 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;; }
通过上面的步骤基本上就完成了一个普通的人脸识别流程,但其缺点是准确率还不是很高,要提高准确率可以考虑用深度学习的方法,后面研究到的话会写出来跟大家交流。
相关文章推荐
- C++开发人脸性别识别教程(11)——图片人脸检测程序BUG处理
- 机器视觉开源处理库汇总-介绍n款计算机视觉库/人脸识别开源库/软件 -几种图像处理类库的比较-视觉相关网站
- 图像处理18:透视变换
- 图像处理之基础---卷积及其快速算法的C++实现
- 图像处理 C语言 hough变换 检测直线
- 【数字图像处理】C++读取、旋转和保存bmp图像文件编程实现(转载)
- 图像处理(四):边缘检测(二):sobel和canny
- 图像处理之Canny边缘检测
- 数字图像处理之sobel边缘检测
- FPGA设计——图像处理(Sobel边缘检测)
- 图像处理之霍夫变换(直线检测算法)
- C/C++ 图像处理(8)------图像の柱面投影算法
- opencv图像处理5--车辆检测
- 数字图像处理,相位相关图像配准算法的C++实现
- 数字图像处理,高斯平滑滤波的C++实现
- 图像处理 C语言 hough变换 检测直线
- 图像处理之前景检测(二)之混合高斯模型(主要为知识梳理)
- 图像处理算法基础(八)---霍夫变换直线检测
- 基于OpenCV的火焰检测(一)——图像预处理
- 图像处理--------应用卷积– 轧花与边缘检测 分类: 视频图像处理 2015-07-24 09:50 24人阅读 评论(0) 收藏