方向性梯度直方图 (HOG)详解
一、HOG特征描述符
特征描述符就是通过提取图像的有用信息,并且丢弃无关信息来简化图像的表示。
HOG特征描述符可以将3通道的彩色图像转换成一定长度的特征向量。
在HOG特征描述符中,梯度方向的分布,也就是梯度方向的直方图被视作特征。
图像的梯度(x和y导数)非常有用,因为边缘和拐角(强度突变的区域)周围的梯度幅度很大,并且边缘和拐角比平坦区域包含更多关于物体形状的信息。
举例:
图1:
图2:
图1 有包含很多信息,比如物体的形状、颜色、边缘、背景等。而图2 的信息相对少得多(只有形状和边缘),但足以区分两个图像。
特征描述符的作用:它是图像的简化表示,仅包含有关图像的最重要信息。
最受欢迎特征描述符的:
HOG:Histogram of Oriented Gradients
SIFT:Scale Invariant Feature Transform
SURF:Speeded-Up Robust Feature
二、 计算 HOG 的过程(HOG STEPS)
- 图像预处理
预处理数据是机器学习项目中的关键步骤,处理图像时也不例外。
①首先将图像进行剪裁并缩放到固定尺寸(64×128 )
②灰度图像和彩色图像都可以用于计算梯度图,对于彩色图像,先对三通道颜色值分别计算梯度,然后取梯度值最大的那个作为该像素的梯度。
③伽马矫正,调节图像对比度,减少光照对图像的影响(包括光照不均和局部阴影),使过曝或者欠曝的图像恢复正常,更接近人眼看到的图像。
伽马矫正(Gamma Normalization)
公式:
其中H(x,y)表示像素点(x,y)的像素值。实验证明,对每个颜色通道进行平方根gamma压缩(即gamma参数为0.5)时有较高的性能提升。 - 计算梯度图
为了得到梯度直方图,那么首先需要计算水平和垂直梯度,这可以通过使用以下内核过滤图像来实现,分别用于计算水平梯度和垂直梯度。
我们可以使用内核大小为1的Sobel算子,来获得相同的结果。
然后再计算x和y方向梯度的合梯度,包括幅值和方向
注意:梯度方向会取绝对值,因此得到的角度范围是 [0,180°]。
如下分别为x方向梯度图,y方向梯度图,梯度幅值图,梯度方向图:
在每个像素处,梯度有一个大小和一个方向。x方向梯度图会强化垂直边缘特征,y方向梯度图会强化水平边缘特征。这就使得有用的特征(轮廓)得到保留,无关不重要的信息被去除。
3. 计算 8×8 单元格中梯度的直方图
首先明确几个概念的区别Block、Cell和Bin
每个Block包含2x2个8x8的Cell
Bin
把180°分成9个部分称为9个Bin
在这一步,我们先把整个图像划分为若干个8x8的小单元,称为cell,并计算每个cell的梯度直方图。这个cell的尺寸也可以是其他值,根据具体的特征而定。
为什么我们要把图像分成若干个8x8的小单元?
这是因为对于一整张梯度图,其中的有效特征是非常稀疏的,不但运算量大,而且效果可能还不好。于是我们就使用特征描述符来表示一个更紧凑的特征。一个8x8的小单元就包含了8x8x2 = 128个值,因为每个像素包括梯度的大小和方向。
现在我们要把这个8x8的小单元用长度为9的数组来表示,这个数组就是梯度直方图。这种表示方法不仅使得特征更加紧凑,而且对单个像素值的变化不敏感,也就是能够抗噪声干扰。
我们来看一下图片中的一个cell中的梯度:
以博尔特头顶的8*8像素大小的cell为例,通过前两步的计算可以得到每个像素的梯度幅值和梯度方向。
接下来在8×8的cell中创建一个9-bins的直方图。在蓝色圈所在像素的梯度方向是80度,幅值为2,所以在bin为80的格子里面加2。在红色圈所在像素的梯度方向为10度,幅值为4,但是bin中没有10这个值,只有0和20,所以把4平均分配到bin为0和20的格子中。
还有一点需要注意到的如果某个像素的方向超过了160,由于直方图是首尾相连的(即180就是0),因此我们把像素值按比例(根据像素的角度距离边界远近)分配到0和160的格子中,如下图。
通过对cell中所有像素点进行统计得到以下方向梯度直方图。
4. block归化
HOG将8×8的一个区域作为一个cell,再以2×2个cell作为一组,称为block。由于每个cell有9个值,2×2个cell则有36个值,HOG是通过滑动窗口的方式来得到block的,如下图所示:
在前面的步骤中,我们基于图像的梯度对每个cell创建了一个直方图。
但是图像的梯度对整体光照非常敏感,比如通过将所有像素值除以2来使图像变暗,那么梯度幅值将减小一半,因此直方图中的值也将减小一半。这意味着对于特定图片,图像的某些部分与其他部分相比会非常亮。我们无法从图像中完全消除这一点。但是我们可以通过采用 16×16 块对梯度进行归一化来减少这种光照变化。 理想情况下,我们希望我们的特征描述符不会受到光照变化的影响,那么我们就需要将直方图“归一化” 。
在说明如何归一化直方图之前,先看看长度为3的向量是如何归一化的。
假设我们有一个向量 [128,64,32],向量的长度为
这叫做向量的L2范数。将这个向量的每个元素除以146.64就得到了归一化向量 [0.87, 0.43, 0.22]。
现在有一个新向量,是第一个向量的2倍 [128x2, 64x2, 32x2],也就是 [256, 128, 64],我们将这个向量进行归一化,你可以看到归一化后的结果与第一个向量归一化后的结果相同。所以,对向量进行归一化可以消除整体光照的影响。
知道了如何归一化,现在来对block的梯度直方图进行归一化(注意不是cell),一个block有4个直方图,将这4个直方图拼接成长度为36的向量,然后对这个向量进行归一化。
因为使用的是滑动窗口,滑动步长为8个像素,所以每滑动一次,就在这个窗口上进行归一化计算得到长度为36的向量,并重复这个过程。
5. 计算HOG特征向量
每滑动一次,一个block就得到一个长度为36的特征向量,那会得到多少个特征向量呢?
比如上面这个图,将整幅图像划分成cell的个数为8x16,就是横向有8个cell,纵向有16个cell。每个block有2x2个cell的话,那么cell的个数为:(16-1)x(8-1)=105。即有7个水平block和15个竖直block。
再将这105个block合并,就得到了整个图像的特征描述符,长度为 105×36=3780。