https://mp.weixin.qq.com/s/a4aPycxfIe_qNIP_vrIZ5w
人脸可能出现在图像中的任何一个位置
人脸可能有不同的大小
人脸在图像中可能有不同的视角和姿态
人脸可能部分被遮挡
评价一个人脸检测算法好坏的指标是检测率和误报率。我们将检测率定义为:
算法要在检测率和误报率之间做平衡,理想的情况是有高检测率,低误报率。
经典的人脸检测算法流程是这样的:用大量的人脸和非人脸样本图像进行训练,得到一个解决2类分类问题的分类器,也称为人脸检测模板。这个分类器接受固定大小的输入图片,判断这个输入图片是否为人脸,即解决是和否的问题。人脸二分类器的原理如下图所示:
由于人脸可能出现在图像的任何位置,在检测时用固定大小的窗口对图像从上到下、从左到右扫描,判断窗口里的子图像是否为人脸,这称为滑动窗口技术(sliding window)。为了检测不同大小的人脸,还需要对图像进行放大或者缩小构造图像金字塔,对每张缩放后的图像都用上面的方法进行扫描。由于采用了滑动窗口扫描技术,并且要对图像进行反复缩放然后扫描,因此整个检测过程会非常耗时。
由于一个人脸附件可能会检测出多个候选位置框,还需要将检测结果进行合并去重,这称为非极大值抑制(NMS)。多尺度滑动窗口技术的原理如下图所示:
典型应用
人脸检测是机器视觉领域被深入研究的经典问题,在安防监控、人证比对、人机交互、社交等领域都有重要的应用价值。数码相机、智能手机等端上的设备已经大量使用人脸检测技术实现成像时对人脸的对焦、图集整理分类等功能,各种虚拟美颜相机也需要人脸检测技术定位人脸,然后才能根据人脸对齐的技术确定人脸皮肤、五官的范围然后进行美颜。在人脸识别的流程中,人脸检测是整个人脸识别算法的第一步。
我们将整个人脸检测算法分为3个阶段,分别是早期算法,AdaBoost框架,以及深度学习时代,在接下来将分这几部分进行介绍。
早期的人脸检测算法使用了模板匹配技术,即用一个人脸模板图像与被检测图像中的各个位置进行匹配,确定这个位置处是否有人脸;此后机器学习算法被用于该问题,包括神经网络,支持向量机等。以上都是针对图像中某个区域进行人脸-非人脸二分类的判别。
早期有代表性的成果是Rowley等人提出的方法[1][2]。他们用神经网络进行人脸检测,用20x20的人脸和非人脸图像训练了一个多层感知器模型。文献[1]的方法用于解决近似正面的人脸检测问题,原理如下图所示:
文献[2]的方法解决多角度人脸检测问题,整个系统由两个神经网络构成,第一个网络用于估计人脸的角度,第二个用于判断是否为人脸。角度估计器输出一个旋转角度,然后用整个角度对检测窗进行旋转,然后用第二个网络对旋转后的图像进行判断,确定是否为人脸。系统结构如下图所示:
Rowley的方法有不错的精度,由于分类器的设计相对复杂而且采用的是密集滑动窗口进行采样分类导致其速度太慢。
接下来介绍AdaBoost框架之后的方法,boost算法是基于PAC学习理论(probably approximately correct)而建立的一套集成学习算法(ensemble learning)。其根本思想在于通过多个简单的弱分类器,构建出准确率很高的强分类器,PAC学习理论证实了这一方法的可行性,感谢大神Leslie-Valiant!!我们首先来看FDDB上各种检测算法的ROC曲线,接下来的介绍将按照这些ROC曲线上的算法进行展开。
在2001年Viola和Jones设计了一种人脸检测算法[10]。它使用简单的Haar-like特征和级联的AdaBoost分类器构造检测器,检测速度较之前的方法有2个数量级的提高,并且保持了很好的精度,我们称这种方法为VJ框架。VJ框架是人脸检测历史上第一个最具有里程碑意义的一个成果,奠定了基于AdaBoost目标检测框架的基础,所以作为重点和大家唠唠。
用级联AdaBoost分类器进行目标检测的思想是:用多个AdaBoost分类器合作完成对候选框的分类,这些分类器组成一个流水线,对滑动窗口中的候选框图像进行判定,确定它是人脸还是非人脸。
在这一系列AdaBoost分类器中,前面的强分类器设计很简单,包含的弱分类器很少,可以快速排除掉大量的不是人脸的窗口,但也可能会把一些不是人脸的图像判定为人脸。如果一个候选框通过了第一级分类器的筛选即被判定为人脸,则送入下一级分类器中进行判定,以此类推。如果一个待检测窗口通过了所有的强分类器,则认为是人脸,否则是非人脸。下图是分类器级联进行判断的示意图:
出于性能考虑,弱分类器使用了简单的Haar-like特征,这种特征源自于小波分析中的Haar小波变换,Haar小波是最简单的小波函数,用于对信号进行均值、细节分解。这里的Haar-like特征定义为图像中相邻矩形区域像素之和的差值。下图是基本Haar-like特征的示意图:
Haar-like特征是白色矩形框内的像素值之和,减去黑色区域内的像素值之和。以图像中第一个特征为例,它的计算方法如下:首先计算左边白色矩形区域里所有像素值的和,接下来计算右边黑色矩形区域内所有像素的和,最后得到的Haar-like特征值为左边的和减右边的和。
这种特征捕捉图像的边缘、变化等信息,各种特征描述在各个方向上的图像变化信息。人脸的五官有各自的亮度信息,很符合Haar-like特征的特点。
为了实现快速计算,使用了一种称为积分图(Integral Image)的机制。通过积分图可以快速计算出图像中任何一个矩形区域的像素之和,从而计算出各种类型的Haar-like特征。假设有一张图像,其第i行第j列处的像素值为,积分图定义为:
即原始图像在任何一点处的左上角元素之和。在构造出积分图之后,借助于它可以快速计算出任何一个矩形区域内的像素之和,以下图中的矩形框为例:
在上图中,要计算黑色矩形框内的像素值之和。假设上面四个矩形的右下角的坐标分别为
之所以这样,是因为黑色区域内的像素值之和等于这4个矩形框内的像素值之和,减去上面两个矩形框的像素值之和,再减去左边两个矩形框的像素值之和,这样做的话,左上角的矩形框被减了两遍,因此要加一遍回来。在计算出任何一个矩形区域的像素值之和后,可以方便的计算出上面任何一种Haar-like特征。下图是通过AdaBoost算法自动筛选出来的对区分人脸和非人脸有用的Haar-like特征,基本符合人类的直观感受:
弱分类器采用最简单的深度很小的决策树,甚至只有一个内部节点。决策树的训练算法此处不做详细的阐述,需要注意的是这里的特征向量是稀疏的,即每一棵决策树只接受少量特征分量的输入,根据它们来做决策。
强分类器和前面讲述的是一样的,不同的是这里的强分类器加上了一个调节阈值:
其中为阈值,它通过训练得到。每一级强分类器在训练时使用所有的人脸样本作为正样本,并用上一级强分类器对负样本图像进行扫描,把找到的虚警中被判定为人脸的区域截取出来作为下一级强分类器的负样本。
假设第i级强分类器的检测率和误报率分别为di 和fi,由于要通过了所有强分类器才被判定为正样本,因此级联分类器的误报率为:
这个式子表明增加分类器的级数会降低检测率。对于前者,可以理解为一个负样本被每一级分类器都判定为正样本的概率;对于后者,可以理解为一个正样本被所有分类器都判定为正样本的概率。
在VJ算法问世之后,较好的解决了近似正面人脸的检测问题。此后出现了大量改进方案,在深度学习技术出现之前,一直是人脸检测算法的主流框架。这些方案的改进主要在以下几个方面:
新的特征,包括扩展的Haar特征[4],ACF特征[15]等,它们比标准的Haar-like特征有更强的描述能力,同时计算成本也很低。
使用其他类型的AdaBoost分类器。VJ框架中采用的是离散型的AdaBoost算法,除此之外,还有实数型,Logit型,Gentle型等各种方案。实数型、Logit型和Gentle型AdaBoost算法不仅能输出分类标签值,还能给出置信度,有更高的精度。
分类器级联结构,如Soft Cascade,将VJ方法的多个强分类器改成一个强分类器(该算法后面会有介绍)。另外,检测处于各种角度和姿态的人脸是研究另一个重点,VJ方法的分类器级联只有一条路径,是瀑布模型,改进的方案有树状级联,金字塔级联等,篇幅所限这里不做过多解释,各种级联方案如下图所示:
在深度学习出现以前工业界的方案都是基于VJ算法。但VJ算法仍存在一些问题:
Haar-like特征是一种相对简单的特征,其稳定性较低;
弱分类器采用简单的决策树,容易过拟合。因此,该算法对于解决正面的 人脸效果好,对于人脸的遮挡,姿态,表情等特殊且复杂的情况,处理效果不理想(虽然有了一些改进方案,但还是不够彻底!!)。
基于VJ-cascade的分类器设计,进入下一个stage后,之前的信息都丢弃了,分类器评价一个样本不会基于它在之前stage的表现----这样的分类器鲁棒性差。
ACF[15](Aggregate Channel Features for Multi-view Face Detection)是一种为分类提供足够多的特征选择的方法。在对原图进行处理后,得到多通道的图像,这些通道可以是RGB的通道,可以是平滑滤波得到的,可以是x方向y方向的梯度图等等。将这些通道合起来,在此基础上提取特征向量后续采用Soft-Cascade分类器进行分类。
相较于VJ-cascade的设计,Soft-Cascade采用几个改进的方案:
每个stage的决策函数不是二值而是标量值(scalar-valued) ,且与该样本有多"容易"通过这个stage以及在这个stage的相对重要性成比例。
生成的决策函数是需要通过之前每个阶段的值而不单单是本阶段来判定。
文中把检测器的运行时间-准确率权衡通过一个叫ROC surface的3维曲面清楚的展示出来,方便调节参数,可以明确的知道动了哪个参数会对这个检测器的性能会有些什么影响。
DPM(Deformable Part Model),正如其名称所述,可变形的组件模型,是一种基于组件的检测算法,其所见即其意。该模型由Felzenszwalb在2008年提出,并发表了一系列的CVPR,NIPS会议。并且还拿下了2010年,PASCAL VOC的“终身成就奖”。
由于DPM算法[16]本身是一种基于组件的检测算法,所以对扭曲,性别,多姿态,多角度等的人脸都具有非常好的检测效果(人脸通常不会有大的形变,可以近似为刚体,基于DMP的方法可以很好地处理人脸检测问题)。
DPM的方法采用的是FHOG进行特征的提取,作者对HOG进行了很大的改动,没有直接采用4*9=36维向量,而是对每个8x8的cell提取18+9+4=31维特征向量。作者还讨论了依据PCA(Principle Component Analysis)可视化的结果选9+4维特征,能达到HOG 4*9维特征的效果。基于DPM的方法在户外人脸集上都取得了比Viola-Jones更好的效果,但是由于该模型过于复杂,判断时计算复杂,很难满足实时性的要求。后续有了一些列改进的流程,比如加入级联分类器,针对特征计算采用了积分图的方法等,但都还没有达到VJ方法的效率。
DPM模型一个大的问题是速度太慢,因此在工程中很少使用,一般采用的是AdaBoost框架的算法。
基于经典的人工设计特征本身稳定性并不稳定,容易受外界环境的影响(光照、角度、遮挡等),所以在复杂场景下的人脸检测性能很难的到保证,只能应用到受限的场景中。深度学习出现以后,DCNN(深度卷积神经网络)能很好的学习到图像中目标物各个层级的特征,对外界的抗干扰能力更强,后序的人脸检测方法基本都基于DCNN的特征来优化了。
基于深度学习的方法在FDDB上基本饱和了,是时候抛出一个新的benchmark了!!!WIDERFace测试集上各种算法的性能:
卷积神经网络在图像分类问题上取得成功之后很快被用于人脸检测问题,在精度上大幅度超越之前的AdaBoost框架,当前已经有一些高精度、高效的算法。直接用滑动窗口加卷积网络对窗口图像进行分类的方案计算量太大很难达到实时,使用卷积网络进行人脸检测的方法采用各种手段解决或者避免这个问题。
Cascade CNN[17]可以认为是传统技术和深度网络相结合的一个代表,和VJ人脸检测器一样,其包含了多个分类器,这些分类器采用级联结构进行组织,然而不同的地方在于,Cascade CNN采用卷积网络作为每一级的分类器。
构建多尺度的人脸图像金字塔,12-net将密集的扫描这整幅图像(不同的尺寸),快速的剔除掉超过90%的检测窗口,剩下来的检测窗口送入12-calibration-net调整它的尺寸和位置,让它更接近潜在的人脸图像的附近。
采用非极大值抑制(NMS)合并高度重叠的检测窗口,保留下来的候选检测窗口将会被归一化到24x24作为24-net的输入,这将进一步剔除掉剩下来的将近90%的检测窗口。和之前的过程一样,通过24-calibration-net矫正检测窗口,并应用NMS进一步合并减少检测窗口的数量。
将通过之前所有层级的检测窗口对应的图像区域归一化到48x48送入48-net进行分类得到进一步过滤的人脸候选窗口。然后利用NMS进行窗口合并,送入48-calibration-net矫正检测窗口作为最后的输出。
网络设计要点:
1.第一级12-net要尽量快,保证召回率的同时,过滤大量非人脸,在每一个尺度,使用NMS,recall达到99%
2.第二级24-net的输入为第一级检测的样本,首先与gt匹配,标定出正负样本,然后分类,另外,第二级使用了多尺度,即将两个stage的fc进行concate。同样,在每一个尺度,使用NMS,recall达到97%
3.第三级48-net网格稍微加深,过程同stage2,本次所有的尺度一块使用NMS
4.回归网络使用bounding box的方式
12x12,24x24,48x48尺寸作为输入的分类CNN网络结构,其中输出为2类-人脸和非人脸。
Cascade CNN一定程度上解决了传统方法在开放场景中对光照、角度等敏感的问题,但是该框架的第一级还是基于密集滑动窗口的方式进行窗口过滤,在高分辨率存在大量小人脸(tiny face)的图片上限制了算法的性能上限。