使用机器学习的方法进行人脸检测的第一步需要训练人脸分类器,这是一个耗时耗力的过程,需要收集大量的正负样本,并且样本质量的好坏对结果影响巨大,如果样本没有处理好,再优秀的机器学习分类算法都是零。

今年3月23日,微软公司在推特(Twitter)社交平台上推出了一个基于机器学习的智能聊天机器人Tay,Tay被设定为一个年龄为十几岁的女孩,主要目标受众是18岁至24岁的青少年。人们只需要@一下Tay,Tay就会追踪该用户的网名、性别、喜欢的食物、邮编、感情状况等个人信息。除了聊天,Tay还可以说笑话,讲故事等,让人感觉这就是一个知道你很多小秘密,嘴甜心暖的“小闺蜜”。Tay会在与人们的交流中不断学习,随着时间积累,她的理解能力将逐步提升,变得愈发“智能”。

然而比较戏剧性的是在Tay推出24小时不到,这个人工智能机器人就被人类彻底“教坏”,成为一个集反犹太人、性别歧视、种族歧视于一身的“不良少女”。逼得微软不得不让Tay暂时“下岗”。

微软在一项声明中表示,“人工智能机器人Tay属于机器学习项目,设计它的目的就是让它与人类进行互动。在学习的过程中,它把人类的好坏言论都学了。因此,它发表了一些不恰当的言论。我们正在纠偏,对Tay进行调整。”

微软的机器学习算法不可谓不先进,但是为什么会出现这种情况呢,比较合理的解释就是Tay是被人们输入的“不良”样本带坏的。

一个好消息是,OpenCV安装包里自带有已经训练好的人脸分类器“haarcascade_frontalface_alt.xml”,位置在“XX\opencv\sources\data\haarcascades”里,我们可以直接拿来使用,检测效果还可以接受。这个文件夹下还有其他一些分类器,像左右眼、上身、笑脸检测等等。

下边就使用OpenCV自带的基于Haar特征的级联分类器实现人脸检测,使用的版本是VS2012+OpenCV2.4.10,本来我的机器上安装的是OpenCV2.4.13版本,但是发现13版本的加载分类器的函数cvLoad总是报错,换成10版本就没问题了(包括之前在训练决策树的时候,也发现2.4.13版本的训练结果总是不对)。

程序涉及到Mat和IplImage指针的一个转换,还有一个比较关键的函数cvHaarDetectObjects,函数原型是:

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)));
  • 第一个参数image,表示待检测图像;
  • 第二个参数cascade,表示Haar特征分类器,需要使用cvLoad()加载Haar特征分类器XML文件;
  • 第三个参数为storage,是申请的一块内存空间,用于管理所使用的内存。
  • 第四个参数scale_factor,表示下一次对图像的扫描中,搜索窗口增长的比例系数,即下次搜索窗口扩大的比例,有其默认值1.1。
  • 第五个参数min_neighbors,从其命名上就可以看出来,表示构成检测目标的相邻矩形的最小个数,如果在检测目标位置的“邻居”位置上,检测到的潜在的人脸目标小于设定值,则不认为是人脸区域,所有调节这个参数可以对人脸的检测个数特别是目标的鲁棒性产生影响。值越小,检测到的人脸区域越多,同时意味着可能有误检和重复区域。
  • 第六个参数CV_DEFAULT,不甚理解,使用默认值吧。
  • 第七个参数min_size和第八个参数max_size表示检测窗口的最小值和最大值,程序一般会根据图像大小自动设置。

#include <opencv2/opencv.hpp>
#include "highgui/highgui.hpp"
#include <Windows.h> using namespace std;
using namespace cv; int main()
{
// 加载Haar特征检测分类器
const char *pstrCascadeFileName = "D:\\ProgramFilesD\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml";
CvHaarClassifierCascade *pHaarCascade = NULL;
pHaarCascade = (CvHaarClassifierCascade*)cvLoad(pstrCascadeFileName); // 载入图像并转换为灰度图像
const char *pstrImageName = "E:\\Picture\\Face03.jpg";
Mat image=imread(pstrImageName);
Mat imageGray;
cvtColor(image,imageGray,CV_RGB2GRAY); // 人脸识别与标记
if (pHaarCascade != NULL)
{
MemStorage mStorage=cvCreateMemStorage(0);
cvClearMemStorage(mStorage); // 识别
DWORD dwTimeBegin, dwTimeEnd;
dwTimeBegin = GetTickCount(); //Mat转换为IplImage
IplImage IimageGray(imageGray);
CvSeq *pcvSeqFaces = cvHaarDetectObjects(&IimageGray, pHaarCascade, mStorage);
dwTimeEnd = GetTickCount();
cout<<"检测到的人脸总数:\n"<<pcvSeqFaces->total<<endl<<endl;
cout<<"检测耗时:\n"<<dwTimeEnd-dwTimeBegin<<endl;
// 用矩形框标记
for(int i = 0; i <pcvSeqFaces->total; i++)
{
CvRect* r = (CvRect*)cvGetSeqElem(pcvSeqFaces, i);
Point2f p1=Point2f(r->x,r->y); //矩形左上角点位
Point2f p2=Point2f(r->x+r->height,r->y+r->width); //矩形右下角点位
rectangle(image,p1,p2,Scalar(255,0,0),2); //矩形框标注人脸位置
}
}
namedWindow("人脸检测",0);
imshow("人脸检测", image);
waitKey(0);
return 0;
}

标准脸:

艺术照:

多人合照:

这个是专门针对正面人脸的,检测效果还可以,有时候会有误检,通过调整参数一般可以消除掉。

OpenCV中基于Haar特征和级联分类器的人脸检测的更多相关文章

  1. 使用Harr特征的级联分类器实现目标检测

    前言  最近在学习人脸的目标检测任务时,用了Haar人脸检测算法,这个算法实现起来太简洁了,读入个.xml,调用函数就能用.但是深入了解我发现这个算法原理很复杂,也很优秀.究其根源,于是我找了好些篇相 ...

  2. 基于MATLAB的adaboost级联形式的人脸检测实现

    很早之前就做过一些关于人脸检测和目标检测的课题,一直都没有好好总结出来,趁着这个机会,写个总结,希望所写的内容能给研究同类问题的博友一些见解和启发!!博客里面涉及的公式太繁琐了,直接截图了. 转载请注 ...

  3. OpenCV中基于HOG特征的行人检测

    目前基于机器学习方法的行人检测的主流特征描述子之一是HOG(Histogram of Oriented Gradient, 方向梯度直方图).HOG特征是用于目标检测的特征描述子,它通过计算和统计图像 ...

  4. OpenCV学习记录(二):自己训练haar特征的adaboost分类器进行人脸识别 标签: 脸部识别opencv 2017-07-03 21:38 26人阅读

    上一篇文章中介绍了如何使用OpenCV自带的haar分类器进行人脸识别(点我打开). 这次我试着自己去训练一个haar分类器,前后花了两天,最后总算是训练完了.不过效果并不是特别理想,由于我是在自己的 ...

  5. OpenCV使用级联分类器实现人脸检测

    一.概述 案例:使用opencv级联分类器CascadeClassifier+其提供的特征数据实现人脸检测,检测到人脸后使用红框画出来. API介绍:detectMultiScale( InputAr ...

  6. 使用级联分类器实现人脸检测(OpenCV自带的数据)

    #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace st ...

  7. OpenCV开发笔记(五十五):红胖子8分钟带你深入了解Haar、LBP特征以及级联分类器识别过程(图文并茂+浅显易懂+程序源码)

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  8. 【macOS】 在OpenCV下训练Haar特征分类器

    本教程基于以下环境 macOS 10.12.6,OpenCV 3.3.0,python 3.6.由于网上基于masOS系统的教程太少,想出一篇相关教程造福大家-本文旨在学习如何在opencv中基于ha ...

  9. 基于Haar特征的Adaboost级联人脸检测分类器

    基于Haar特征的Adaboost级联人脸检测分类器基于Haar特征的Adaboost级联人脸检测分类器,简称haar分类器.通过这个算法的名字,我们可以看到这个算法其实包含了几个关键点:Haar特征 ...

随机推荐

  1. android闹钟实现原理

    闹钟的原理可用下面我自己画的一幅图来概括:(不对的地方,尽管吐槽) 我们来看看新建闹钟到闹钟响铃的步骤:    1.新建一个闹钟: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...

  2. DMA 如何查看它有没有传输完成 传输完成再开启

    摘自:https://blog.csdn.net/zzwdkxx/article/details/9026173 /////////////////////////////////////////// ...

  3. jquery如何实现点击标题收缩下面的内容

    jquery如何实现点击标题收缩下面的内容 一.总结 一句话总结:怎么做复杂前端任务,先把样式(最简单)做出来,然后在写js. 1.如何取jquery集合中的某个索引号的元素? 不是get(),是eq ...

  4. html 页面 黑白

    css代码,写在最顶端 html {filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);-webkit-filter: ...

  5. 打开cad文件的几种方法

    转自原文 打开cad文件的几种方法 IWorkspaceFactory pWorkspaceFactory; IFeatureWorkspace pFeatureWorkspace; IFeature ...

  6. POJ2112 Optimal Milking 【最大流+二分】

    Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12482   Accepted: 4508 ...

  7. RandomStringUtils RandomUtils

    上一篇是StringUtils 链接http://www.cnblogs.com/tele-share/p/8060129.html 1.RandomStringUtils 1.1模拟实现random ...

  8. php实现 合并表记录(需求是最好的老师)

    php实现 合并表记录(需求是最好的老师) 一.总结 一句话总结:php数组,桶. 1.fgets的作用? 读取一行 0 1 2.如何读取一行中的两个数? fgets()读取一行后explode以空格 ...

  9. html5-3 html5标签(热点地图如何实现)(边学边做)

    html5-3 html5标签(热点地图如何实现)(边学边做) 一.总结 一句话总结:热点地图用绝对定位实现. 1.自定义列表怎么弄? dl  自定义列表dt  自定义标题dd  自定义列表内容 2. ...

  10. 【b803】传纸条

    Time Limit: 1 second Memory Limit: 50 MB [问题描述] 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行 ...