OpenCV入门指南----人脸检测

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

    在OpenCV中,人脸检测也是其热门应用之一。在OpenCV的特征检测专题就详细介绍了人脸检测的原理——通过Haar特征来识别是否为人脸。Haar特征检测原理与Haar特征分类器的训练放到下一篇《【OpenCV入门指南】第十四篇  Haartraining》来讲,本篇主要介绍如何在OpenCV中使用Haar特征分类器来对图像中的人脸进行检测和识别。下面将分成五步来详细示范如何在OpenCV中进行人脸识别:

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

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

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

    四.人脸识别示例代码

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

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

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

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

OpenCV有已经自带了人脸的Haar特征分类器。OpenCV安装目录中的\data\ haarcascades目录下的haarcascade_frontalface_alt.xml与haarcascade_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类型,大家应该很熟悉这个CvMemStorage类型了,《OpenCV入门指南》中很多文章都介绍过了。

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

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

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

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

函数返回值:

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

四.人脸识别示例代码

下面给出一个完整的示例代码,代码中的GetTickCount可以参阅《Windows 各种计时函数总结》,cvEqualizeHist可以参阅《【OpenCV入门指南】第八篇灰度直方图》。

// FaceDetect.cpp : 定义控制台应用程序的入口点。
// 本文配套博客文章地址: http://blog.csdn.net/morewindows/article/details/8426318  

#include "stdafx.h"#include <iostream>
#include <opencv2/core/core.hpp>   //cvGetSize  cvCreateImage
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>  //cvResize cvInitMatHeader cvGetMinMaxHistValue cvCvtColor
#include <opencv2/imgproc/imgproc.hpp>#include <Windows.h>   //DWORD  GetTickCount()

#ifdef _DEBUG
#pragma comment(lib, "opencv_core244d")
#pragma comment(lib, "opencv_highgui244d")
#pragma comment(lib, "opencv_imgproc244d")  //cvResize 
#pragma comment(lib, "opencv_objdetect244d")  //cvHaarDetectObjects
#else
#pragma comment(lib, "opencv_core244")
#pragma comment(lib, "opencv_highgui244")
#pragma comment(lib, "opencv_imgproc244")  //cvResize
#pragma comment(lib, "opencv_objdetect244") //cvHaarDetectObjects
#endifusing namespace std;  
int main()  
{  // 加载Haar特征检测分类器  // haarcascade_frontalface_alt.xml系OpenCV自带的分类器 下面是我机器上的文件路径  const char *pstrCascadeFileName = "G:\\Software\\openCV\\opencv\\data\\haarcascades\\haarcascade_frontalface_alt.xml";  CvHaarClassifierCascade *pHaarCascade = NULL;  pHaarCascade = (CvHaarClassifierCascade*)cvLoad(pstrCascadeFileName);  // 载入图像  const char *pstrImageName = "./images/linzhiling.jpg";  //const char *pstrImageName = "./images/liuyifei.jpg";  //const char *pstrImageName = "./images/unknown.jpg";  IplImage *pSrcImage = cvLoadImage(pstrImageName, CV_LOAD_IMAGE_UNCHANGED);  IplImage *pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);  cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);  // 人脸识别与标记  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对象,该对象包含一系列CvRect表示检测到的人脸矩形//第一个参数表示输入图像,尽量使用灰度图以加快检测速度//第二个参数表示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 *pcvSeqFaces = cvHaarDetectObjects(pGrayImage, pHaarCascade, pcvMStorage);  dwTimeEnd = GetTickCount();  printf("人脸个数: %d   识别用时: %d ms\n", pcvSeqFaces->total, dwTimeEnd - dwTimeBegin);  // 标记  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); //用矩形画出脸部部分/*CvPoint startPoint,endPoint;startPoint.x = cvRound(r->x);startPoint.y = cvRound(r->y);endPoint.x = cvRound(r->x + r->width);endPoint.y = cvRound(r->x + r->height);cvRectangle(pSrcImage,startPoint,endPoint,FaceCirclecolors[i % 8]);*/}  cvReleaseMemStorage(&pcvMStorage);  }  const char *pstrWindowsTitle = "人脸识别";  cvNamedWindow(pstrWindowsTitle, CV_WINDOW_AUTOSIZE);  cvShowImage(pstrWindowsTitle, pSrcImage);  cvWaitKey(0);  cvDestroyWindow(pstrWindowsTitle);  cvReleaseImage(&pSrcImage);   cvReleaseImage(&pGrayImage);  return 0;  
}
View Code

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

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

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

 

运行结果二:

 

运行结果三(多人):

 

本文转自:http://blog.csdn.net/morewindows/article/details/8426318

转载于:https://www.cnblogs.com/tianyalu/p/5689285.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372629.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

matlab提取艾里斑,艾里斑:我不是雀斑

正是艾里斑&#xff0c;限制了光学仪器的精度我们知道凸透镜能把入射光会聚到它的焦点上&#xff0c;由于透镜的口径有一定大小&#xff0c;限制了光线的传播&#xff0c;所以凸透镜也会发生衍射。这导致透镜无法把光线会聚成无限小的点&#xff0c;而只会在焦点上形成具有一定…

mysql启动错误排查-无法申请足够内存

一般情况下mysql的启动错误还是很容易排查的&#xff0c;但是今天我们就来说一下不一般的情况。拿到一台服务器&#xff0c;安装完mysql后进行启动&#xff0c;启动错误如下&#xff1a; 有同学会说&#xff0c;哥们儿你是不是buffer pool设置太大了&#xff0c;设置了96G内存。…

Spring vs Guice:重要的一个关键区别

根据弹簧对象的名称识别它们 不管使用XML还是Java配置都没有关系&#xff0c;Spring范围大致类似于Map <String&#xff0c;Object>结构。 这意味着您不能有两个名称相同的对象 。 为什么这是一件坏事&#xff1f; 如果您的大型应用程序包含许多Configuration类或XML文件…

php 批量更新死锁,php – 在尝试获取锁定时,哪个查询导致死锁;尝试重新启动事务...

我无法弄清楚哪个Query在尝试获取锁定时导致死锁;尝试重新启动事务.我的mysql包装器有以下几行if (mysql_errno($this->conn) 1213) {$this->bug_log(0,"Deadlock. SQL:".$this->sql);}bug_log写入文件的位置.错误日志文件没有死锁错误,但/var/log/mysqld.…

Task和BackTask

一、总结性知识点&#xff1a; 1、Android应用运行时会创建任务Task&#xff0c;用于存放主窗口2、每一个任务包含一个堆栈数据结构&#xff0c;用于保存当前应用已创建的窗口对象&#xff0c;这个堆栈即回退栈BackStack3&#xff64; 位于回退栈顶的窗口会处于焦点状态4&#…

Java面试题二

1、public、private、protected、Friendly的区别与作用域 public,protected,friendly,private的访问权限如下&#xff1a; 关键字 当前类 包内 子孙类 包外 public √ √ √ √ protected…

使用Spring Roo进行快速云开发–第1部分:Google App Engine(GAE)

Spring Roo是在Java平台上提供快速应用程序开发的工具。 我已经解释了何时使用它&#xff1a; http : //www.kai-waehner.de/blog/2011/04/05/when-to-use-spring-roo 。 Spring Roo目前支持两种针对云计算的解决方案&#xff1a;Google App Engine&#xff08;GAE&#xff09;…

mysql 重装,Windows系统中完全卸载MySQL数据库实现重装mysql

一、在控制面板&#xff0c;卸载MySQL的所有组件控制面板——》所有控制面板项——》程序和功能&#xff0c;卸载所有和MySQL有关的程序二、找到你的MysQL安装路径&#xff0c;看还有没有和MySQL有关的文件夹&#xff0c;全删如果安装在C盘&#xff0c;检查一下C:\Program File…

loadrunner 关联

1、记住关联的位置&#xff08;之前&#xff09;&#xff0c;因为登录之前需要token&#xff0c;才能验证登录是否成功&#xff0c;所以&#xff0c;放在登录之前 转载于:https://www.cnblogs.com/zyp1/p/5692343.html

网页上线后音频不能自动播放

一、问题描述 开发环境谷歌浏览器本地测试通过&#xff0c;网站上线后的音乐不播放&#xff0c;而是自动下载&#xff1f; 开发环境safari浏览器中&#xff0c;音频不播放。 二、问题分析 用audio或者embed标签都有问题&#xff0c;为了节省用户的流量&#xff0c;安卓和ios都默…

Akka STM –与STM Ref和Agent进行乒乓球比赛

乒乓是一个经典示例&#xff0c;其中2个玩家&#xff08;或线程&#xff09;访问共享资源–乒乓球桌并在彼此之间传递Ball&#xff08;状态变量&#xff09;。 使用任何共享资源&#xff0c;除非我们同步访问&#xff0c;否则线程可能会遇到潜在的死锁情况。 PingPong算法非常简…

c mysql二进制,MySQL运用connector C/C+读取二进制字段

MySQL使用connector C/C读取二进制字段MySQL使用connector C/C读取二进制字段&#xff0c;两种方法&#xff1a;用getStringvector vec;while (pResultSet->next()){string str pResultSet->getString("data");vec.insert(vec.end(), str.begin(), str.end())…

在下一个项目中不使用JavaDoc的5大原因

JavaDoc对于框架和库的开发是绝对必要的&#xff0c;这些框架和库为其他框架&#xff08;例如Spring Framework&#xff0c;JDK&#xff09;提供了公共接口。 对于内部企业软件和/或产品开发&#xff0c;我有以下原因会在将来忽略“ 100&#xff05;JavaDoc策略”。 1&#xff…

NPOI操作Excel辅助类

/// <summary> /// NPOI操作excel辅助类 /// </summary> public static class NPOIHelper {#region 定义与初始化public static HSSFWorkbook workbook;[Flags]public enum LinkType{网址,档案,邮件,内容};private static void InitializeWorkbook(){if (workbook …

JSP九大内置对象,七大动作,三大指令

JSP之九大内置对象 隐藏对象入门探索 Servlet 和JSP中输出数据都需要使用out对象。Servlet 中的out对象是通过getWriter()方法获取的。而JSP中没有定义out对象却可以直接使用。这是因为out是JSO的内置隐藏对象。JSP中的常见的9个内置隐藏对象如下 out输出流对象 隐藏对象out是…

matlab变步长的梯形公式,用变步长梯形法计算积分∫sinx/x*x的近似值(二分二次即可)...

共回答了20个问题采纳率&#xff1a;90%题目没写全吧?现假定积分区间为[0,1],教材《数值分析》(华中科技大学出版)第87页,例题4.2就有详细的解答.貌似题目也有错?确定分母是【x^2】?现在附上该例题(分母是x)的全部解答过程&#xff1a;先对整个区间[0,1]使用梯形公式.对于函…

使用Cloud SQL的Google App Engine全文搜索

许多Google AppEngine开发人员一直在等待全文搜索功能&#xff0c;特别是来自网络上最大的搜索引擎Google。 很高兴看到Google团队正在努力&#xff0c;您可以在Google I / O 2011大会上签到&#xff1a; Bo Majewski和Ged Ellis进行的全文本搜索 。 据我所知&#xff0c;非常有…

php 数组值sum,php sum数组值(如果特定列的值重复)

我有一个阵列。我要检查是否有重复的费用,如果有,我要用相同的费用列汇总所有值。[12] > Array([type] > Other Miscellaneous Fees[fee] > 158[amount] > -22.56[code] > COL_AUDIO[feedesc] > COLLEGE AUDIO VISUAL FEE)[13] > Array([type] > Other…

hdu-5734 Acperience(数学)

题目链接&#xff1a; Acperience Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem DescriptionDeep neural networks (DNN) have shown significant improvements in several application domains including computer vision and…

Ninject依赖注入(一)

Ninject学习笔记&#xff08;一&#xff09; Ninject学习笔记&#xff08;一&#xff09;理解依赖注入DI概念什么是DI&#xff1f;DI是如何工作的&#xff1f;什么是DI容器使用Ninject如何使用NinjectNinject对象生命周期暂时范围单例范围线程范围请求范围自定义范围Ninject模块…