Haar + AdaBoost

本篇博客引用论文:
【1】Rapid Object Detection using a Boosted Cascade of Simple Features
【2】Robust Real-Time Face Detection
这两篇论文基本思想相似,只不过前一篇是应用于目标检测,后一篇是用于人脸检测。绝对的经典之作,论文引用量已经上万。在论文中,主要提到三个创新点:

  •  积分图:它使得应用到检测器的特征能够被快速计算 
  • AdaBoost分类器:它使用AdaBoost学习算法从巨大的Haar-like特征中挑选出少量至关重要的特征 
  • 级联结构:以一种级联的方式组合分类器,投入更多关注在类人脸区域上

特征(Features)

Haar-like特征最早是由Papageorous等应用在人脸表示,VioIa和Jones在此基础上,使用3种类型4种形式的特征,如图1所示。Haar特征分为三类:边缘特征、线性特征、中心特征和对角线特征,组合成特征模板。特征模板内有白色和黑色两种矩形,并定义该模板的特征为黑色矩形像素和减去白色矩形像素和(The sum of the pixels which lie within the white rectangles are subtracted from the sum of pixels in the grey rectangles)。Haar特征值反映了图像的灰度变化情况。人脸检测时,脸部的一些特征能由矩形特征简单的描述,如眼睛要比脸颊颜色深,鼻梁两侧比鼻梁深等等。

在给定有限的数据情况下,基于特征的检测能够编码特定区域的状态,而且基于特征的系统比基于像素的系统要快得多。但是矩形特征只对一些简单的图形结构,如边缘、线段和其他简单的图形结构比较敏感,描述相对粗糙,只能描述水平、垂直和对角等特定方向的结构。

图1: Haar-like特征

通过改变特征模板的大小和位置,可在图像子窗口中穷举出大量的特征。特征模板在图像子窗口中扩展(平移伸缩)得到的特征称为矩形特征,矩形特征的值称为特征值。

目前,haar-like矩形特征已不仅仅局限于上面四种情况,加入了45度角的矩形特征,扩展后的特征大致分为四种,边缘特征、线性特征、中心环绕特征和对角线特征,如图2所示

图2:矩形特征分类

Haar特征个数计算

给定一个m*m大小的子窗口,那么如何计算这个子窗口中包含的矩形特征数量呢?我们知道,对于一个矩形,只要确定其左上顶点A\left ( x_{1}, y_{1} \right )和右下顶点B\left ( x_{2}, y_{2} \right )两个坐标,这个矩形就能够被确定的。如果矩形还满足下面两个条件(被称为(s,t)条件,满足(s,t)条件的矩形被称为条件矩形):1. x方向边长必须能被自然数s整除;2. y方向边长必须能够被自然数t整除。这样,这个矩形的最小尺寸为s×t或者t×s,最大尺寸为[m/s]*s x [m/t]*t 或者[m/t]*t x [m/s]*s;其中[]为整除运算符

如图3所示,确定条件矩形的左上角顶点A\left ( x_{1}, y_{1} \right )x_{1} \in \left \{ 1, 2, \cdots , m-s, m-s+1 \right \}, y_{1} \in \left \{ 1, 2, \cdots, m-t, m-t+1 \right \},那么B点B\left ( x_{2}, y_{2} \right )的取值范围也被固定,x_{2} \in \left \{ x_{1} + s , x_{1} + 2\cdot s, \cdots, x_{1} + p\cdot s\right \}, y_{2} \in \left \{ y_{1}+t, y_{1} + 2 \cdot t, \cdots, y_{1}+ q \cdot t \right\}

其中p = [\frac{m-x_{1}+1}{s}], q = [\frac{m-y_{1}+1}{t}],可知x_{2}y_{2}所属集合里元素的数量分别为p和q

图3: m*m子窗口

由此可知,在m*m子窗口中,满足(s,t)条件的所有矩形的数量为:

                                                          \begin{align*} &\Omega_{\left ( s,t \right )}^{m}=\sum_{x_{1}= 1}^{m-s+1}\sum_{y_{1}= 1}^{m-t+1}p \cdot q \\ & =\sum_{x_{1}=1}^{m-s+1}\sum_{y_{1}=1}^{m-t+1}[\frac{m-x_{1}+1}{s}][\frac{m-y_{1}+1}{t}] \\ &=\sum_{x_{1}=1}^{m-s+1}[\frac{m-x_{1}+1}{s}]\sum_{y_{1}=1}^{m-t+1}[\frac{m-y_{1}+1}{t}] \\ &= \left ( [\frac{m}{s}] +[\frac{m-1}{s}] + \cdots + 1\right )\cdot \left ( [\frac{m}{t}] +[\frac{m-1}{t}] + \cdots + 1 \right ) \end{align*}

依据上述公式就能够推断出一个子窗口中的特征总数量。图4中就列出了不同特征模板所对应的(s,t)条件,一般来说,m×m子窗口中特征的总数量等于所选特征模板的特征数量之和

图4:(s,t)条件的矩形特征

纠结了好久如何计算,话不多说,一切尽在代码中,最后结果和所给结果相等,至少证明我没有理解错。

def haarFeature():
    feature = [[1, 2], [2, 1], [1, 3], [3, 1], [2, 2]]
    windowSize = 24

    totalFeature = []
    count = 0
    for t in range(5):
        sizeX = feature[t][0]
        sizeY = feature[t][1]
        typeCount = 0

        for width, height in product(range(sizeX, windowSize + 1, sizeX),
                                     range(sizeY, windowSize + 1, sizeY)):
            for x, y in product(range(0, windowSize- width + 1),
                                range(0, windowSize - height + 1)):
                totalFeature.append((t, x, y, width, height))
                count += 1

        print('type', t, ': (s,t)=', sizeX, sizeY, typeCount)
    print('total feature number of 24 * 24:', count)
    print(len(totalFeature))

输出结果:

type 0 : (s,t)= 1 2 43200
type 1 : (s,t)= 2 1 43200
type 2 : (s,t)= 1 3 27600
type 3 : (s,t)= 3 1 27600
type 4 : (s,t)= 2 2 20736
total feature number of 24 * 24: 162336

积分图(Integral Image)

积分图是一种能够描述全局信息的矩阵表示方法。Viola将积分图应用到特征的计算之中。定义图像中坐标为(x, y)的点的积分图ii\left ( x,y \right )等于x,y左上角方向上此图像所有像素的和,如下图5所示,点(x, y)的积分图等于阴影矩形部分的所有像素和。 用公式表达就是:

                                                                    ii\left ( x, y \right ) = \sum_{x' \leqslant x, y' \leq y} i\left ( x', y' \right )

其中i\left ( x', y' \right )为原始图像(x', y')处的像素值。对于灰度图像,其值取值为0~255;对于彩色图像,可以先按照人脸色彩空间将其转化为灰度取值

ii\left ( x,y \right )也可以通过以下迭代求出:

                                                                  \\ s\left ( x, y \right ) = s\left ( s, y-1 \right ) + i\left ( x,y \right ) \\ ii\left ( x, y \right ) = ii\left ( x-1, y \right ) + s\left ( x, y \right )

其中s\left ( x, y \right )为点(x, y)为y方向上图像像素之和,被称为‘cumulative row sum’,s\left(x, -1 \right ) =0, ii\left( -1, y\right)=0

图5:点(x,y)的积分图计算

利用积分图计算矩形特征值

图像区域的运算:一个区域里的像素值,可以利用该区域端点的积分图来计算,如下图6所示,区域D的像素值=ii\left ( 4 \right ) + ii\left ( 1 \right ) -ii\left ( 2 \right ) -ii\left ( 3 \right ),也就是区域D的像素值=区域A+B+C+D的像素值 + 区域A的像素值 - 区域A+C的像素值 - 区域A+B的像素值。由此,可用积分图快速得到一个区域的像素值。

图6:基于积分图,图像区域的运算

特征模板的特征值计算:如图1中的B为例,如图5所示,此特征模板的特征值为区域A的像素值 - 区域B的像素值,由上述区域的积分图运算,区域A的像素值=ii\left ( 5 \right ) + ii\left ( 1 \right ) -ii\left ( 2 \right ) -ii\left (4 \right ),区域B的像素值=ii\left ( 6 \right ) + ii\left ( 2 \right ) - ii\left ( 3 \right ) - ii\left ( 5 \right ),所以此特征模板的特征值为\left [ ii\left (5 \right )-ii\left ( 4 \right ) \right ] +\left [ ii\left ( 3 \right )-ii\left ( 2 \right ) \right ] - \left [ ii\left ( 2 \right )-ii\left ( 1 \right ) \right ] - \left [ ii\left (6 \right )-ii\left ( 5 \right ) \right ],可知,矩形特征的特征值计算只于此特征端点的积分图有关,与坐标位置无关。所以通过计算特征矩形端点的积分图,再进行简单的加减运算,就可以得到特征值。正因为如此,特征的计算速度大大提高,也提高了目标的检测速度。

图7:特征模板的特征值计算

Adaboost

Adaboost是集成学习中的一种最常用的方法,它通过组合很多弱分类器达到一个强分类器的分类效果。详情请移步我的博客文章《集成学习》

确定训练子窗口中的矩形特征数量和特征值后,对每一个特征f,训练一个弱分类器h\left ( x, f, p, \theta \right ),其中x是一个24*24大小的子窗口,f是一个特征,p指示不等号的方向,\theta是一个阈值。

                                                               h\left ( x, f, p, \theta \right ) = \left\{\begin{matrix} 1 & if \, p\cdot f\left ( x \right ) < p\cdot \theta \\ 0 & otherwise \end{matrix}\right.

训练一个弱分类器h\left ( x, f, p, \theta \right )的过程实际上就是在寻找特征f的最优阈值\theta,使得弱分类器对所有样本的判断误差最低。选取一个最佳弱分类器就是选择那个对所有训练样本的分类误差在所有弱分类器中最低的那个弱分类器。

弱分类器训练的过程可描述为:对于一个特征,计算其在样本中的特征值,然后按照特征值进行排序。对在排序队里的每个特征,计算全部正例样本的权重和T^{+},全部负例样本的权重和T^{-},当前样本前的正例权重和S^{+}和当前样本前的负例权重和S^{-}。选择当前元素的特征值和前一个元素的特征值之间的数作为阈值,所得到的弱分类器就在当前元素处把样本分成两部分--人脸或者非人脸,该阈值的分类误差为:

                                                            e=min\left( S^{+} + \left(T^{-} - S^{-} \right ), S^{-} + \left(T^{+} - S^{+} \right )\right)

图8描述了整个AdaBoost算法的流程,AdaBoost算法最后得到结果是一个强分类器,这个强分类器中包含T个弱分类器,通过让所有弱分类器投票,再对所有投票结果按照弱分类器的错误率加权求和,将投票加权求和的结果和平均投票结果进行比较从而得到最终的强分类器。

图8:AdaBoost算法流程

 

级联分类器

在介绍级联分类前,先插播介绍一下在人脸检测中的评价指标:

检测率:被正确检测到的人脸数目与原图像内包含的人脸数目的比值。检测率越高,表明检测系统对人脸的接受能力越高

误识率:被误检为人脸的非人脸子窗口的数目与原图像内被检测的所有非人脸子窗口数目的比值

检测率无法反映系统对非人脸的排除能力,有可能所有人脸都被检测到的同时有大量的非人脸也被误检为人脸。因此,引入误检率来衡量系统对非人脸样本的排除能力。误识率越低,说明检测系统对非人脸的排除能力强。

现在讨论一下比传统的AdaBoost分类器更快的分类方法,即级联分类器。该分类器由若干个简单的Adaboost分类器串联而成。级联分类器的图片描述见图9。每层的强分类器能够让几乎全部的人脸样本通过,拒绝很大一部分非人脸样本。在检测的过程中,因为检测率比较高,所以一旦检测到某区域不是目标就可以直接停止后续检测。由于在人脸检测应用中非人脸区域占大部分,这样大部分检测窗口都能够很快停止,使得分类速度得到很大的提高。 

给定一个级联分类器,假设其误识率为F= \prod_{i=1}^{K}f_{i},其中F是整个级联分类器的误识率,K是级联分类器的层数,f_{i}是第i层强分类器的误识率;假设其检测率为D=\prod_{i=1}^{K}d_{i},其中D是整个级联分类器的检测率,K是级联分类器的层数,d_{i}是第i层强分类器的检测率。假设需要一个99%的检测率和1%的误检率的人脸分类器,现在有一个99.9%正确率和50%误检率的AdaBoost分类器,那么通过级联,假设10级级联,就能够得到检测率和误检率分别为0.999^{10} \approx 0.990.5^{10}\approx 0.1。而且一个一个99.9%正确率和50%误检率的AdaBoost分类器比一个99%的检测率和1%的误检率所需要的特征维度要少很多,使得计算更快。

图9:级联检测过程

如图10所示,用户选择级联分类器每层可接受的最大误识率f和最小检测率d,特征数量每层递增,使用AdaBoost训练直到达到目标检测率和误识率。检测率和误识率是在测试集上测试当前分类器得到的。如果总的误识率没有达到要求,那么就再添加一层。

图10:级联人脸检测的训练过程

最后,对haar+Adaboost人脸检测算法做个总结,包括四部分,haar-like特征+积分图快速计算haar-like特征值+Adaboost训练区分人脸和非人脸的强分类器+将多个强分类器级联在一起,以提高准确率。

参考文献:

An extended Set of Haar-like Features for Rapid Object Detection

Haar特征与积分图(AdaBoost方法原理介绍,非常经典)

浅析人脸检测之Haar分类器方法

(北京大学本科论文)基于AdaBoost算法的人脸检测

基于Adaboost的人脸检测方法及眼睛定位算法研究

  • 1
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

马鹤宁

谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值