博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OpenCV入门指南 人脸检测 haar分类器
阅读量:6148 次
发布时间:2019-06-21

本文共 4341 字,大约阅读时间需要 14 分钟。

OpenCV入门指南  人脸检测 

    本篇介绍图像处理与模式识别中最热门的一个领域——人脸检测(人脸识别)。人脸检测可以说是学术界的宠儿,在不少EISCI高级别论文都能看到它的身影。甚至很多高校学生的毕业设计都会涉及到人脸检测。当然人脸检测的巨大实用价值也让很多公司纷纷关注,很多公司都拥有这方面的专利或是开发商业产品出售。

    OpenCV中,人脸检测也是其热门应用之一。在OpenCV就详细介绍了人脸检测的原理——通过Haar特征来识别是否为人脸。本篇主要介绍如何在OpenCV中使用Haar特征分类器来对图像中的人脸进行检测和识别。下面将分成五步来详细示范如何在OpenCV中进行人脸识别:

    一.人脸的Haar特征分类器是什么

    二.在哪找人脸的Haar特征分类器

    三.怎么用人脸的Haar特征分类器

    四.人脸识别示例代码

    五.人脸识别程序运行结果

 

一.人脸的Haar特征分类器是什么

人脸的Haar特征分类器就是一个XML文件,该文件中会描述人脸的Haar特征值。当然Haar特征的用途可不止可以用来描述人脸这一种,用来描述眼睛,嘴唇或是其它物体也是可以的。

 

二.在哪找人脸的Haar特征分类器

OpenCV有已经自带了人脸的Haar特征分类器。OpenCV安装目录中的\data\ haarcascades目录下的haarcascade_frontalface_alt.xmlhaarcascade_frontalface_alt2.xml都是用来检测人脸的Haar分类器。这个haarcascades目录下还有人的全身,眼睛,嘴唇的Haar分类器。读者可以仿照本方的例子来试验下效果看看。

 

三.怎么用人脸的Haar特征分类器

使用人脸的Haar特征分类器非常之简单,直接使用cvHaarDetectObjects。下面来看看这个函数的介绍:

函数功能:检测图像中的目录

函数原型:

CVAPI(CvSeq*) cvHaarDetectObjects(

  const CvArr* image,

  CvHaarClassifierCascade* cascade,

  CvMemStorage* storage,

  double scale_factor CV_DEFAULT(1.1),

  int min_neighbors CV_DEFAULT(3),

  int flags CV_DEFAULT(0),

  CvSize min_size CV_DEFAULT(cvSize(0,0)),

  CvSize max_size CV_DEFAULT(cvSize(0,0))

);

函数说明:

第一个参数表示输入图像,尽量使用灰度图以加快检测速度。

第二个参数表示Haar特征分类器,可以用cvLoad()函数来从磁盘中加载xml文件作为Haar特征分类器。

第三个参数为CvMemStorage类型

第四个参数表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1即每次搜索窗口依次扩大10%

第五个参数表示构成检测目标的相邻矩形的最小个数(默认为3)。如果组成检测目标的小矩形的个数和小于 min_neighbors - 1 都会被排除。如果min_neighbors 0, 则函数不做任何操作就返回所有的被检候选矩形框,这种设定值一般用在用户自定义对检测结果的组合程序上。

第六个参数要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果设置为CV_HAAR_DO_CANNY_PRUNING,那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域,因此这些区域通常不会是人脸所在区域。

第七个,第八个参数表示检测窗口的最小值和最大值,一般设置为默认即可。

函数返回值:

函数将返回CvSeq对象,该对象包含一系列CvRect表示检测到的人脸矩形。

 

四.人脸识别示例代码

void CHaardetectfaceDlg::Ondetectface(){    // TODO: Add your control notification handler code here    // 加载Haar特征检测分类器    // haarcascade_frontalface_alt.xml系OpenCV自带的分类器 下面是我机器上的文件路径     const char *pstrCascadeFileName = "F:\\Program Files (x86)\\OpenCV\\data\\haarcascades\\haarcascade_frontalface_alt.xml";    CvHaarClassifierCascade *pHaarCascade = NULL;                                     pHaarCascade = (CvHaarClassifierCascade*)cvLoad(pstrCascadeFileName);          //从磁盘中加载xml文件    // 载入图像     const char *pstrImageName = "9.jpg";     IplImage *pSrcImage = cvLoadImage(pstrImageName, CV_LOAD_IMAGE_UNCHANGED);     //读入图片    IplImage *pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);      cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);                                 //rgb转化为灰度图    if (pHaarCascade!=NULL)    {        // 人脸识别与标记         CvScalar FaceCirclecolors[] =        {            {
{0, 0, 255}}, {
{0, 128, 255}}, {
{0, 255, 255}}, {
{0, 255, 0}}, {
{255, 128, 0}}, {
{255, 255, 0}}, {
{255, 0, 0}}, {
{255, 0, 255}} }; CvMemStorage *pcvMStorage = cvCreateMemStorage(0); //申请一块内存来存储找到的轮廓序列 cvClearMemStorage(pcvMStorage); // 识别 DWORD dwTimeBegin, dwTimeEnd; dwTimeBegin = GetTickCount(); CvSeq *pcvSeqFaces = cvHaarDetectObjects(pGrayImage, pHaarCascade, pcvMStorage); dwTimeEnd = GetTickCount(); // printf("人脸个数: %d 识别用时: %d ms\n", pcvSeqFaces->total, dwTimeEnd - dwTimeBegin); 可以输出个数和所化时间 //标记 m_total=pcvSeqFaces->total; m_time=dwTimeEnd - dwTimeBegin; UpdateData(FALSE); 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, FaceCirclecolors[i % 8], 2); }; cvReleaseMemStorage(&pcvMStorage); }; const char *pstrWindowsTitle = "人脸检测"; cvNamedWindow(pstrWindowsTitle, CV_WINDOW_AUTOSIZE); cvShowImage(pstrWindowsTitle, pSrcImage); cvWaitKey(0); cvDestroyWindow(pstrWindowsTitle); cvReleaseImage(&pSrcImage); cvReleaseImage(&pGrayImage); }

  

五.人脸识别程序运行结果

运行结果一(单人正面):

 

 

  

这张图的干扰太少,换张干扰大点的图来试试。

 

运行结果二

 

 

 

运行结果三(多人):

 

 

效果还不错。但也存在缺点,可能会将背景部分误认为是头部。当然商业级产品的准确度,性能,效率肯定会比OpenCV自带的分类器高的多。

 

 

2013-06-18 09:28:54

转载于:https://www.cnblogs.com/EnteRbo/p/3141746.html

你可能感兴趣的文章
关于C#导出 文本文件
查看>>
使用native 查询时,对特殊字符的处理。
查看>>
maclean liu的oracle学习经历--长篇连载
查看>>
ECSHOP调用指定分类的文章列表
查看>>
分享:动态库的链接和链接选项-L,-rpath-link,-rpath
查看>>
Javascript一些小细节
查看>>
禁用ViewState
查看>>
Android图片压缩(质量压缩和尺寸压缩)
查看>>
nilfs (a continuent snapshot file system) used with PostgreSQL
查看>>
【SICP练习】150 练习4.6
查看>>
HTTP缓存应用
查看>>
KubeEdge向左,K3S向右
查看>>
DTCC2013:基于网络监听数据库安全审计
查看>>
CCNA考试要点大搜集(二)
查看>>
ajax查询数据库时数据无法更新的问题
查看>>
Kickstart 无人职守安装,终于搞定了。
查看>>
linux开源万岁
查看>>
linux/CentOS6忘记root密码解决办法
查看>>
25个常用的Linux iptables规则
查看>>
集中管理系统--puppet
查看>>