安装完OpenCV之后,目录下有很多例子代码,其中一份名为FaceDetect的代码激起了我的兴趣,打开一看,果然是实现人脸检测的. 于是借鉴了下它的思路,实现了一个简单的人脸检测的程序。
注意: 本例中,分类训练器的xml文件路径如下:
D:\OpenCV\opencv\data\haarcascades\haarcascade_frontalface_alt.xml
但由于在C++中\\是一种转义字符, 只表示一个\, 就和\n表示回车一样, 所以指定路径时应变成如下:
D:\\OpenCV\\opencv\\data\\haarcascades\\haarcascade_frontalface_alt.xml
刚开始时由于大意,忘记转换了,导致总是检测失败.
代码如下:
#include <opencv2/opencv.hpp> #include <cstdio> #include <cstdlib> #include <Windows.h> using namespace std; const char *pcascadeName = "D:\\OpenCV\\opencv\\data\\haarcascades\\haarcascade_frontalface_alt.xml"; const char *pImageName = "image.jpg"; void DetectAndMark(); int main(int argc, const char** argv) { DetectAndMark(); return 0; } void DetectAndMark() { // load the Haar classifier CvHaarClassifierCascade *pHaarClassCascade; pHaarClassCascade = (CvHaarClassifierCascade*)cvLoad(pcascadeName); //load the test image IplImage *pSrcImage = cvLoadImage(pImageName, CV_LOAD_IMAGE_UNCHANGED); IplImage *pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1); if(pSrcImage == NULL || pGrayImage == NULL) { printf("can't load image!\n"); return; } cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY); if (pHaarClassCascade != NULL && pSrcImage != NULL && pGrayImage != NULL) { const static CvScalar colors[] = { CV_RGB(0,0,255), CV_RGB(0,128,255), CV_RGB(0,255,255), CV_RGB(0,255,0), CV_RGB(255,128,0), CV_RGB(255,255,0), CV_RGB(255,0,0), CV_RGB(255,0,255) }; CvMemStorage *pcvMemStorage = cvCreateMemStorage(0); cvClearMemStorage(pcvMemStorage); //detect the face int TimeStart, TimeEnd; TimeStart = GetTickCount(); CvSeq *pcvSeqFaces = cvHaarDetectObjects(pGrayImage, pHaarClassCascade, pcvMemStorage); TimeEnd = GetTickCount(); printf("the number of faces: %d\nSpending Time: %d ms\n", pcvSeqFaces->total, TimeEnd - TimeStart); //mark the face for(int i = 0; i <pcvSeqFaces->total; i++) { CvRect* r = (CvRect*)cvGetSeqElem(pcvSeqFaces, i); CvPoint center; int radius; center.x = cvRound((r->x + r->width * 0.5)); center.y = cvRound((r->y + r->height * 0.5)); radius = cvRound((r->width + r->height) * 0.25); cvCircle(pSrcImage, center, radius, colors[i % 8], 2); } cvReleaseMemStorage(&pcvMemStorage); } const char *pstrWindowsTitle = "FaceDetect Demo"; cvNamedWindow(pstrWindowsTitle, CV_WINDOW_AUTOSIZE); cvShowImage(pstrWindowsTitle, pSrcImage); cvWaitKey(0); cvDestroyWindow(pstrWindowsTitle); cvReleaseImage(&pSrcImage); cvReleaseImage(&pGrayImage); }
现在到了考验程序的准确度的时候了,先选了张简单的图片,结果如下:
还不错,准确检测出来了,来张多人脸的图测试下:
居然也都通过了,看来这个类Haar分类训练器果然训练有素啊, 再来一张试试:
这次露马脚了,居然唯独把LP的主唱Chester给忽视了。。 再来一张测验下:
呵呵,这次中招的更多了,马政委也被无视了。。 最后特意挑了张脸部有重叠的检验一下:
这个也检测出来了,有点出乎意料。
总结:总体来说,人脸检测水平还不错,但离商用级别还有不小差距, 后续有时间将详细研究下其算法! 真个工程已经上传至我的资源, 有兴趣的朋友可以点击这里下载!