[补充] 这是我时隔差不多两年后, 回来编辑这篇文章加的这段补充, 说实话看到这么多评论很是惊讶, 有很多评论不是我不想回复, 真的是时间久了, 很多细节我都忘记了, 无力回复, 非常抱歉. 我本人并非做CV的, 这两年也都没有再接触CV, 作为一个本科毕业的苦逼码工, 很多理论基础都不扎实, 回顾这篇文章的时候, 我知道其实有很多地方都是写的模棱两可, 加这个补充, 也是希望看这篇文章同学要带着批判的眼光来看, 要想透彻的理解算法, 一是要看透算法原作者的论文, 二是要读懂相关的优秀源码实现. 只看这篇文章是不可能有透彻理解的, 我也深知, 很可能会有一些误导在里面, 欢迎大家的批评. 再次感谢热心回复的同学, 再次对我没能帮上忙表示抱歉, 希望大家走的更高更远, 做研究要严谨和勤奋, 在获得一定感性认识的基础上一定要深究细节原理, 不要为了论文而论文. (这个博客我可能也不会在维护了, 我现在成了一个刷题党= =.)
由于工作需要,我开始研究人脸检测部分的算法,这期间断断续续地学习Haar分类器的训练以及检测过程,在这里根据各种论文、网络资源的查阅和对代码的理解做一个简单的总结。我试图概括性的给出算法的起源、全貌以及细节的来龙去脉,但是水平有限,只能解其大概,希望对初学者起到帮助,更主要的是对我个人学习的一次提炼。
一、Haar分类器的前世今生
人脸检测属于计算机视觉的范畴,早期人们的主要研究方向是人脸识别,即根据人脸来识别人物的身份,后来在复杂背景下的人脸检测需求越来越大,人脸检测也逐渐作为一个单独的研究方向发展起来。
目前的人脸检测方法主要有两大类:基于知识和基于统计。
“基于知识的方法主要利用先验知识将人脸看作器官特征的组合,根据眼睛、眉毛、嘴巴、鼻子等器官的特征以及相互之间的几何位置关系来检测人脸。基于统计的方法则将人脸看作一个整体的模式——二维像素矩阵,从统计的观点通过大量人脸图像样本构造人脸模式空间,根据相似度量来判断人脸是否存在。在这两种框架之下,发展了许多方法。目前随着各种方法的不断提出和应用条件的变化,将知识模型与统计模型相结合的综合系统将成为未来的研究趋势。”(来自论文《基于Adaboost的人脸检测方法及眼睛定位算法研究》)
基于知识的人脸检测方法
Ø 模板匹配
Ø 人脸特征
Ø 形状与边缘
Ø 纹理特性
Ø 颜色特征
基于统计的人脸检测方法
Ø 主成分分析与特征脸
Ø 神经网络方法
Ø 支持向量机
Ø 隐马尔可夫模型
Ø Adaboost算法
本文中介绍的Haar分类器方法,包含了Adaboost算法,稍候会对这一算法做详细介绍。所谓分类器,在这里就是指对人脸和非人脸进行分类的算法,在机器学习领域,很多算法都是对事物进行分类、聚类的过程。OpenCV中的ml模块提供了很多分类、聚类的算法。
注:聚类和分类的区别是什么?一般对已知物体类别总数的识别方式我们称之为分类,并且训练的数据是有标签的,比如已经明确指定了是人脸还是非人脸,这是一种有监督学习。也存在可以处理类别总数不确定的方法或者训练的数据是没有标签的,这就是聚类,不需要学习阶段中关于物体类别的信息,是一种无监督学习。
其中包括Mahalanobis距离、K均值、朴素贝叶斯分类器、决策树、Boosting、随机森林、Haar分类器、期望最大化、K近邻、神经网络、支持向量机。
我们要探讨的Haar分类器实际上是Boosting算法的一个应用,Haar分类器用到了Boosting算法中的AdaBoost算法,只是把AdaBoost算法训练出的强分类器进行了级联,并且在底层的特征提取中采用了高效率的矩形特征和积分图方法,这里涉及到的几个名词接下来会具体讨论。
虽说haar分类器采用了Boosting的算法,但在OpenCV中,Haar分类器与Boosting没有采用同一套底层数据结构,《Learning OpenCV》中有这样的解释:“Haar分类器,它建立了boost筛选式级联分类器。它与ML库中其他部分相比,有不同的格局,因为它是在早期开发的,并完全可用于人脸检测。”
是的,在2001年,Viola和Jones两位大牛发表了经典的《Rapid Object Detection using a Boosted Cascade of Simple Features》【1】和《Robust Real-Time Face Detection》【2】,在AdaBoost算法的基础上,使用Haar-like小波特征和积分图方法进行人脸检测,他俩不是最早使用提出小波特征的,但是他们设计了针对人脸检测更有效的特征,并对AdaBoost训练出的强分类器进行级联。这可以说是人脸检测史上里程碑式的一笔了,也因此当时提出的这个算法被称为Viola-Jones检测器。又过了一段时间,Rainer Lienhart和Jochen Maydt两位大牛将这个检测器进行了扩展【3】,最终形成了OpenCV现在的Haar分类器。之前我有个误区,以为AdaBoost算法就是Viola和Jones搞出来的,因为网上讲Haar分类器的地方都在大讲特讲AdaBoost,所以我错觉了,后来理清脉络,AdaBoost是Freund 和Schapire在1995年提出的算法,是对传统Boosting算法的一大提升。Boosting算法的核心思想,是将弱学习方法提升成强学习算法,也就是“三个臭皮匠顶一个诸葛亮”,它的理论基础来自于Kearns 和Valiant牛的相关证明【4】,在此不深究了。反正我是能多简略就多简略的把Haar分类器的前世今生说完鸟,得出的结论是,大牛们都是成对儿的。。。额,回到正题,Haar分类器 = Haar-like特征 + 积分图方法 + AdaBoost + 级联;
注:为何称其为Haar-like?这个名字是我从网上看来的,《Learning OpenCV》中文版提到Haar分类器使用到Haar特征,但这种说法不确切,应该称为类Haar特征,Haar-like就是类Haar特征的意思。
二、Haar分类器的浅入浅出
之所以是浅入浅出是因为,我暂时深入不能,只是根据其他人的总结,我加以梳理归纳,用自己的理解阐述出来,难免会有错误,欢迎指正。
Haar分类器算法的要点如下:
① 使用Haar-like特征做检测。
② 使用积分图(Integral Image)对Haar-like特征求值进行加速。
③ 使用AdaBoost算法训练区分人脸和非人脸的强分类器。
④ 使用筛选式级联把强分类器级联到一起,提高准确率。
2.1 Haar-like特征你是何方神圣?
一看到Haar-like特征这玩