您现在的位置是:首页 >技术教程 >【youcans 的 OpenCV 学习课】22. Haar 级联分类器网站首页技术教程

【youcans 的 OpenCV 学习课】22. Haar 级联分类器

youcans_ 2023-06-20 20:00:03
简介【youcans 的 OpenCV 学习课】22. Haar 级联分类器

专栏地址:『youcans 的图像处理学习课』
文章目录:『youcans 的图像处理学习课 - 总目录』



3. Haar 特征及其加速计算

Haar 特征分类器是基于 Haar-like 特征提取的监督学习分类器。我们首先讨论 Haar 特征及其加速计算。

3.1 Haar 特征

Haar 特征用黑白两种矩形框组合成特征模板,在特征模板内用黑色矩形像素和减去白色矩形像素和来表示这个模版的特征值。

矩形特征只对一些简单的图形结构,如边缘、线段较敏感,所以只能描述在特定方向(水平、垂直、对角)上有明显像素模块梯度变化的图像结构。

Haar 特征分为三类:边缘特征、线性特征、中心特征和对角线特征。Haar 特征因为类似于 Haar 小波而得名,Haar-like 特征提取过程可以看作是对图像局部进行 Haar 小波变换。

Lienhart R.等对 Haar-like 矩形特征库作了进一步扩展,加入了旋转 45度的对角线特征、中心环绕特征。扩展后的 Haar-like 特征大致分为 4 种类型:边缘特征、线性特征、中心环绕特征和对角线特征。

在这里插入图片描述

Haar 特征值反映了图像的灰度变化情况。例如:脸部的一些特征能由矩形特征简单的描述,如:眼睛要比脸颊颜色要深,鼻梁两侧比鼻梁颜色要深,嘴巴比周围颜色要深等。


3.2 Haar 特征值的计算

特征模板在图像子窗口中扩展(平移伸缩)得到的特征称为“矩形特征”;矩形特征的值称为“特征值”。

f = w w h i t e ∗ ∑ p i ∈ w h i t e p i − w b l a c k ∗ ∑ p i ∈ b l a c k p i f = w_{white}*sum_{p_i in white}{p_i} - w_{black}*sum_{p_i in black}{p_i} f=wwhitepiwhitepiwblackpiblackpi

其中,w 是权重,用于调节黑白区域面积平衡。当特征模板中黑白区域面积相等时 w=1,则特征值的计算简化为:

f = ∑ 白色区域像素值 − ∑ 黑色区域像素值 f = sum{白色区域像素值} - sum{黑色区域像素值} f=白色区域像素值黑色区域像素值

矩形特征值是矩形位置、矩形大小和模板类型这三个变量的函数。

  • 矩形位置:矩形模板框滑动遍历图像的每个位置,类似于卷积核;
  • 矩形大小:矩形大小可以根据需要来定义。
  • 模板类型:包括垂直、水平、对角等不同类型。

通过改变类别、大小和位置,就可以使很小的检测窗口含有非常多的矩形特征,如:在24*24像素大小的检测窗口内矩形特征数量可以达到16万个。随着图像尺寸的扩大, 特征总量近似指数增长 ,这对于特征值的计算带来了很大的挑战。

积分图就是只遍历一次图像就可以求出图像中所有区域像素和的快速算法,大大的提高了图像特征值计算的效率。


3.3 积分图像

Crow 提出的积分图像是一种快速计算图像矩形区域和的算法。积分图像是指对于图像中的每一个像素,取其左上侧区域的全部像素的累加值作为该像素的像素值。积分图相当于建立了二维查找表,极大地降低了计算量、提高了计算速度。

利用积分图像,使用 3次加减法就可以计算出图像中任意矩形区域内像素值的和,由此可以快速实现图像的均值滤波。

L ( x , y ) = ∑ i ≤ x ∑ j ≤ y I ( x , y ) s u m a b c d = L a − L b − L c + L d L(x,y) = sum_{i le x} sum_{j le y} I(x,y) \ sum_{abcd} = L_a - L_b - L_c + L_d L(x,y)=ixjyI(x,y)sumabcd=LaLbLc+Ld

式中,L 表示积分图像的像素值,I 表示输入图像的像素值,abcd表示矩形 S 的顶点。

在这里插入图片描述

通过积分图像可以快速地计算出图像中任意矩形区域内像素值的和、均值和均方差,计算复杂度仅为O(1),这对于像素的邻域处理非常有效。

OpenCV 提供了函数 cv.integral 计算积分图像。

函数说明:

cv.integral(src[, sum=None, sdepth=-1]) → sum
cv.integral2(src[, sum=None, sqsum=None, sdepth=-1, sqdepth=-1]) → sum, sqsum
cv.integral3(src[, sum=None, sqsum=None, tilted=None, sdepth=-1, sqdepth=-1]) → sum, sqsum, titled

函数 cv.integral 计算像素值的积分图像,函数 cv.integral2 计算像素值的积分图像和像素值的平方积分图像,函数 cv.integral3 计算旋转 45度的像素值的积分图像。

s u m ( X , Y ) = ∑ x < X , y < y i m a g e ( x , y ) s q s u m ( X , Y ) = ∑ x < X , y < y i m a g e ( x , y ) 2 t i t l e d ( X , Y ) = ∑ y < y , a b s ( x − X + 1 ) ≤ Y − y − 1 i m a g e ( x , y ) sum(X,Y) = sum_{x<X,y<y} image(x,y) \ sqsum(X,Y) = sum_{x<X,y<y} image(x,y)^2 \ titled(X,Y) = sum_{y<y,abs(x-X+1) le Y-y-1} image(x,y) \ sum(X,Y)=x<X,y<yimage(x,y)sqsum(X,Y)=x<X,y<yimage(x,y)2titled(X,Y)=y<y,abs(xX+1)Yy1image(x,y)

参数说明:

  • scr:输入图像,形状 (H,W) 的 Numpy 数组,8位整型或浮点类型
  • sum:积分图像,形状 (H+1,W+1) 的 Numpy 数组,32位整型或浮点类型
  • sqsum:平方积分图像,形状 (H+1,W+1) 的 Numpy 数组,双精度浮点类型
  • titled:旋转 45度的像素值积分图像,形状 (H+1,W+1) 的 Numpy 数组,类型与 sum 相同
  • sdepth:积分图像和旋转积分图像的深度,CV_32S/CV_32F/CV64F,可选项,默认值 -1
  • sqdepth:平方积分图像的深度,CV_32F/CV64F,可选项,默认值 -1

注意事项:

  1. 允许单通道输入;对于多通道图像,独立地处理各通道的数据。
  2. 可以用可变窗口大小进行快速模糊或快速块相关。

3.4 基于积分图像加速计算 Haar 特征值

Haar 特征值是白色区域像素和与黑色区域像素和之差。使用积分图像可以快速直接地计算白色区域或黑色区域的的像素和,而不需要遍历像素累加计算,因此可以实现 Haar 特征值的加速计算。

在这里插入图片描述

如上图所示,

f = ∑ 白色区域像素值 − ∑ 黑色区域像素值 = I n t e g r a l ( A r e a w h i t e ) − I n t e g r a l ( A r e a b l a c k ) = s u m a b d e − s u m b c e f = ( L a − L b − L d + L e ) − ( L b − L c − L e + L f ) = ( L a − L b ) − ( L b − L c ) − ( L d − L e ) + ( L e − L f ) egin{aligned} f &= sum{白色区域像素值} - sum{黑色区域像素值} \ &= Integral(Area_{white}) - Integral(Area_{black}) \ &= sum_{abde} - sum_{bcef} \ &= (L_a - L_b - L_d + L_e) - (L_b - L_c - L_e + L_f) \ &= (L_a - L_b) - (L_b - L_c) - (L_d - L_e) + (L_e - L_f) end{aligned} f=白色区域像素值黑色区域像素值=Integral(Areawhite)Integral(Areablack)=sumabdesumbcef=(LaLbLd+Le)(LbLcLe+Lf)=(LaLb)(LbLc)(LdLe)+(LeLf)

提取图像的 Haar 特征需要大量重复计算多个尺度矩形的和,反复遍历每个像素,基于积分图像的方法是使用动态规划思想,极大地降低了计算时间。


4. Haar 特征级联分类器

Haar 特征分类器是基于 Haar-like 特征,使用积分图像加速计算,并用 Adaboost 训练的强分类器级联方法来进行特征检测的监督学习分类器。

4.1 Adaboost 算法

Adaboost 算法( Adaptive Boosting )是一种通用的分类器性能提升算法,其核心思想是针对同一个训练集训练不同的分类器(弱分类器),然后把这些弱分类器集合起来,构成一个更强的最终分类器(强分类器)。

Boosting 是一种重要的集成学习技术,主要思想是通过一些简单的规则整合,将预测精度较低的弱学习器增强为预测精度较高的强学习器,为学习算法的设计提供了一种有效的新思路和新方法。作为一种元算法框架,Boosting 几乎可以应用于所有目前流行的机器学习算法,以加强原算法的预测精度。

Adaboost 算法是一种有效而实用的 Boosting 算法,算法的原理是通过调整样本权重和弱分类器权值,从训练出的弱分类器中筛选出权值系数最小的弱分类器组合成一个最终强分类器。

Adaboost 算法是一种迭代训练算法,对样本训练集中的关键分类特征集进行多次挑选,逐步训练分量弱分类器。使用适当的阈值选择最佳弱分类器,最后将每次迭代训练选出的最佳弱分类器构建为强分类器。

Adaboost 算法的训练过程是:

  1. 先通过对 N 个训练样本集的学习得到第 1 个弱分类器;
  2. 将分错的样本和其他的新样本一起构成一个新的 N 个样本的训练集,通过对这个训练集的学习得到第 2 个弱分类器 ;
  3. 将 1 和 2 都分错了的样本和其他的新样本构成另一个新的 N 个样本的训练集,通过对这个训练集的学习得到第 3 个弱分类器;
  4. 依次类推,直到获得最终的强分类器。

Adaboost 算法的基本步骤如下:

  1. 构建第一个弱学习器,找到性能最好的“树桩”(stump)。
  2. 计算“树桩”的分类误差:

e t = ∑ i = 1 n w i ∗ ∣ h j ( x i ) − y i ∣ e_t = sum^n_{i=1} w_i * |h_j(x_i) - y_i| et=i=1nwihj(xi)yi

  1. 调整“树桩”的权重:

α = 1 2 l n ( 1 − e t e t ) alpha = frac{1}{2} ln(frac{1-e_t}{e_t}) α=21ln(et1et)

  1. 调整样本权重:

w t + 1 , i ← w t , i β t 1 − e t w i ← w i ∑ j = 1 n w j w_{t+1, i} leftarrow w_{t,i} eta_t^{1-e_t}\ w_i leftarrow frac{w_i}{sum^n_{j=1} w_j} wt+1,iwt,iβt1etwij=1nwjwi

  1. 再次运行,构造一个新的自举数据集。
  2. 重复以上过程,直到达到终止条件。
  3. 将弱学习器组合成一个集成模型。

Adaboost 算法广泛应用于二分类问题、多类单标签问题、多类多标签问题、大类单标签问题和回归问题。使用 Adaboost 算法构造 Haar 特征分类器,可以更好地选择矩形特征的组合,这些矩形特征的组合就构成了分类器,分类器以决策树的方式存储这些矩形特征组合。


4.2 级联分类器

级联分类器(Cascade Classifier)是多个 AdaBoost 强分类器的级联组合,可以使用较少的特征和简单的分类器更快更好的实现分类。检测图像中的被检窗口依次通过每一级分类器,通过全部各级分类器的检测区域就是目标区域。由于大部分候选区域在前几层的检测中就被排除了,因此算法的效率很高。

建立弱分类器

一个完整的弱分类器包含:Haar 特征 + leftValue + rightValue + 弱分类器阈值(threshold)。建立弱分类器的步骤如下:

  1. 对于每个特征 f,计算所有训练样本的特征值,并将其排序。

  2. 扫描一遍排好序的特征值,对排好序的表中的每个元素,计算下面四个值:

  • 全部人脸样本的权重的和 t1;
  • 全部非人脸样本的权重的和 t0;
  • 在此元素之前的人脸样本的权重的和 s1;
  • 在此元素之前的非人脸样本的权重的和s0;

选取当前元素特征值fi(x),和它前面的一个特征值fi-1(x)之间的值作为阈值,该阈值的分类误差为:

e = m i n [ ( S 1 + ( T 0 − S 0 ) ) , [ ( S 0 + ( T 1 − S 1 ) ) ] e = min{[(S_1 + (T_0 - S_0)), [(S_0 + (T_1 - S_1))]} e=min[(S1+(T0S0)),[(S0+(T1S1))]

通过把这个排序的表从头到尾扫描一遍可以为弱分类器选择使分类误差最小的阈值(即最优阈值)。

建立强分类器

强分类器是由多个弱分类器并联构成的。迭代建立强分类器的步骤如下如下:

  1. 给定训练样本集 S,共 N 个样本,其中 X 和 Y 分别对应于正样本和负样本,T 为训练的最大循环次数。

  2. 初始化样本权重为 1/N,即为训练样本的初始概率分布。

  3. 第一次迭代训练 N 个样本,得到第一个最优弱分类器。

  4. 提高上一轮中被误判的样本的权重。

  5. 将新的样本和上次本分错的样本放在一起进行新一轮的训练。

  6. 循环执行步骤 4-5,T 轮后得到 T 个最优弱分类器。

  7. 组合 T 个最优弱分类器得到强分类器,组合方式如下:

C ( x ) = { 1 , ∑ t = 1 T a t h t ( x ) ≥ 1 2 ∑ t = 1 T a t 0 , e l s e C(x) = egin{cases} 1 &, sum_{t=1}^T {a_th_t(x)} ge frac{1}{2} sum_{t=1}^T {a_t}\ 0 &, else\ end{cases} C(x)={10,t=1Tatht(x)21t=1Tat,else

这相当于让所有弱分类器投票,对投票结果按照弱分类器的错误率加权求和,再进行阈值比较得到最终的结果。

级联强分类器

级联分类器相当于一个决策树,通过各级检测器逐级排除,得到最终结果 。

将多个强分类器组织为筛选式的级联分类器,每级分类器排除一部分非人脸样本,只有通过所有各级分类器的检测窗口才是人脸区域。

筛选式级联分类器的策略是,将若干个强分类器由简单到复杂排列,通过训练使每个强分类器都有较高检测率,而对误识率的要求相对较低。部分被检测的区域可以很早被筛选掉,迅速判断该区域没有要求被检测的物体,可以显著地降低计算量。


4.3 Haar 级联分类器

基于 Haar 特征的级联分类器是 Paul Viola 在论文”Rapid Object Detection using a Boosted Cascade of Simple Features”中提出的一种目标检测方法。

Haar 级联分类器在每一级的节点中,使用 AdaBoost 算法学习一个高检测率低拒绝率的多层分类器。其特点是:

  1. 使用 Haar-like 输入特征,对矩形图像区域的和或者差进行阈值化。

  2. 使用积分图像计算 45°旋转区域的像素和,加速 Haar-like 输入特征的计算。

  3. 使用统计 Boosting 来创建二分类(人脸/非人脸)的分类器节点(高通过率,低拒绝率)。

  4. 将弱分类器并联组合起来,构成筛选式级联分类器。

在这里插入图片描述

各级的 Boosting 分类器对于有人脸的检测窗口都能通过,同时拒绝一小部分非人脸的检测窗口,并将通过的检测窗口传给下一个分类器。依次类推,最后一个分类器将几乎所有非人脸的检测窗口都拒绝掉,只剩下有人脸的检测窗口。因此,只要检测窗口区域通过了所有各级 Boosting 分类器,则认为检测窗口中有人脸。

在实际应用中输入图片的尺寸较大,需要进行多区域、多尺度的检测。多区域是要遍历图片的不同位置,多尺度是为了检测图片中不同大小的人脸。

在 Haar 级联分类人脸检测器中,主要利用了人脸的结构化特征:

  • 眼睛区域比脸部区域暗;

  • 鼻子区域比眼睛区域亮。

通过这 5 个矩形区域的明暗关系,就可以形成对人脸的各个部分的判别特征。Haar 人脸检测训练很高,但对侧脸的检测性能较差。


版权声明:

youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/130373695)
Copyright 2022 youcans, XUPT
欢迎关注 『youcans 的 OpenCV 学习课』 系列,持续更新

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。