Haar特征、积分图、Adaboost算法、分类器训练

一、Haar-like特征

Haar特征值反映了图像分度变化的情况。

Haar-like特征最早是由Papageorgiou等应用于人脸表示,Viola和Jones在此基础上,使用3种类型4种形式的特征。

Haar特征分为三类:边缘特征、线性特征、中心特征和对角线特征,组合成特征模板。特征模板内有白色和黑色两种矩形,并定义该模板的特征值为白色矩形像素和减去黑色矩形像素和。Haar特征值反映了图像的灰度变化情况。例如:脸部的一些特征能由矩形特征简单的描述,如:眼睛要比脸颊颜色要深,鼻梁两侧比鼻梁颜色要深,嘴巴比周围颜色要深等。但矩形特征只对一些简单的图形结构,如边缘、线段较敏感,所以只能描述特定走向(水平、垂直、对角)的结构。


对于图中的A, B和D这类特征,特征数值计算公式为:v=Sum白-Sum黑,而对于C来说,计算公式如下:v=Sum白-2*Sum黑;之所以将黑色区域像素和乘以2,是为了使两种矩形区域中像素数目一致。

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

矩形特征可位于图像任意位置,大小也可以任意改变,所以矩形特征值是矩形模版类别、矩形位置和矩形大小这三个因素的函数。故类别、大小和位置的变化,使得很小的检测窗口含有非常多的矩形特征,如:在24*24像素大小的检测窗口内矩形特征数量可以达到16万个。这样就有两个问题需要解决了:

(1)如何快速计算那么多的特征?---积分图大显神通;

(2)哪些矩形特征才是对分类器分类最有效的?---如通过AdaBoost算法来训练

二、Haar-like特征的计算—积分图

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

积分图主要的思想是将图像从起点开始到各个点所形成的矩形区域像素之和作为一个数组的元素保存在内存中,当要计算某个区域的像素和时可以直接索引数组的元素,不用重新计算这个区域的像素和,从而加快了计算(这有个相应的称呼,叫做动态规划算法)。积分图能够在多种尺度下,使用相同的时间(常数时间)来计算不同的特征,因此大大提高了检测速度。

积分图是一种能够描述全局信息的矩阵表示方法。积分图的构造方式是位置(i,j)处的值ii(i,j)是原图像(i,j)左上角方向所有像素的和:


1、积分图的构建方法

1)用s(i,j)表示行方向的累加和,初始化s(i,-1)=0;

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

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

s(i,j)=s(i,j-1)+f(i,j)

ii(i,j)=ii(i-1,j)+s(i,j)

4)扫描图像一遍,当到达图像右下角像素时,积分图像ii就构造好了。

积分图构造好之后,图像中任何矩阵区域的像素累加和都可以通过简单运算得到如图所示:


一个区域的像素值,可以利用该区域端点的积分图计算,如上图所示,ii(1)表示区域A的像素值,ii(2)表示区域A+B的像素值,ii(3)表示区域A+C的像素值,ii(4)表示区域A+B+C+D的像素值。而区域D的像素值=ii(4)+ii(1)-ii(2)-ii(3),由此,可用积分图快速得到一个区域的像素值之和。

而Haar-like特征值无非就是两个矩阵像素和的差,同样可以在常数时间内完成。所以矩形特征的特征值计算,只与此特征矩形的端点的积分图有关,所以不管此特征矩形的尺度变换如何,特征值的计算所消耗的时间都是常量。这样只要遍历图像一次,就可以求得所有子窗口的特征值。

2、计算特征值

       以“两矩形特征”中的第二个特征为例,如下图,使用积分图计算其特征值:


该矩形特征的特征值,由定义,为区域A的像素值之和减去区域B的像素值之和。

区域A的像素值之和=ii(5)+ii(1)-ii(2)-ii(4)

区域B的像素值之和=ii(6)+ii(2)-ii(5)-ii(3)

则该矩型的特征值=ii(5)+ii(1)-ii(2)-ii(4)-[ ii(6)+ii(2)-ii(5)-ii(3)]

                                     =[ii(5)-ii(4)]+[ii(3)-ii(2)]-[ii(2)-ii(1)]-[ii(6)-ii(5)]

所以,矩形特征的特征值,只与特征矩形的端点的积分图有关,而与图像的坐标无关。通过计算特征矩形的端点的积分图,在进行简单的加减运算,就可以得到特征值。正因为如此,特征的计算速度大大提高,也提高了目标的检测速度。

三、Adaboost算法

AdaBoost 是一种迭代算法,其核心思想是针对同一个训练集训练不同的分类器,即弱分类器,然后把这些弱分类器集合起来,构造一个更强的最终分类器。算法本身是改变数据分布实现的,它根据每次训练集之中的每个样本的分类是否正确,以及上次的总体分类的准确率,来确定每个样本的权值。将修改权值的新数据送给下层分类器进行训练,然后将每次训练得到的分类器融合起来,作为最后的决策分类器。

1、Adaboost算法过程


这就是Adaboost的结构,最后的分类器YM是由数个弱分类器(weak classifier)组合而成的,相当于最后m个弱分类器来投票决定分类,而且每个弱分类器的话语权”α不一样。

算法的具体过程

给定样本集:,其中

标记集合

(1)  初始化所有训练样例的权重分布。每个训练样本最开始时都被赋予相同的权重,即其中M为样例数

(2)  进行多伦迭代,For m = 1,……M

a).使用具有权值分布的训练数据集学习得弱分类器,计算在训练数据集上的分类误差率,最小化权重误差函数(weighted error function):


有上式可知,在训练数据集上的误差率就是被误分类样本的权值之和。

b).计算的系数,接下来计算该弱分类器的话语权,表示在最终分类器中的重要程度(目的,得到弱分类器在最终分类器中所占的权重)

由上式可知,时,随着的减小而增大,意味着分类误差率越小的弱分类器在最终分类器中的作用越大。

c)更新训练数据集的权值分布(目的:获得样本新的权值分布),用于下一轮迭代

(3)组合各个弱分类器,如下:


从而得到最终分类器,如下:


2Adaboost的一个例子

下面,给定下列训练样本,请用AdaBoost算法学习一个强分类器。


求解过程:初始化训练数据的权值分布,令每个权值,其中,M = 10i = 1,2, ..., 10,然后分别对于m = 1,2,3, ...等值进行迭代.

拿到这10个数据的训练样本后,根据 X Y 的对应关系,要把这10个数据分为两类,一类是“1”,一类是“-1”,根据数据的特点发现:“0 1 2”3个数据对应的类是“1”“3 4 5”3个数据对应的类是“-1”“6 7 8”3个数据对应的类是“1”9是比较孤独的,对应类“-1”。抛开孤独的9不讲,“0 1 2”“3 4 5”“6 7 8”这是3类不同的数据,分别对应的类是1-11,直观上推测可知,可以找到对应的数据分界点,比如2.55.58.5 将那几类数据分成两类。当然,这只是主观臆测,下面实际计算下这个过程。

    迭代过程1

对于m=1,在权值分布为10个数据,每个数据的权值皆初始化为0.1)的训练数据上,经过计算可得:

阈值v2.5时误差率为0.3x < 2.5时取1x > 2.5时取-1,则6 7 8分错,误差率为0.3),阈值v5.5时误差率最低为0.4x < 5.5时取1x > 5.5时取-1,则3 4 5 6 7 8皆分错,误差率0.6大于0.5,不可取。故令x > 5.5时取1x < 5.5时取-1,则0 1 2 9分错,误差率为0.4),阈值v8.5时误差率为0.3x < 8.5时取1x > 8.5时取-1,则3 4 5分错,误差率为0.3)。所以无论阈值v2.5,还是8.5,总得分错3个样本,故可任取其中任意一个如2.5,弄成第一个基本分类器为:


上面说阈值v2.5时则6 7 8分错,所以误差率为0.3,更加详细的解释是:因为样本集中0 1 2对应的类(Y)是1,因它们本身都小于2.5,所以被分在了相应的类“1”中,分对了。3 4 5本身对应的类(Y)是-1,因它们本身都大于2.5,所以被分在了相应的类“-1”中,分对了。但6 7 8本身对应类(Y)是1,却因它们本身大于2.5而被分在了类"-1"中,所以这3个样本被分错了。9本身对应的类(Y)是-1,因它本身大于2.5,所以被分在了相应的类“-1”中,分对了。从而得到在训练数据集上的误差率(被误分类样本“6 7 8”的权值之和)。然后根据误差率计算的系数


这个代表在最终的分类函数中所占的权重,为0.4236。接着更新训练数据的权值分布,用于下一轮迭代:


值得一提的是,由权值更新的公式可知,每个样本的新权值是变大还是变小,取决于它是被分错还是被分正确。即如果某个样本被分错了,则为负,负负等正,结果使得整个式子变大(样本权值变大),否则变小。第一轮迭代后,最后得到各个数据新的权值分布= (0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.1666,0.1666, 0.1666, 0.0715)。由此可以看出,因为样本中是数据“6 7 8”分错了,所以它们的权值由之前的0.1增大到0.1666,反之,其它数据皆被分正确,所以它们的权值皆由之前的0.1减小到0.0715

分类函数。此时,得到的第一个弱分类器在训练数据集上有3个误分类点(即6 7 8)。

    从上述第一轮的整个迭代过程可以看出:被误分类样本的权值之和影响误差率,误差率影响基本分类器在最终分类器中所占的权重。

    迭代过程2

对于m=2,在权值分布为= (0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.1666, 0.1666, 0.1666, 0.0715)的训练数据上,经过计算可得:

阈值v2.5时误差率为0.1666*3x < 2.5时取1x > 2.5时取-1,则6 7 8分错,误差率为0.1666*3),阈值v5.5时误差率最低为0.0715*4x > 5.5时取1x < 5.5时取-1,则0 1 2 9分错,误差率为0.0715*3 + 0.0715),阈值v8.5时误差率为0.0715*3x < 8.5时取1x > 8.5时取-1,则3 4 5分错,误差率为0.0715*3)。所以,阈值v8.5时误差率最低,故第二个基本分类器为:

面对的还是下述样本:


很明显,把样本“3 4 5”分错了,根据可知它们的权值为0.0715, 0.0715, 0.0715,所以在训练数据集上的误差率0.2143

计算的系数:


更新训练数据的权值分布:

 = (0.0455, 0.0455, 0.0455, 0.1667, 0.1667, 0.01667, 0.1060, 0.1060, 0.1060, 0.0455)。被分错的样本“3 4 5”的权值变大,其它被分对的样本的权值变小.,此时,得到的第二个弱分类器在训练数据集上有3个误分类点(即3 4 5)。

    迭代过程3

对于m=3,在权值分布为= (0.0455, 0.0455, 0.0455, 0.1667, 0.1667, 0.01667,0.1060, 0.1060, 0.1060, 0.0455)的训练数据上,经过计算可得:

阈值v2.5时误差率为0.1060*3x < 2.5时取1x > 2.5时取-1,则6 7 8分错,误差率为0.1060*3),

阈值v5.5时误差率最低为0.0455*4x > 5.5时取1x < 5.5时取-1,则0 1 2 9分错,误差率为0.0455*3 + 0.0715),

阈值v8.5时误差率为0.1667*3x < 8.5时取1x > 8.5时取-1,则3 4 5分错,误差率为0.1667*3)。所以阈值v5.5时误差率最低,故第三个基本分类器为:


依然还是原样本:


此时,被误分类的样本是:0 1 2 9,这4个样本所对应的权值皆为0.0455,所以在训练数据集上的误差率。计算的系数:


更新训练数据的权值分布:

=(0.125, 0.125, 0.125, 0.102, 0.102, 0.102, 0.065, 0.065,0.065, 0.125)。被分错的样本“0 1 2 9”的权值变大,其它被分对的样本的权值变小。


此时,得到的第三个基本分类器在训练数据集上有0个误分类点。至此,整个训练过程结束。,将上面计算得到的各值代入中,得到最终的分类器为:

3Adaboost优点

1)Adaboost是一种有很高精度的分类器

2)可以使用各种方法构建子分类器,Adaboost算法提供的是框架

3)当使用简单分类器时,计算出的结果是可以理解的,而且弱分类器的构造及其简单

4)简单,不用做特征筛选

5)不用担心overfitting
















你可能感兴趣的:(opencv,adaboost,haar)