总流程
描述子
描述子是从图片或者局部提取的有用特征.
一般来说, 特征描述子把widthxheightx3的图片转换为长度为n的向量. HOG中图片大小为64x128x3, 描述子长度为3780
计算得到的描述子经过SVM等的分类器可以进行二分类.
In the HOG feature descriptor, the distribution ( histograms ) of directions of gradients ( oriented gradients ) are used as features. Gradients (xand y derivatives ) of an image are useful because the magnitude of gradients is large around edges and corners ( regions of abrupt intensity changes ) and we know that edges and corners pack in a lot more information about object shape than flat regions.
计算
预处理
从图片中截出部分区域, 然后resize到64x128的图片, 但是也可以resize到1:2的比例, 比如100×200, 128×256, or 1000×2000 but not 101×205
文章作者还提到了用gamma correction, 但是效果没有提升太多. 所以这里不提了
计算梯度
HOG需要计算水平梯度和垂直梯度, 通过下面的滤波器卷积可以得到梯度结果. 同样可以用sobel算子计算 因为sobel算子可以分解为下面的向量相乘 梯度大小 梯度方向 下面图片显示的是梯度大小, 左边是x方向梯度, 中间是y方向梯度, 右边是帝都大小 可以看到, 梯度图片中, 大部分无用的信息已经被去掉了, 但是轮廓更加突出了, 还是很容易看出是一个人的轮廓
图片每一个像素都有一个梯度大小和梯度方向. 对于彩色图片来说, 这里的梯度大小等于三个通道中最大的梯度大小. 梯度方向是该大小对应的方向.
计算每个cell的梯度直方图
图片被分割成8x8的cell, 每个cell会得到一个梯度直方图.
每个cell里面一共有 8x8x2(大小,方向) = 128个梯度信息, 将这128个信息转换成一个9个取值的直方图, 可以让模型更加鲁棒.
这里选择8x8是因为在64x128的图片中, 可以提取到有用的信息, 例如头部, 手部之类的部分 右边8x8方向矩阵中, 使用的是0-180的角度(unsigned gradients) 接下来需要将所有的梯度大小, 整合到9个分段的直方图中 这里面, 80对应的大小是2, 所以在直方图80上面加入2, 而10对应的没有具体的区间值, 在于0-20中间,所以分成2给0, 2给20. 这里需要注意的是, 如果超出了160, 那么0相当于180, 梯度大小按照比例加入160和0的区间. 例如, 梯度为165, 与160相差5, 与180相差15, 所已经接近160. 160加入: 85x15/20=63.75, 0加入: 85x5/10=21.25 最后可以得到这样的一个直方图
直方图归一化
因为上面计算得到的直方图之间会因为局部像素强度大小差异而较大的差异, 所以需要对所有的网格进行归一化 这里的做法是遍历图片得到相互之间有2个8x8 cell重合的16x16的网格, 对上面的4个直方图进行归一化. 具体将4个9x1的向量, 转化成36x1的向量, 然后求L2 norm.
计算HOG特征向量
上面得到的36x1向量会合并成一个更大的向量, 具体实现如下:
首先上面我们得到了(64/8 -1)x(128/8 - 1) = 7x15 = 105个16x16的网格. 每个网格对应一个36x1的向量, 所以当我们合并所有的向量, 我们可以得到一个36x105 = 3780维度的向量
可视化
HOG描述子一般可视化是画出每一个8x8的方格子中对应的9x1归一化后的向量.
Reference
- http://vision.stanford.edu/teaching/cs231b_spring1213/slides/HOG_2011_Stanford.pdf
- https://www.youtube.com/watch?v=7S5qXET179I
- https://www.learnopencv.com/histogram-of-oriented-gradients/