OpenCV16:Hog特征
Hog特征
什么是Hog特征?Hog特征属于特征的一种,因此也是一种计算结果。我们在【OpenCV14:Haar特征】中可以知道,Haar特征是由模板计算出来的结果,Hog特征与其不同的是,其在经过模板计算时更复杂,还需要进一步的运算。
首先陈述一下如何计算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特征模板类似,但是只有水平 和竖直
两种。
对于水平方向的模板的卷积计算:a = 1*p1 + 0*p2 + (-1)*p3 = 相邻元素之差
对于竖直方向的模板的卷积计算:b = 1*p1 + 0*p2 + (-1)*p3 = 上下元素之差
那么梯度的幅值 =
梯度的方向(角度) = 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,则判定为目标,反之则不是目标。