(学习笔记二)——基于opencv人脸检测原理及实现

opencv 进阶10-人脸识别原理说明及示例-cv2.CascadeClassifier.detectMultiScale() 在 OpenCV 中,人脸检测使用的是 cv2.CascadeClassifier.detectMultiScale()函数,它可以检测出图片中所有的人脸。该函数由分类器对象调用,其语法格式为:image:待检测图像,通常为灰度图像。scaleFactor:表示在前后两次相继的扫描中,搜索窗口的缩放比例。minNeighbors:表示构成检测目标的相邻矩形的最小个数。默认情况下,该值为 3,意味着有 3 个以上的检测标记存在时,才认为人脸存在。 阅读详情

最近搞了几天的人脸检测,终于把大体框架和原理搞清楚了,现在写出来供大家学习之用,如有不对之处,还请大家指正。也希望大家在学习opencv的过程中能将学习过程及重点记录下来,以博客的形式分析,毕竟opencv的教材还不太多,我们自己学习大部分要靠网上的资料。通过博客分享的形式能使大家快速进步,同时也算是对自己学习的一个记录和总结。只是一个倡议,大家自己决定,呵呵。
好了进入正题。
学习基于opencv的人脸检测,首先要理清大概需要做哪些事情。这里总共分两步,第一步就是训练分类器,第二步就是利用训练好的分类器进行人脸检测。
1、训练分类器
训练分类器我没有学习,因为opencv的源代码中(opencv安装目录\data\haarcascades)中已经有了很多训练好的分类器供我们使用。但是有必要对分类器的训练原理和过程做一些介绍,以便后面进一步的学习中能够对这部分有一定了解。
目前人脸检测分类器大都是基于haar特征利用Adaboost学习算法训练的。

目标检测方法最初由Paul Viola [Viola01]提出,并由Rainer Lienhart [Lienhart02]对这一方法进行了改善. 首先,利用样本(大约几百幅样本图片)的 harr 特征进行分类器训练,得到一个级联的boosted分类器。训练样本分为正例样本和反例样本,其中正例样本是指待检目标样本(例如人脸或汽车等),反例样本指其它任意图片,所有的样本图片都被归一化为同样的尺寸大小(例如,20x20)。

分类器训练完以后,就可以应用于输入图像中的感兴趣区域(与训练样本相同的尺寸)的检测。检测到目标区域(汽车或人脸)分类器输出为1,否则输出为0。为了检测整副图像,可以在图像中移动搜索窗口,检测每一个位置来确定可能的目标。 为了搜索不同大小的目标物体,分类器被设计为可以进行尺寸改变,这样比改变待检图像的尺寸大小更为有效。所以,为了在图像中检测未知大小的目标物体,扫描程序通常需要用不同比例大小的搜索窗口对图片进行几次扫描。

分类器中的“级联”是指最终的分类器是由几个简单分类器级联组成。在图像检测中,被检窗口依次通过每一级分类器, 这样在前面几层的检测中大部分的候选区域就被排除了,全部通过每一级分类器检测的区域即为目标区域。 目前支持这种分类器的boosting技术有四种: Discrete Adaboost, Real Adaboost, Gentle Adaboost and Logitboost。"boosted" 即指级联分类器的每一层都可以从中选取一个boosting算法(权重投票),并利用基础分类器的自我训练得到。基础分类器是至少有两个叶结点的决策树分类器。 Haar特征是基础分类器的输入,主要描述如下。目前的算法主要利用下面的Harr特征。

Image:Haarfeatures.png

每个特定分类器所使用的特征用形状、感兴趣区域中的位置以及比例系数(这里的比例系数跟检测时候采用的比例系数是不一样的,尽管最后会取两个系数的乘积值)来定义。例如在第二行特征(2c)的情况下,响应计算为复盖全部特征整个矩形框(包括两个白色矩形框和一个黑色矩形框)象素的和减去黑色矩形框内象素和的三倍 。每个矩形框内的象素和都可以通过积分图象很快的计算出来。

通过上述陈述,应该对整个训练过程有个大概的了解,但是对于训练的具体过程还是不太明晰,那么可以继续参考下面的文章:
http://apps.hi.baidu.com/share/detail/44451430
相信看过上面这篇文章以及前面的陈述后大家应该对分类器的训练原理有了一个整体的了解,至于一些细节如果还不清晰应该不影响使用,毕竟那些细节可能需要数字图像处理的专业知识。

2、利用分类器进行检测
前面也已经说过,opencv的源代码中已经给我们提供了一些训练好的分类器,例如人脸检测分类器,人体检测分类器等。那么如果没有什么特定的需要,我们完全可以利用这些分类器直接进行人脸及人体检测。

对于分类器的使用大致要经过三个阶段,从文件中加载分类器、利用分类器进行检测、检测完成后释放分类器。这三个阶段对应三个函数,cvLoadHaarClassifierCascade、cvHaarDetectObjects、cvReleaseHaarClassifierCascade。这三个函数包含在库文件opencv_objdetect231d.lib中,为了使用,需要在(以vs2008为例)项目-属性-配置属性-链接器-输入,附加依赖项中添加相应的库文件,即opencv_objdetect231d.lib。三个函数原型及参数意义如下:
a、CvHaarClassifierCascade* cvLoadHaarClassifierCascade(const char* directory,cvSize orig_window_size);
directory
训练好的分类器路径
orig_window_size
级联分类器训练中采用的检测目标的尺寸。这个信息在分类器中没有存储,因此要单独指出。
函数 cvLoadHaarClassifierCascade 用于从文件中装载训练好的利用哈尔特征的级联分类器,或者从OpenCV中嵌入的分类器数据库中导入。分类器的训练可以应用函数haartraining(详细察看opencv/apps/haartraining) 这个数值是在训练分类器时就确定好的,修改它并不能改变检测的范围或精度。
需要注意的是,这个函数已经过时了。现在的目标检测分类器通常存储在 XML 或 YAML 文件中,而不是通过路径导入。从文件中导入分类器,可以使用函数 cvLoad 。
b、CvSeq* cvHaarDetectObjects(const CvArr* image, CvHaarClassifierCascade* cascade,CvMemStorage* storage,double scale_factor=1.1,int min_neighbors=3,int flags=0,CvSize min_size=cvSize(0,0));
image
被检图像
cascade
harr 分类器级联的内部标识形式
storage 用来存储检测到的一序列候选目标矩形框的内存区域。 scale_factor
在前后两次相继的扫描中,搜索窗口的比例系数。例如1.1指将搜索窗口依次扩大10%。
min_neighbors
构成检测目标的相邻矩形的最小个数(缺省-1)。如果组成检测目标的小矩形的个数和小于min_neighbors-1 都会被排除。如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框,这种设定值一般用在用户自定义对检测结果的组合程序上。
flags
操作方式。当前唯一可以定义的操作方式是 CV_HAAR_DO_CANNY_PRUNING。如果被设定,函数利用Canny边缘检测器来排除一些边缘很少或者很多的图像区域,因为这样的区域一般不含被检目标。人脸检测中通过设定阈值使用了这种方法,并因此提高了检测速度。
min_size
检测窗口的最小尺寸。缺省的情况下被设为分类器训练时采用的样本尺寸(人脸检测中缺省大小是~20×20)。

函数 cvHaarDetectObjects 使用针对某目标物体训练的级联分类器在图像中找到包含目标物体的矩形区域,并且将这些区域作为一序列的矩形框返回。函数以不同比例大小的扫描窗口对图像进行几次搜索(察看cvSetImagesForHaarClassifierCascade)。 每次都要对图像中的这些重叠区域利用cvRunHaarClassifierCascade进行检测。 有时候也会利用某些继承(heuristics)技术以减少分析的候选区域,例如利用 Canny 裁减 (prunning)方法。 函数在处理和收集到候选的方框(全部通过级联分类器各层的区域)之后,接着对这些区域进行组合并且返回一系列各个足够大的组合中的平均矩形。调节程序中的缺省参数(scale_factor=1.1, min_neighbors=3, flags=0)用于对目标进行更精确同时也是耗时较长的进一步检测。为了能对视频图像进行更快的实时检测,参数设置通常是:scale_factor=1.2, min_neighbors=2, flags=CV_HAAR_DO_CANNY_PRUNING, min_size=<minimum possible face size> (例如, 对于视频会议的图像区域)。
c、void cvReleaseHaarClassifierCascade(CvHaarClassifierCascade** cascade);
cascade
双指针类型指针指向要释放的cascade. 指针由函数声明。
函数 cvReleaseHaarClassifierCascade 释放cascade的动态内存,其中cascade的动态内存或者是手工创建,或者通过函数 cvLoadHaarClassifierCascade 或 cvLoad分配。
三个主要函数介绍完之后,就可以看程序了,毕竟通过程序学函数和用法是最快的(个人觉得)。

#include "cv.h"
#include "highgui.h"
#include <stdio.h>

void displaydetection(IplImage* pInpImg,CvSeq* pFaceRectSeq,char* FileName);

int main(int argc,char** argv)
{
	IplImage* pInpImg=0;
	CvHaarClassifierCascade* pCascade=0;		//指向后面从文件中获取的分类器
	CvMemStorage* pStorage=0;					//存储检测到的人脸数据
	CvSeq* pFaceRectSeq;						//用来接收检测函数返回的一系列的包含人脸的矩形区域
	
	if (argc<2)
	{
		printf("missing name of image file!\n");
		return -1;
	}

	//初始化
	pInpImg=cvLoadImage(argv[1],1);	
	pStorage=cvCreateMemStorage(0);				//创建默认大先64k的动态内存区域
	pCascade=(CvHaarClassifierCascade*)cvLoad("haarcascade_frontalface_alt.xml");		//加载分类器

	if (!pInpImg||!pStorage||!pCascade)
	{
		printf("initialization failed:%s\n",(!pInpImg)?"can't load image file":(!pCascade)?"can't load haar-cascade---make sure path is correct":"unable to allocate memory for data storage",argv[1]);
		return -1;
	}
	//人脸检测
	pFaceRectSeq=cvHaarDetectObjects(pInpImg,pCascade,pStorage,
		1.2,2,CV_HAAR_DO_CANNY_PRUNING,cvSize(40,40));
	//将检测到的人脸以矩形框标出。
	displaydetection(pInpImg,pFaceRectSeq,argv[1]);

	cvReleaseImage(&pInpImg);
	cvReleaseHaarClassifierCascade(&pCascade);
	cvReleaseMemStorage(&pStorage);
	return 0;
}

void displaydetection(IplImage* pInpImg,CvSeq* pFaceRectSeq,char* FileName)
{
	int i;
	cvNamedWindow("haar window",1);
	printf("the number of face is %d",pFaceRectSeq->total);
	for (i=0;i<(pFaceRectSeq?pFaceRectSeq->total:0);i++)
	{
		CvRect* r=(CvRect*)cvGetSeqElem(pFaceRectSeq,i);
		CvPoint pt1={r->x,r->y};
		CvPoint pt2={r->x+r->width,r->y+r->height};

//		cvSetImageROI(pInpImg,*r);
//		IplImage* dst=cvCreateImage(cvSize(92,112),pInpImg->depth,pInpImg->nChannels);
//		cvResize(pInpImg,dst,CV_INTER_LINEAR);
//		cvSaveImage("lian.jpg",dst);
		cvRectangle(pInpImg,pt1,pt2,CV_RGB(0,255,0),3,4,0);
	}
	cvShowImage("haar window",pInpImg);
//	cvResetImageROI(pInpImg);
	cvWaitKey(0);
	cvDestroyWindow("haar window");
}
通过上面的程序可以实现在一张图片中检测出人脸,并用矩形框标出。到此就完成了人脸检测。下一篇文章将对人脸识别进行介绍。
参考:

http://www.opencv.org.cn/index.php/Cv%E6%A8%A1%E5%BC%8F%E8%AF%86%E5%88%AB



OpenCV中的人脸关键点检测和人脸特征提取如何实现? 在OpenCV中,人脸关键点检测和人脸特征提取是常见的计算机视觉任务。OpenCV提供了一些用于实现这些任务的函数和算法。下面将介绍如何在OpenCV中实现人脸关键点检测和人脸特征提取。 阅读详情

相关推荐

Python及bs4、lxml、numpy模块包的安装

Python及bs4、lxml、numpy模块包的安装Python 的安装:python的安装比较简单,直接在官网下载相应版本,然后双击安装 注意:下载时勾选安装pip和添加到PATH路径安装 pip:Python2.7.9 和3.4以上的版本默认安装了pip,但是需要upgrading才能使用:在cmd 命令行,cd 转到对应python的安装目录,输入命令:python -m pip inst

tiantiancsdn的博客 8591

[Python从零到壹] 七十六.图像识别及经典案例篇之OpenCV快速实现人脸检测及视频人脸动态识别

前文介绍了车牌检测及区域识别,通过融合车牌颜色更精准识别汽车的车牌,并分割对应的车牌字母或数字。这篇文章将详细讲解人脸检测的应用案例,通过OpenCV快速实现人脸检测,涉及图像、视频、摄像头。本文提供的案例将为读者提供深入的理解,也是最简单的人脸识别案例,希望您喜欢。

杨秀璋的专栏 614

Python从0到50(二十二):xpath和lxml模块的讲解与应用

xpath和lxml模块的讲解与应用

712

一文带你了解人脸检测算法的类型及其工作原理

在过去的几年里,人脸识别受到了广泛的关注,被认为是图像分析领域最有前途的应用之一。人脸检测可以考虑人脸识别操作的很大一部分。根据其强度将计算资源集中在持有人脸的图像部分。图片中的人脸检测方法很复杂,因为人脸存在可变性,例如姿势、表情、位置和方向、肤色、眼镜或面部毛发的存在、相机增益的差异、照明条件和图像分辨率。 物体检测是计算机技术中的一种,它与图像处理和计算机视觉相联系,它与人脸、建筑物、树木、汽车等物体的检测实例相互作用。人脸检测算法的主要目的是确定图像中是否有任何人脸。 近年来,在人脸识别

TSINGSEE青犀视频官方技术博客 8156

Python爬虫使用lxml模块爬取豆瓣读书排行榜并分析

上次使用了BeautifulSoup库爬取电影排行榜,爬取相对来说有点麻烦,爬取的速度也较慢。本次使用的lxml库,我个人是最喜欢的,爬取的语法很简单,爬取速度也快。 本次爬取的豆瓣书籍排行榜的首页地址是: https://www.douban.com/doulist/1264675/?start=0&sort=time&playable=0&sub_type= 该排...

1704

python爬虫之数据解析(二):XPath语法和lxml模块

XPath语法和lxml模块 什么是XPath? xpath(XML Path Language)是一门在XML和HTML文档中查找信息的语言,可用来在XML和HTML文档中对元素和属性进行遍历。 XPath开发工具 Chrome插件XPath Helper。 安装方法: 打开插件伴侣,选择插件 选择提取插件内容到桌面,桌面上会多一个文件夹 把文件夹放入想要放的路径下 打开谷歌浏览器,选择扩展程序,开发者模式打开,选择加载已解压的扩展程序,选择路径打开即可 Firefox插件Try XPath。 XPa

小王@Note的博客 555

CV学习:传统(机器学习)图像识别(分类)

本文代码全部可运行,笔者运行环境:python3.7+pycharm+opencv4.6。此文是学习记录,记录实现图像识别所需知识,对各知识点并不做深入探究,但笔者提供了相关链接以便读者进行深入学习。 传统图像识别技术是指利用机器学习进行特征提取与图像分类。图像识别的过程包括信息获取、预处理、特征提取、图像分类。

m0_51485946的博客 1万+

使用lxml进行爬虫简介

一 爬虫技术简介 爬虫:一段自动抓取互联网信息的程序,从互联网上抓取对于我们有价值的信息。 **XML:**可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。 <?xml version="1.0" encoding="ISO-8859-1"?> <!-- Copyright w3school.com.cn --> <note&g...

技术空间 985

Python开发简单爬虫速成教程(MongoDB Navicat、requests模块、XPath基础和lxml模块、实战当当网5星图书排行榜数据抓取+数据存储到MongoDB数据库)

Python开发简单爬虫速成教程 **b站学习视频网址:**https://www.bilibili.com/video/BV1164y1m7Xb?p=1 一、简介 按照一定的规则,自动抓取网络信息的程序或者脚本,搜索引擎的重要组成。 搜索引擎 数据分析 人工智能 薅羊毛、抢车票 爬虫产品: 神箭手、八爪鱼、造数、后羿采集器 数据储备: python编程基础 http 数据库 怎么学: python语法知识 python爬虫常用到的几个重要内置库Requests,用于请求网页

joseph的博客 6994

Python爬虫-10-lxml匹配

lxml匹配 lxml 是python三方的结构匹配模块, lxml是python的一个解析库,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高 lxml匹配步骤 (1)导入模块: from lxml import etree (2)lxml在爬虫匹配当中具有相当固定的套路 ① 将爬虫获取到的HTML字符串转换为HTML结构图 ② xpath匹配获取数据 ...

karry_孙二的博客 1588

【python】爬虫基础——JSON、requests、BeautifulSoup、lxml、爬取静态网页

JSON是⼀种存储和交换数据的语法JSON仅仅是⽂本,它能够轻松地在服务器浏览器之间传输JSON的数据格式其实就是python里面的字典格式。

urge的博客 2705

Python ---------》 Python3.7配置Scrapy运行环境

最近学习了 Python 的第一个框架 Scrapy 。对于一个框架来说环境配置是很重要的。 所以本文特意来记录我自己在配置环境是出现的错误和解决办法。 参考至:https://blog.youkuaiyun.com/c406495762/article/details/60156205 1.直接使用指令pip3 install scrapy,发现有诸多错误。 Failed building wheel fo...

钢铁侠啊i的个人博客 1091

ubuntu环境下python爬虫项目需要的模块

端午假期逛了下ubuntukylin社区,发现里面的掌声不少。 所以我这个爱国爱党爱美眉的三好青年也装了最新版的ubuntukylin。 由于之前阿里云机器是centos,所以有些Python的模块还得重装下,以下是一些模块的安装和出现相关问题的解决方法(备注:大天朝的网络,所以建议还是翻翻墙) 脚本依赖的python模块与安装方法如下,验证方法import + module

语言浮云,数学王道 665

2.web爬虫,scrapy模块以及相关依赖模块安装

当前环境python3.5 ,windows10系统 Linux系统安装 在线安装,会自动安装scrapy模块以及相关依赖模块 pip install Scrapy 手动源码安装,比较麻烦要自己手动安装scrapy模块以及依赖模块 安装以下模块 1、lxml-3.8.0.tar.gz (XML处理库) 2、Twisted-17.5.0.tar.bz2 (用Python编写的异步网络框架) 3、S...

老K带你学Python 392

Python3安装lxml 4.4.0以上版本导入etree报错的解决

最近学习python爬虫,在分析网页时需要用到的lxml库的etree模块,本人用Python3.8.7,在安装了最新的4.8.0版本lxml后,from lxml import etree导入语句被pycharm标注红色错误,实验多次发现lxml 4.4.0及其以前的版本不存在这个问题,4.4.1以后的版本都有。于是网上一番搜索学习,最后终于大致弄清楚了原因,并初步解决了问题。 首先,并不是所谓的较新版本的lxml没有etree模块了。即使被pycharm标红,但其实程序是可以正常运行的,也可以得到正确

zhfak的博客 5690

Python通过Lxml库解析网络爬虫抓取到的html

Lxml是基于 libxml2解析库的Python封装。libxml2是使用C语言编写的,解析速度很好,不过安装起来稍微有点复杂。安装说明可以参考(http: //Lxml.de/installation.html),在CentOS7上中文安装说明(http://www.cjavapy.com/article/64/),使用lxml库来解析网络爬虫抓取到的HTML是一种非常高效的方式。

weixin_42098295的博客 2018

Python-lxml 与 XPath 实战

摘要: 本文详细介绍了Python的lxml解析库及其在HTML/XML文档解析中的应用。lxml基于XPath语法,具有高效、精准的特点,适合处理复杂网页数据。文章内容包括: 基础使用:安装lxml库,通过etree.HTML()解析文档,利用XPath提取数据(如文本、属性值)。 XPath语法:讲解路径表达式(/、//、@)、通配符、多路径匹配及内建函数(如contains()、text())。 实战案例:以豆瓣电影Top250为例,演示如何通过基准表达式定位列表项,再遍历提取详细信息(标题、评分、导

彭于晏长沙分晏 267

【Python爬虫实战】Python实现动态网页爬虫(requests模块)_python+def+get_pages+用法

Python爬虫实战,requests模块,Python实现动态网页爬虫让我们愉快地开始吧~① Python所有方向的学习路线图,清楚各个方向要学什么东西② 600多节Python课程视频,涵盖必备基础、爬虫和数据分析③ 100多个Python实战案例,含50个超大型项目详解,学习不再是只会理论④ 20款主流手游迫解 爬虫手游逆行迫解教程包⑤ 爬虫与反爬虫攻防教程包,含15个大型网站迫解⑥ 爬虫APP逆向实战教程包,含45项绝密技术详解。

2401_84590351的博客 1257
上一篇: PCA原理
下一篇: (学习笔记三)——人脸识别
longxiaoshi
博客等级 码龄15年 59粉丝 18原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值