C++开发人脸性别识别教程(10)——加入图片的人脸检測程序
2017-07-10 21:56
309 查看
现在我们的MFC框架已经初具规模,能够读取并显示目录下的图片。在这篇博文中我们将向当中加入人脸检測的程序。
一、人脸检測算法
这里我们使用OpenCv封装的Adaboost方法来进行人脸检測,參见:C++开发人脸性别识别教程(4)——OpenCv的人脸检測函数
二、初始化
1、加入初始化button
在进行人脸检測之前须要初始化一些相关变量。比如开辟内存,载入检測器等等。首先,我们为MFC框架加入一个初始化button。并将ID更改为IDC_BUTTON_INITIAL:
双击这个button。加入事件响应函数:
2、初始化变量
从之前的博客中可知。OpenCv在进行人脸检測时须要用到两个静态变量:static CvMemStorage* storage和static CvHaarClassifierCascade* cascade。这里我们将其作为成员变量加入到CGenderRecognitionMFCDlg类中。这里因为static CvMemStorage*和static CvHaarClassifierCascade*这两个类型名在MFC类向导中是无法被识别的,因此须要手动加入至CGenderRecognitionMFCDlg类的构造函数中:
接下里对这两个惊天变量进行初始化。
C++明白规定静态成员变量要在类外进行初始化,而不能在类内声明时或者构造函数内进行初始化,原因就是静态变量时属于类本身的,而非类对象的属性,和全局变量相似,因此我们将这两个静态变量的初始化操作放在GenderRecognitionMFCDlg.cpp文件(从解决方式资源管理器窗体中查找cpp文件)的开头位置:
三、编写人脸检測函数
这里将人脸检測的操作封装成一个函数detect_and_draw(),作为成员函数加入到CGenderRecognitionMFCDlg类中:
在类视图中找到detect_and_draw()函数。完好其人脸检測代码,因为之前已经具体介绍过人脸检測的相关操作。这里直接给出代码:
四、调用人脸检測函数
理论上在显示图像之前应该自己主动调用人脸检測操作,因此在GetNextBigImg()函数中调用人脸检測函数:
因为在detect_and_draw()函数中已经封装了picture显示的程序。所以能够将GetNextBigImg()函数中原有的picture控件显示程序去掉。
大功告成。顺利完毕人脸检測:
三、总结
这里我们初步完毕了MFC中的人脸检測功能。但这里存在两个严重的BUG,一是假设用户未单击“初始化”button,直接打开图片,程序会因缺少必要的初始化步骤而直接崩溃;二是如上图所见,OpenCv在进行人脸检測时可能会错误检測出多个矩形。当中仅仅有一个矩形包括人脸,其余的都是干扰,须要进行处理,我们将在下一篇博客中介绍怎样解决这两个BUG。
同一时候在此须要强调一下两个问题:
1、静态成员变量的初始化:c++中能够对类中私有成员中的静态变量初始化吗?
2、字符串的连接:C++字符换行 .
一、人脸检測算法
这里我们使用OpenCv封装的Adaboost方法来进行人脸检測,參见:C++开发人脸性别识别教程(4)——OpenCv的人脸检測函数
二、初始化
1、加入初始化button
在进行人脸检測之前须要初始化一些相关变量。比如开辟内存,载入检測器等等。首先,我们为MFC框架加入一个初始化button。并将ID更改为IDC_BUTTON_INITIAL:
双击这个button。加入事件响应函数:
2、初始化变量
从之前的博客中可知。OpenCv在进行人脸检測时须要用到两个静态变量:static CvMemStorage* storage和static CvHaarClassifierCascade* cascade。这里我们将其作为成员变量加入到CGenderRecognitionMFCDlg类中。这里因为static CvMemStorage*和static CvHaarClassifierCascade*这两个类型名在MFC类向导中是无法被识别的,因此须要手动加入至CGenderRecognitionMFCDlg类的构造函数中:
接下里对这两个惊天变量进行初始化。
C++明白规定静态成员变量要在类外进行初始化,而不能在类内声明时或者构造函数内进行初始化,原因就是静态变量时属于类本身的,而非类对象的属性,和全局变量相似,因此我们将这两个静态变量的初始化操作放在GenderRecognitionMFCDlg.cpp文件(从解决方式资源管理器窗体中查找cpp文件)的开头位置:
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框 CvMemStorage* CGenderRecognitionMFCDlg::storage = NULL; CvHaarClassifierCascade* CGenderRecognitionMFCDlg::cascade = NULL;然后在“初始化”button的响应函数OnBnClickedButtonInitial()中载入相应的人脸检測器:
void CGenderRecognitionMFCDlg::OnBnClickedButtonInitial() { cascade = cvLoadHaarClassifierCascade("D:\\opencv\\sources\\data\\haarcascades \\haarcascade_frontalface_alt_tree.xml",cvSize(30,30)); storage = cvCreateMemStorage(0); // TODO: 在此加入控件通知处理程序代码 }初始化完毕。
三、编写人脸检測函数
这里将人脸检測的操作封装成一个函数detect_and_draw(),作为成员函数加入到CGenderRecognitionMFCDlg类中:
在类视图中找到detect_and_draw()函数。完好其人脸检測代码,因为之前已经具体介绍过人脸检測的相关操作。这里直接给出代码:
void CGenderRecognitionMFCDlg::detect_and_draw(IplImage* img) { /**********初始化**********/ double scale = 1.2; IplImage* gray = cvCreateImage(cvSize(img->width,img->height),8,1); /**********灰度化**********/ if (img->nChannels = 3) { cvCvtColor(img,gray, CV_BGR2GRAY);//将图像灰度化存放在gray中 } else { gray = img; } /**********直方图均衡**********/ cvEqualizeHist(gray,gray); /**********人脸检測**********/ cvClearMemStorage(storage); CvSeq* objects = cvHaarDetectObjects(gray,//待检測图像 cascade, //分类器标识 storage, //存储检測到的候选矩形 1.3, //相邻两次检測中窗体扩大的比例 3, //觉得是人脸的最小矩形数(阈值) 0, //CV_HAAR_DO_CANNY_PRUNING cvSize(30,30)); //初始检測窗体大小 /**********绘制检測结果**********/ if(objects->total > 0) //假设人脸检測成功 { for (int i = 0; i < (objects ? objects->total : 0); i++) { CvRect* rect = (CvRect*)cvGetSeqElem(objects,i); cvRectangle(img,cvPoint(rect->x,rect->y), cvPoint(rect->x + rect->width,rect->y + rect->height),cvScalar(0.0,255)); } } /**********在图像控件上显示图像**********/ CvvImage cvvImage; cvvImage.CopyOf(img); cvvImage.DrawToHDC(m_pPicCtlHdc,m_PicCtlRect); cvReleaseImage(&gray); }注意这里相对于之前的程序,加入了一项直方图均衡化的操作。以提高人脸检測的成功率:
四、调用人脸检測函数
理论上在显示图像之前应该自己主动调用人脸检測操作,因此在GetNextBigImg()函数中调用人脸检測函数:
因为在detect_and_draw()函数中已经封装了picture显示的程序。所以能够将GetNextBigImg()函数中原有的picture控件显示程序去掉。
大功告成。顺利完毕人脸检測:
三、总结
这里我们初步完毕了MFC中的人脸检測功能。但这里存在两个严重的BUG,一是假设用户未单击“初始化”button,直接打开图片,程序会因缺少必要的初始化步骤而直接崩溃;二是如上图所见,OpenCv在进行人脸检測时可能会错误检測出多个矩形。当中仅仅有一个矩形包括人脸,其余的都是干扰,须要进行处理,我们将在下一篇博客中介绍怎样解决这两个BUG。
同一时候在此须要强调一下两个问题:
1、静态成员变量的初始化:c++中能够对类中私有成员中的静态变量初始化吗?
2、字符串的连接:C++字符换行 .
相关文章推荐
- C++开发人脸性别识别教程(10)——添加图片的人脸检测程序
- C++开发人脸性别识别教程(11)——图片人脸检测程序BUG处理
- C++开发人脸性别识别教程(9)——搭建MFC框架之显示图片
- C++开发人脸性别识别教程(9)——搭建MFC框架之显示图片
- C++开发人脸性别识别教程(13)——针对单张图片的性别识别
- C++开发人脸性别识别教程(3)——OpenCv配置和ImageWatch插件介绍
- C++开发人脸性别识别教程(16)——视频人脸性别识别
- C++开发人脸性别识别教程(6)——通过SVM实现性别识别
- C++开发人脸性别识别教程(15)——搭建MFC框架启动摄像头
- C++开发人脸性别识别教程(7)——搭建MFC框架之界面绘制
- C++开发人脸性别识别教程(5)——通过FaceRecognizer类实现性别识别
- C++开发人脸性别识别教程(16)——视频人脸性别识别
- C++开发人脸性别识别教程(14)——灰度图像识别BUG处理
- C++开发人脸性别识别教程(17)——辅助功能之人脸批量分割
- C++开发人脸性别识别教程(3)——OpenCv配置和ImageWatch插件介绍
- C++开发人脸性别识别教程(8)——搭建MFC框架之读取目录信息
- C++开发人脸性别识别教程(6)——通过SVM实现性别识别
- C++开发人脸性别识别教程(1)——前瞻
- C++开发人脸性别识别教程(2)——VisualStudio初探
- C++开发人脸性别识别教程(12)——添加性别识别功能