OpenCV16:Hog特征

 Hog特征

什么是Hog特征?Hog特征属于特征的一种,因此也是一种计算结果。我们在【OpenCV14:Haar特征】中可以知道,Haar特征是由模板计算出来的结果,Hog特征与其不同的是,其在经过模板计算时更复杂,还需要进一步的运算。

首先陈述一下如何计算Hog特征:

1、模块划分        

OpenCV16:Hog特征
图1

 

如上图所示,白色底板作为一张image,可以看出其关系:image > win > block > cell 

在block 和win 的滑动中,有step(步长);在cell 中,有bin

            win:一般win 是特征计算的最顶层单元,比如在做行人检测或车辆检测时,一个win框应能够覆盖整个目标(obj)的全部信息。另外,win的大小是任意的,但一般推荐使用64*128
           block:一个win含有若干个block,一般来讲win的宽高是block的整数倍  ,若win为64*128,则block为16*16。block位于win中,因而block需要对win进行从上到下,从左到右的遍历,所以,它存在step(步长),推荐使用大小8*8。

           则在计算block时,就有如下式子:count = ((64 - 16)* 8  + 1)* ((128 - 16)* 8 +1)= 105 

           cell:一般推荐8*8 ,那么一个block中需要多少cell?从上面的图1中可以看出,cell与block不同,cell是并列不可重叠的。就表明cell不可滑动,所以一个16*16的block中有4个8*8的cell。

           bin:每个像素都有梯度的存在,梯度有两个属性:大小、方向。bin与梯度的方向有关。对于方向,其范围是0 - 360° ,以40°为单位,我们可以将其分为9块,每一块就是一个单元称为bin。 即 ,一个bin = 40°。

           那么,cell与bin什么关系呢?一个cell需要完整包含360°的信息,因而cell包含9个bin的信息即可。

Hog特征的维度:与Haar特征结果是得到一个值不同,Hog特征得到的是一个向量,它存在维度属性。因为Hog特征是要描述目标的所有信息,所以,维度必须要等于窗体中的某个数。

因而,维度 = 窗体中所有block个数 * 每个block中cell的个数 * 每个cell中bin的数量。那么按照上面的推荐值,即为 维度 =105 * 4 * 9 = 3780

 

2、根据Hog特征模板计算梯度和方向

前提:计算单位为像素。每个像素都有一个梯度,win中所有像素的梯度构成了Hog特征。

Hog特征的模板与Haar特征模板类似,但是只有水平  OpenCV16:Hog特征 和竖直  OpenCV16:Hog特征 两种。

对于水平方向的模板的卷积计算:a = 1*p1 + 0*p2  + (-1)*p3 = 相邻元素之差

对于竖直方向的模板的卷积计算:b = 1*p1 + 0*p2  + (-1)*p3 = 上下元素之差

那么梯度的幅值 = OpenCV16:Hog特征

梯度的方向(角度) = arctan(a / b)

3、根据梯度和方向进行bin投影

 我们将 0 - 360° 的范围分为了9块bin,每块bin的大小是40°,但这40°是以20°分开的。比如:一块bin(记为bin_01)一部分是0-20°,那么另一部分就是180°-200°    。

对于某一个像素 [i, j] 来说,设它的梯度幅值为 f 。

若方向(角度)a = 10°,由于 0 < 10 < 20,所以投影至bin_01中,而且,a=10°恰好为角的中线,所以此时它在bin上的投影就为 f 。

若方向(角度)a 不为中线时,则将其分解到两个bin中,假设为bin_01和bin_02。简单介绍一下分解公式:

f_01 = f * F(夹角) ,f_02 = f * (1 - F(夹角) ),其中F(夹角)是个函数,它的取值范围是 0 - 1.0 

4、每个模块的Hog特征

整体Hog特征的计算:上面举的例子中,一个窗体中有3780个维度(由上面维度公式可知,这意味着由3780个bin),我们挑出其中一个详细讲解。

一个block中由4个cell,一个cell又可以分成9个bin。因此,我们有如下定义:

cell_0、cell_1、cell_2、cell_3;bin_0、bin_1、bin_2、bin_3、bin_4、bin_5、bin_6、bin_7、bin_8;

则cell_0:bin_0、。。。、bin_8;

cell_1:bin_0、。。。、bin_8;

cell_2:bin_0、。。。、bin_8;

cell_3:bin_0、。。。、bin_8;

 假设第一个像素 [i, j] ,角度投影在了某一cell的bin_0上,那么这个像素的bin_0的内容就变成了 f_0。 

第二个像素 [i+1, j],角度也投影在了某一cell的bin_0上,那么这个像素的bin_0的内容就变成了 f_1。

则遍历cell_0完之后,权重累加,bin_0 = sum( f_0 + f_1 + ... + f_n),此时的bin_0为cell_0下的值。需要注意的是,当某个像素被分解至两个bin时,累加时也要计算上另一个bin的值。例如,如果 [i, j] 被分解到 bin_0 和 bin_1 那么,计算bin_0的sum()时,要加上分解的那个bin_1的值。

cell 复用:

在一个block中存在4个cell,一般来说,他们是并列排序,分别是 [cell_0]、 [cell_1]、 [cell_2]、 [cell_3]

 cell_0 对应自己的 bin_0 — bin_8

在进行计算时,还有另一个维度的划分,将其分为:cellx0、cellx2、cellx4

cellx0中某一像素 [i, j],计算出来的bin,只对当前的cellx0起作用。

cellx2中某一像素 [i, j],对应两个cell,需要计算这两个cell上的bin值。

同理,cellx4对应四个cell。

如何进行Hog特征的判决?

这就涉及到SVM的知识

用Hog * SVM(与Hog特征数相同的线性向量) = 值,若值 > 判决门槛T,则判定为目标,反之则不是目标。