(一)目标检测之 Viola |
您所在的位置:网站首页 › michaeljones › (一)目标检测之 Viola |
文章目录
前言一、Viola Jones 背景二、Haar-like特征三、积分图四、AdaBoost五、级联检测六、结果七、复现八、总结参考资料
目标检测:找出图像中所有感兴趣的物体,包含物体定位和物体分类两个子任务,即同时确定物体的类别和位置。 传统目标检测方法的缺点: 特征难以设计特征不鲁棒,效率存在瓶颈滑动窗口提取策略非常繁琐算法基本流程: 候选框:通常采用滑动窗口的方法进行 特征提取 = { 底层特征:颜色、纹理、形状 中层特征: P C A 、 L D A 高层特征:对底层和中层特征进一步挖掘、表示 特征提取=\left\{ \begin{aligned} &底层特征:颜色、纹理、形状\\ &中层特征:PCA、LDA\\ &高层特征:对底层和中层特征进一步挖掘、表示 \end{aligned} \right. 特征提取=⎩ ⎨ ⎧底层特征:颜色、纹理、形状中层特征:PCA、LDA高层特征:对底层和中层特征进一步挖掘、表示 分类器:根据提取到的特征对目标进行分类,分类器主要有 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算法的三个创新性点: 采用积分图像(integral image)技术,加速对Haar-like输入特征的计算采用 AdaBoost 算法进行特征选择,选择出几个关键的视觉特征采用检测级联技术提高准确率,允许图像的背景区域被很快丢弃,从而将更多的计算放在可能是目标的区域上,减少了计算开销 二、Haar-like特征 在Haar-like特征提出之前,传统的人脸检测算法一般是基于图像像素值进行的,计算量较大且实时性较差。Papageorgiou等人最早将Harr小波用于人脸特征表示,Haar小波是最简单的小波函数,用于对信号进行均值、细节分解。Viola和Jones 在此基础上,提出了多种形式的Haar特征。Lienhart等人对Haar矩形特征做了进一步的扩展,加入了旋转45° 的矩形特征,现有的Haar特征模板主要如下图所示: 下图是通过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)=x′≤x,y′≤y∑i(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,j−1)+f(i,j)ii(i,j)=ii(i−1,j)+s(i,j) 4)扫描图像一遍,当到达图像右下角像素时,积分图像 i i ii ii 就构造好了。
下图为积分图的使用方法: 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), GIntensity←31(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) GGleam←31(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算法仍存在一些问题: Haar-like特征是一种相对简单的特征,其稳定性较低弱分类器采用简单的决策树,容易过拟合。因此,该算法对于解决正面的 人脸效果好,对于人脸的遮挡,姿态,表情等特殊且复杂的情况,处理效果不理想基于VJ-cascade的分类器设计,进入下一个分类器后,之前的信息都丢弃了,分类器评价一个样本不会基于样本在之前步骤中的表现,导致分类器的鲁棒性差。 参考资料 Rapid Object Detection using a Boosted Cascade of Simple浅析人脸检测之Haar分类器方法目标检测2——传统典型方法:Viola-JonesViola-Jones’ face detection claims 180k features |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |