(一)目标检测之 Viola-Jones


在这里插入图片描述

前言

目标检测:找出图像中所有感兴趣的物体,包含物体定位和物体分类两个子任务,即同时确定物体的类别和位置。

传统目标检测方法的缺点:

  • 特征难以设计
  • 特征不鲁棒,效率存在瓶颈
  • 滑动窗口提取策略非常繁琐

算法基本流程:

在这里插入图片描述

  • 候选框:通常采用滑动窗口的方法进行

  • 特征提取 = { 底层特征:颜色、纹理、形状 中层特征: P C A 、 L D A 高层特征:对底层和中层特征进一步挖掘、表示 特征提取=\left\{ \begin{aligned} &底层特征:颜色、纹理、形状\\ &中层特征:PCA、LDA\\ &高层特征:对底层和中层特征进一步挖掘、表示 \end{aligned} \right. 特征提取= 底层特征:颜色、纹理、形状中层特征:PCALDA高层特征:对底层和中层特征进一步挖掘、表示

  • 分类器:根据提取到的特征对目标进行分类,分类器主要有 SVM,AdaBoost 等

  • NMS:非极大值抑制,计算置信度,进行候选框的合并、过滤,寻找最佳物体检测位置

VJ算法最初用于检测正面的人脸图像,在VJ出现的时候,人脸检测方法主要有两大类:基于知识基于统计

  • 基于知识
      主要是利用先验知识将人脸看作器官特征的组合,根据眼睛、眉毛、嘴巴、鼻子等器官的特征以及它们相互之间的几何位置关系来检测人脸。有模板匹配、人脸特征、形状与边缘、纹理特性、颜色特征等方法。

  • 基于统计
      将人脸看作一个整体的模式——二维像素矩阵,从统计的观点通过大量人脸图像样本构造人脸模式空间,根据相似度量来判断人脸是否存在。主要包括主成分分析与特征脸、神经网络方法、支持向量机、隐马尔可夫模型、Adaboost等算法。


一、Viola Jones 背景

  在2001年,Viola 和 Jones 在CVPR上发表了经典的《Rapid Object Detection using a Boosted Cascade of Simple Features》《Robust Real-Time Face Detection》,提出了Viola-Jones检测器。VJ框架在AdaBoost算法的基础上,使用Haar-like小波特征和积分图技术来进行人脸检测。

  VJ框架在常规700 MHz英特尔奔腾III上,对384×288像素的图像的人脸检测速度达到了每秒15帧。它采用一个单一的灰度图像就实现了高帧速率,较之前的方法有了2个数量级的提高,并且同时保持了很好的精度。

  之后,Rainer Lienhart 和 Jochen Maydt 将这个检测器用对角特征进行了扩展《An Extended Set of Haar-like Features for Rapid Object Detection》。OpenCV 和 Matlab 也都将这个算法写进了函数库中,可以很方便的直接调用。在深度学习技术出现之前,VJ一直是人脸检测算法的主流框架。

VJ算法的三个创新性点:

  1. 采用积分图像(integral image)技术,加速对Haar-like输入特征的计算
  2. 采用 AdaBoost 算法进行特征选择,选择出几个关键的视觉特征
  3. 采用检测级联技术提高准确率,允许图像的背景区域被很快丢弃,从而将更多的计算放在可能是目标的区域上,减少了计算开销

二、Haar-like特征

  在Haar-like特征提出之前,传统的人脸检测算法一般是基于图像像素值进行的,计算量较大且实时性较差。Papageorgiou等人最早将Harr小波用于人脸特征表示,Haar小波是最简单的小波函数,用于对信号进行均值、细节分解。Viola和Jones 在此基础上,提出了多种形式的Haar特征。Lienhart等人对Haar矩形特征做了进一步的扩展,加入了旋转45° 的矩形特征,现有的Haar特征模板主要如下图所示:
在这里插入图片描述
  Haar-like特征定义为上图中白黑矩形区域像素之和的差值。它在灰度分布均匀的区域特征值趋近于0。Haar特征在一定程度上反应了图像灰度的局部变化,这种特征捕捉图像的边缘、变化等信息。
  人脸的五官有各自的亮度信息,例如眼睛比周围区域的颜色要深,鼻梁比两侧颜色要浅。Haar-like特征对于这些“块特征”(眼睛,嘴,发际线)具有比较好的效果,但对树枝或主要靠外形(如咖啡杯)的物体不适用。

下图是通过AdaBoost算法自动筛选出来的对区分人脸和非人脸有用的Haar-like特征,基本符合人类的直观感受。

在这里插入图片描述

在 Viola 和 Jones 论文中提出的特征如下(注意,三个矩形的特征应该有两个)
在这里插入图片描述

特征提取过程详见下图

在这里插入图片描述

VJ 算法使用的图像大小为 24×24,可以计算出矩形特征的数量多达16万个(作者原文为18万,有误)。

考虑水平方向与垂直方向,二邻接矩形有两种情况1×2 和 2×1,三邻接矩形也有两种情况 1×3 和 3×1,而四邻接矩形只有一种情况2×2,总计五种类型。

根据卷积定理,我们知道一个W×H 的图像与 m×n 的filter 做卷积,新生成的图像大小为(W−m+1)×(H−n+1), 新图像的每一个像素其实就是原图一个m×n 的local patch与 m×n 的filter 的乘积和。新图像有多少个像素,就对应着原图多少个m×n 的矩形。

frameSize = 24;
features = 5;
feature = [[2,1], [1,2], [3,1], [1,3], [2,2]]
count = 0;
# Each feature:
for i in range(features):
    sizeX = feature[i][0]
    sizeY = feature[i][1]
    # Each position:
    for x in range(frameSize-sizeX+1):
        for y in range(frameSize-sizeY+1):
            # Each size fitting within the frameSize:
            for width in range(sizeX,frameSize-x+1,sizeX):
                for height in range(sizeY,frameSize-y+1,sizeY):
                    count=count+1
print (count) # 162336

通过上面的代码可以得知:一个 24×24 的图像最终会产生162336个矩形特征,这个维度远远高于图像本身的维度,需要进行特征选择。

三、积分图

  积分图是一种计算方法,以加快盒滤波或卷积过程。积分图像使得VJ检测器中每个窗口的计算复杂度与其窗口大小无关。

i i ( x , y ) = ∑ x ′ ≤ x , y ′ ≤ y i ( x ′ , y ′ ) \begin{aligned} ii(x,y) = \sum_{x^{'}\le x,y^{'} \le y}i(x^{'},y^{'}) \end{aligned} ii(x,y)=xx,yyi(x,y)

i i ii ii表示积分图, i i i是原图, i i ( x , y ) ii(x,y) ii(x,y) 就表示 i ( 1 , 1 ) i(1,1) i(1,1) i ( x , y ) i(x,y) i(x,y) 两个对角点所围城的矩形面积的大小。

积分图构建算法:
1)用 s ( i , j ) s(i,j) s(i,j) 表示行方向的累加和,初始化 s ( i , − 1 ) = 0 s(i,-1)=0 s(i,1)=0;

2)用 i i ( i , j ) ii(i,j) ii(i,j) 表示一个积分图像,初始化 i i ( − 1 , i ) = 0 ii(-1,i)=0 ii(1,i)=0;

3)逐行扫描图像,递归计算每个像素 ( i , j ) (i,j) (i,j) 行方向的累加和 s ( i , j ) s(i,j) s(i,j)和 积分图像 i i ( i , j ) ii(i,j) ii(i,j) 的值

s ( i , j ) = s ( i , j − 1 ) + f ( i , j ) i i ( i , j ) = i i ( i − 1 , j ) + s ( i , j ) s(i,j)=s(i,j-1)+f(i,j)\\ ii(i,j)=ii(i-1,j)+s(i,j) s(i,j)=s(i,j1)+f(i,j)ii(i,j)=ii(i1,j)+s(i,j)
4)扫描图像一遍,当到达图像右下角像素时,积分图像 i i ii ii 就构造好了。

在这里插入图片描述
因为积分图像中的任何一点的值等于位于该点左上角所有像素之和,当获取积分图像后,求取任意一个矩形区域的像素和只需要知道该矩形区域四个边角点的值即可。如上图所示:D = 4+1-(2+3)。

下图为积分图的使用方法:
在这里插入图片描述

四、AdaBoost

AdaBoost是Freund和Schapire在1995年提出的算法,是对传统Boosting算法的一大提升。Adaboost 是一种迭代算法,其核心思想是针对同一个训练集训练不同的分类器(弱分类器),然后把这些弱分类器集合起来,构成一个更强的最终分类器(强分类器)。

AdaBoost 可以同时进行特征选择与分类器训练,作者使用Adaboost算法从一组巨大的随机特征池 (162336) 中选择一组对人脸检测最有帮助的特征。

算法流程如下(红线框出来的部分数字错误):
在这里插入图片描述

五、级联检测

在VJ检测器中引入了一个多级检测范例 ( detection cascades ),通过减少对背景窗口的计算,增加对人脸目标的计算,从而减少了计算开销。

AdaBoost训练出来的强分类器一般具有较小的误识率,但检测率并不很高,一般情况下,高检测率会导致高误识率,这是强分类阈值的划分导致的,要提高强分类器的检测率就要降低阈值,要降低强分类器的误识率就要提高阈值,这是个矛盾的事情。而级联检测通过增加分类器个数可以在提高强分类器检测率的同时降低误识率。

这种思想的精髓在于用简单的强分类器在初期快速排除掉大量的非人脸窗口,同时保证高的召回率,使得最终能通过所有级强分类器的样本数很少。这样做的依据是在待检测图像中,绝大部分都不是人脸而是背景,即人脸是一个稀疏事件,如果能快速的把非人脸样本排除掉,则能大大提高目标检测的效率。

级联检测的过程类似于一个决策树,如下图所示。第一个分类器输出True就会触发同样具有较高检测率的第二个分类器对窗口图像做出评价,第二个分类输出True结果将触发第三个分类器对窗口图像做出评价。只要有一个分类器节点输出False结果,就会判断该窗口图像不包含目标物。

在这里插入图片描述

级联分类器的训练过程要考虑以下两种平衡:一是弱分类器的个数和计算时间的平衡(增加特征个数能提高检测率和降低误识率,但会增加计算时间),二是强分类器检测率和误识率之间的平衡。

训练级联分类器的目的就是为了检测的时候,更加准确。检测时,需要以现实中的一幅大图片作为输入,然后对图片中进行多区域、多尺度的检测,多区域是指要对图片划分多块,对每个块进行检测。由于训练的时候用的照片一般都是 24×24的小图片,所以对于大的人脸图片,还需要进行多尺度的检测,

多尺度检测机制一般有两种策略,一种是不改变搜索窗口的大小,而不断缩放图片,这种方法需要对每个缩放后的图片进行区域特征值的运算,效率不高,而另一种方法,是不断初始化搜索窗口size为训练时的图片大小,不断扩大搜索窗口,进行搜索,解决了第一种方法的弱势。在区域放大的过程中会出现同一个人脸被多次检测,这需要进行区域的合并。VJ算法采用了第二种方法。无论哪一种搜索方法,都会为输入图片输出大量的子窗口图像,这些子窗口图像经过筛选式级联分类器会不断地被每一个节点筛选,抛弃或通过。

六、结果

在Viola和Jones的论文中,训练了一个38层级联分类器,用来检测正面直立人脸。人脸训练集由4916个人工标记的人脸图片组成,都缩放到24×24像素。训练检测器的数据包含9544张图片,都已经进行人工检查,确定不包含任何人脸。
在这里插入图片描述

在MIT+CMU正面人脸测试集上对系统进行测试,结果如下

在这里插入图片描述
在这里插入图片描述

七、复现

参考:Viola-Jones AdaBoost-enabled Face Detection

原图片

在这里插入图片描述
伽马转换

在训练的时候,会将彩色图片转化为灰度图片,会用到伽马转换,图片看上去会更亮。

在这里插入图片描述

项目作者使用了一个简单 Intensity conversion的转换,公式和代码如下:

G I n t e n s i t y ← 1 3 ( R + G + B ) , \mathcal{G}_{Intensity} \leftarrow \frac{1}{3}\left(R + G + B\right), GIntensity31(R+G+B),

Gleam 使用 Gamma校正后的通道

G G l e a m ← 1 3 ( R ′ + G ′ + B ′ ) \mathcal{G}_{Gleam} \leftarrow \frac{1}{3}\left(R' + G' + B'\right) GGleam31(R+G+B)

Gamma校正

t ′ = Γ ( t ) = t 1 / 2.2 . t' = \Gamma(t) = t^{1/2.2}. t=Γ(t)=t1/2.2.

常量 2.2 2.2 2.2 选择原因详见 对 Gamma 校正的个人理解, 但建议在超参数优化中找到最佳值。

def gamma(values: np.ndarray, coeff: float=2.2) -> np.ndarray:
    return values**(1./coeff)

def gleam(values: np.ndarray) -> np.ndarray:
    return np.sum(gamma(values), axis=2) / values.shape[2]

效果

在这里插入图片描述

八、总结

在深度学习出现以前,工业界的方案都是基于VJ算法。但VJ算法仍存在一些问题:

  1. Haar-like特征是一种相对简单的特征,其稳定性较低
  2. 弱分类器采用简单的决策树,容易过拟合。因此,该算法对于解决正面的 人脸效果好,对于人脸的遮挡,姿态,表情等特殊且复杂的情况,处理效果不理想
  3. 基于VJ-cascade的分类器设计,进入下一个分类器后,之前的信息都丢弃了,分类器评价一个样本不会基于样本在之前步骤中的表现,导致分类器的鲁棒性差。

参考资料

  1. Rapid Object Detection using a Boosted Cascade of Simple
  2. 浅析人脸检测之Haar分类器方法
  3. 目标检测2——传统典型方法:Viola-Jones
  4. Viola-Jones’ face detection claims 180k features
  • 29
    点赞
  • 141
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
1. Viola-Jones算法: 优点: - 算法速度非常快,能够在实时系统中使用 - 算法对于不同的目标具有较好的泛化性能,可以应用于人脸识别、人体检测等多个领域 缺点: - 对于遮挡、光照变化、角度变化等因素敏感,准确率有限 - 对于非正面的人脸检测效果较差 - 对于目标的大小、旋转角度等要求较高,需要对输入图像进行预处理 2. HOG算法: 优点: - 算法对于光照变化、遮挡等因素具有一定的鲁棒性,能够在一定程度上保持检测的准确性 - 算法能够在不同的尺度下进行目标检测,对于不同大小的目标具有较好的适应性 缺点: - 算法对于目标的姿态、旋转角度等变化较为敏感,需要进行预处理 - 算法对于背景噪声较大的情况下,会对检测结果产生影响 3. YOLO算法: 优点: - 算法速度较快,能够在实时系统中使用 - 算法能够在单个网络中完成目标检测和分类,具有较高的精度和召回率 - 算法对于目标的姿态、旋转角度等变化较为鲁棒 缺点: - 算法对于小目标的检测准确率较低 - 算法对于密集目标的检测准确率较低 - 算法对于目标的长宽比例较大的情况下,检测效果不佳 4. CNN算法: 优点: - 算法能够自动学习特征,无需手工提取,具有较高的鲁棒性和准确性 - 算法对于目标的姿态、旋转角度等变化较为鲁棒 - 算法在图像分类、目标检测等多个领域具有广泛的应用 缺点: - 算法需要大量的计算资源和数据集支持,训练时间较长 - 算法对于数据集的质量要求较高,需要进行预处理 - 算法的可解释性较差,难以理解和解释其决策过程 5. MTCNN算法: 优点: - 算法能够同时完成人脸检测、关键点检测和人脸对齐等任务,具有较高的精度和鲁棒性 - 算法对于不同尺度、姿态、光照等因素具有较好的适应性和泛化性能 缺点: - 算法运行速度较慢,对于实时系统应用有一定限制 - 算法对于遮挡、模糊等情况下的检测效果较差 - 算法对于不同种族、年龄等差异较大的人脸检测效果有限

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值