深度学习入门 | HOG梯度直方图特征

HOG特征

Histogram of Oriented Gradients 直译过来就是向量梯度直方图,用来记录边缘特征,包括梯度值和梯度方向

1. 数据预处理

输入的图片像素维度可以是任意的,但是识别的一个个小模块一般都是有长宽1:2限制的,可以是100×200, 128×256,或1000×2000。如下图所示,整张图片大小是720×475,框出来的模块是100×200, 我们把它等比放缩到64×128。

在这里插入图片描述预处理还有包括伽马校正和灰度化。这是可选的步骤,因为实验证明做不做影响不大。伽马校正是减少光度对实验的影响。灰度化是将彩色图片变成灰度图。其实彩色图片也可以直接处理。不过是分别对三通道的颜色值进行梯度计算,最后选择梯度最大的那个。

当然也可以不选择进行灰度处理。

2. 计算梯度大小和方向
  • 若进行灰度处理,求梯度大小和方向

对于像素点A,要计算水平梯度和竖直梯度,如上图,水平梯度 g x = 30 − 20 = 10 g_x=30-20=10 gx=3020=10,竖直梯度 g y = 64 − 32 = 32 g_y =64-32=32 gy=6432=32.

那么总的梯度强度值g和梯度方向将按照以下公式计算:
g = g x 2 + g y 2 g=\sqrt{g^2_x+g^2_y} g=gx2+gy2

θ = a r c t a n g y g x \theta=arctan\frac{g_y}{g_x} θ=arctangxgy
梯度方向将会取绝对值,因此梯度方向的范围是0-180度。取绝对值的原因是变为0-180区间,不用0-360是实验过程中前者效果更好,有些程序HOG特征也可以取0-360。

  • 若不进行灰度处理

为了计算HOG描述符,我们需要首先计算水平和垂直梯度;毕竟,我们想要计算梯度的直方图。这很容易通过下面的核函数来过滤图像。

在这里插入图片描述通过在内核大小为1的OpenCV中使用Sobel算子,我们也可以得到同样的结果。代码如下

# Read image
im = cv2.imread('bolt.png')
im = np.float32(im) / 255.0

# Calculate gradient
gx = cv2.Sobel(img, cv2.CV_32F, 1, 0, ksize=1)
gy = cv2.Sobel(img, cv2.CV_32F, 0, 1, ksize=1)

对于彩色图像,计算三个通道的梯度。像素处的梯度幅值为三个通道的梯度幅值的最大值,角度为最大梯度对应的角度

返回结果如下,左边是x方向上的梯度,中间图是y方向上的,而右图是这两个方向叠加的也就是 g = g x 2 + g y 2 g=\sqrt{g^2_x+g^2_y} g=gx2+gy2
在这里插入图片描述梯度图像删除了很多不必要的信息(如固定的彩色背景),但保留了轮廓。在梯度图像里,你依然可以清楚的看到有一个人在图片中。

中间的图中的箭头方向指的就是梯度方向(注意这里还是0-360°),箭头长度代表梯度大小,最右边的图就是计算得到的数值。
3. 计算8×8cells的梯度直方图

我们划分为8×8的cells,我们来计算下里面包含的数,本来8×8的cells里面有8x8x3 = 192个像素值,然后每个像素值可以计算出两个值(梯度大小和方向),加起来是8x8x2 = 128个数。

但是为什么8×8 patch ?为什么不32×32 ?对于行人检测来说,将一个行人的照片中的8×8细胞按比例放大到64×128,其大小足以捕捉到有趣的特征(如脸部、头顶等),就是说8×8可以比较好的保留脸部特征,而32×32划分太小了,容易造成最后的特征数据量过大。

接着,我们需要把计算得到的8×8梯度大小和方向矩阵,整合在一起成1×9的一个新变量。我们根据梯度方向(0-180°)分为9个bin,分别是0、20…、160,接着对应统计梯度大小累计值。

具体来说,我们看蓝色的圈圈,这个像素梯度方向是80,大小为2,那我们就把大小2填到80的格子中去,再看两个红色圈圈。因为红色圈圈的方向是10,大小是4,因为10距离0点为10,距离20点为也为10,那么有一半的大小是投给0这个bin,还有一半的大小(即是2)投给20这个bin。如下图所示
在这里插入图片描述还有一个细节需要注意。如果这个角大于160度,它在160和180之间,我们知道这个角等于0和180度。所以在下面的例子中,165度角的像素对0度和160度角的贡献度是成比例的。
在这里插入图片描述

统计完8×8cells里面64个点的投票数以后,每个bin就会得到一个数值,可以得到一个直方图,在计算机里面就是一个大小为9的数组。

4. 16×16 Block Normalization即block归一化

为了减少亮度带来的影响,比如说你通过将所有像素值除以2来使图像变暗,渐变幅度将改变一半,因此你梯度值和梯度大小这些都会少一半,我们就采取归一化的手段,就是同时除以模长,例如(1,1,1,1)归一化就是(0.25,0.25,0.25,0.25)。

现在我们知道了如何归一化向量,你可能会想,在计算HOG时,可以简单地直接除以模长来归一化9×1直方图。但是一个更好是对一个更大的16×16块进行标准化。

具体来说,我们用2×2的大方块扫过整张图,每个绿色小方块实际上是8*8大小的cell,所以蓝色方块就是由4个cell组成的block,也就是16×16大小的cell。而之前我们把8×8的拿出来计算再整合得到了9×1,那么16×16大小的cell得到的就是36×1向量,我们把这个进行归一化。然后将窗口移动8个像素(参见动画),并在此窗口上计算一个归一化的36×1向量,然后重复这个过程。

5. 得到HOG特征向量,计算维度

一个64×128的图片部分,8×8像素值划分,水平位置8个,竖直位置16个绿色小方块,每个绿色小方块包含8×8个像素值。接着16×16像素值划分,有7个水平位置和15个垂直蓝色小方块,总共7 × 15 = 105个蓝色小方块,每个蓝色小方块最后生成36×1维向量,因此最后我们得到一个36×105 = 3780维的向量。

可视化HOG

图像的HOG描述符通常通过在8×8cell中绘制9×1标准化直方图来可视化,每个绿色小方块我们刚才都得到了9×1的向量,然后这个向量根据数值可以画出直方图,我们再把直方图放上去。你会注意到直方图的主要方向捕捉了人的形状,特别是躯干和腿部周围。
在这里插入图片描述

参考:
https://learnopencv.com/histogram-of-oriented-gradients/
https://zhuanlan.zhihu.com/p/40960756 (知乎)

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值