前言:博主现在也只是大三狗,之前帮同学做了人脸识别的小软件,帮他在某项目中结题。经过十天左右的码码历程,终于在网上代码+自己捣鼓将这个小小小小小项目码了出来。所以就以分享这个小小小软件的历程,对做这类项目的同学一点帮助。此博文可能不能做到一次性更新完,但是我尽量做到有空的时候来更新一下。
声明:由于暂时本科大三,学历、资历暂时有限,在以下文章可能会引用网上各大前辈的一些内容,但是我尽量做到在引用前咨询原创前辈,并做出相关超链接。如果有前辈发现这个内容有部分侵犯您版权,希望前辈可以联系我,我定将很快的删除,并做出道歉,谢谢~
近30年,随概率、神经网络等理论、算法的快速发展,计算机性能不断提高,人脸识别越来越流行,但是又不得不承认这个也是非常困难的话题。所以此文仅介绍比较简单的算法。
此系列文章内容:人脸检测=》人脸预处理=》人脸训练=》人脸识别
零、Opencv安装
Opencv安装过程详见
OpenCV 开发环境的搭建(Win8.1 + VS2013 + OpenCV 2.4.8)
http://www.hiclk.com/2015/03/24/opencv248vs2013/
一、人脸检测
由于Opencv中文首页及Opencv的示例代码中都提到了Haar特征检测器,故此项目中亦采用这种比较常见的人脸检测方法。
关于Haar特征的Adaboost级联人脸检测分类器的详细介绍,请参考雨石前辈的详细介绍
http://blog.csdn.net/stdcoutzyx/article/details/34842233
相信根据上文的学习,读者也对Haar特征的级联分类器有了比较清晰的认识,我们就只来关注此级联分类器的使用。
贴上Haar特征检测的C++实现代码。
<此代码来源于网上,注释为我添加,暂未找到原创作者,若侵犯你的权益,请联系我,我将速更换>
此函数输入IplImage基本数据结构和Haar级联分类器,输出检测到人脸边缘的CvRect矩形框,若未检测到人脸,则返回{-1,-1,-1,-1}
CvRect detectFaceInImage(constIplImage*inputImg,constCvHaarClassifierCascade*cascade)//传入图像与级联分类器指针 { const CvSize minFeatureSize = cvSize(20, 20);//定义核大小 const int flags = CV_HAAR_FIND_BIGGEST_OBJECT | CV_HAAR_DO_ROUGH_SEARCH; // 定义非重复检测 const float search_scale_factor = 1.1f;//定义搜索比例 IplImage *detectImg; IplImage *greyImg = 0; CvMemStorage* storage; CvRect rc; double t; CvSeq* rects; int i; storage = cvCreateMemStorage(0); cvClearMemStorage(storage); detectImg = (IplImage*)inputImg; if (inputImg->nChannels > 1)//是否为灰度图像 { greyImg = cvCreateImage(cvSize(inputImg->width, inputImg->height), IPL_DEPTH_8U, 1);//创建单通道灰度图像 cvCvtColor(inputImg, greyImg, CV_BGR2GRAY);//颜色转化 detectImg = greyImg; } t = (double)cvGetTickCount();//得到系统启动所经历毫秒数 rects = cvHaarDetectObjects(detectImg, (CvHaarClassifierCascade*)cascade, storage, search_scale_factor, 3, flags, minFeatureSize);//检测图像中的目标(人脸) t = (double)cvGetTickCount() - t;//得到计算总耗时 // 得到检测的最大人脸 if (rects->total > 0) { rc = *(CvRect*)cvGetSeqElem(rects, 0); } else rc = cvRect(-1, -1, -1, -1); // Couldn't find the face. if (greyImg) cvReleaseImage(&greyImg); cvReleaseMemStorage(&storage); return rc;// 返回寻找到最大脸的矩形边缘坐标 }
函数调用函数如下:
void Recognition() { frame = cvQueryFrame(cam);//从摄像头获取一帧图像IplImage结构图像 CvHaarClassifierCascade* faceCascade;//定义级联分类器 CvRect faceRect;//定义矩形区域结构 faceCascade =cvLoadHaarClassifierCascade(faceCascadeFilename,cvSize(20,20)); //从文件中装载训练好的级联分类器 const char *faceCascadeFilename = "haarcascade_frontalface_alt.xml";此文件 百度可得到 faceRect = detectFaceInImage(frame, faceCascade);//执行上面函数,返回矩形结构 cvRectangle(frame, cvPoint(faceRect.x, faceRect.y), cvPoint(faceRect.x + faceRect.width - 1, faceRect.y + faceRect.height - 1), CV_RGB(0, 255, 0), 1, 8, 0); //在原Iplimage结构用矩形中标记出人脸 }