基于方向梯度直方图(HOG)的人脸检测

基于方向梯度直方图(HOG)的人脸检测

论文:Histograms of Oriented Gradients for Human Detection, CVPR 2005

惯例,分享歌词一句:

《化鹤归》
醉举杯饮星河 人间胜事且勾勒
来日悠长 此间你我 终能把 岁月雕琢

每个像素点的梯度计算公式:

  • Gx(x,y)=H(x+1,y)H(x1,y) G x ( x , y ) = H ( x + 1 , y ) − H ( x − 1 , y )
  • Gy(x,y)=H(x,y+1)H(x,y1) G y ( x , y ) = H ( x , y + 1 ) − H ( x , y − 1 )
  • 幅度: G(x,y)=Gx(x,y)2+Gy(x,y)2 G ( x , y ) = G x ( x , y ) 2 + G y ( x , y ) 2
  • 方向: α(x,y)=tan1Gx(x,y)Gy(x,y) α ( x , y ) = t a n − 1 G x ( x , y ) G y ( x , y )

算法流程

这里写图片描述
基于方向梯度直方图(HOG)的人脸检测_第1张图片
1. 归一化图像包括先灰度化然后标准化Gamma空间来减小光照因素的影响,Gamma压缩公式为: I(x,y)=I(x,y)gammma I ( x , y ) = I ( x , y ) g a m m m a ,比如gamma可以取0.2
2. 计算每一个像素的梯度
3. 以 88 8 ∗ 8 个像素单元为最小结构单元cell,计算0~360度方向上的权重投影,后面介绍一个计算的例子,将
360划分为9个区间,按照每个像素梯度的幅度给梯度方向的所在区间赋值。最后每个cell形成一个 91 9 ∗ 1 的向量

  1. 将4个cell组成一个block( 1616 16 ∗ 16 ),在这注意,每个cell会被不同的block共享,来通过对重叠cell的归一
    化,消除局部光照的变化以及前景-背景对比度的变化。这样最后每个block会形成 161 16 ∗ 1 的向量
  2. 最后将目标的所有block向量串联形成该目标的特征向量。假设目标窗口为 64128 64 ∗ 128 , 则最后的特征向量
    长度为 (4816(1)=5121 ( 4 ∗ 8 ∗ 16 ) ∗ ( 1 ) = 512 ∗ 1 。注意第4步中由于cell的共享问题导致最后一个cell会以不同的结果
    出现在最后的特征值中。
  3. 利用得到的(特征向量, 目标)制成训练集,来训练SVM等分类器
  4. 从图像上确定检测窗比如64*128,重复以上步骤,将得到的特征向量送给训练好的分类器来检测人脸

cell中权重投影,即 91 9 ∗ 1 向量的计算实例

梯度对于图像影响的例子

注意:图像的原点是图片的左上角,x轴是水平的,y轴是垂直的
基于方向梯度直方图(HOG)的人脸检测_第2张图片

从上面的图像中可以看到x轴方向的梯度主要凸显了垂直方向的线条,y轴方向的梯度凸显了水平方向的梯度,梯度幅值凸显了像素值有剧烈变化的地方。

cell权重投影计算

  1. 在每个像素点,都有一个幅值(magnitude)和方向,对于有颜色的图片,会在三个channel上都计算梯度。那么相应的幅值就是三个channel上最大的幅值,角度(方向)是最大幅值所对应的角。
  2. 分割cell 在这一步,选取的 64128 64 ∗ 128 的检测窗口会被分割成 88 8 ∗ 8 大小的网格每个网格都会计算一个梯度直方图。每个像素有两个值(幅值magnitude,三个channel取最大的magnitude和方向direction,),加起来就是 882=128 8 ∗ 8 ∗ 2 = 128 ,然后将这128个数用一个9个条目的直方图来表示成9个数的数组。用直方图来表示一个patch更加抗噪,一个gradient可能会有噪音,但是用直方图来表示后就不会对噪音那么敏感了。

基于方向梯度直方图(HOG)的人脸检测_第3张图片

  1. 计算cell中每个元素的梯度(方向和幅值)

基于方向梯度直方图(HOG)的人脸检测_第4张图片

中间: 一个网格用箭头表示梯度 右边: 这个网格用数字表示的梯度
中间这个图的箭头是梯度的方向,长度是梯度的大小,可以发现箭头的指向方向是像素强度都变化方向,幅值
是强度变化的大小。

注意,**右边的梯度方向矩阵中可以看到角度是0-180度,不是0-360度,这种被称之
为”无符号”梯度(“unsigned” gradients)因为一个梯度和它的负数是用同一个数字表示的,也就是说一个梯度
的箭头以及它旋转180度之后的箭头方向被认为是一样的。那为什么不用0-360度的表示呢?在实践中发现在
某些检测任务中,unsigned gradients比signed gradients效果更好。一些HOG的实现中可以让你指定
signed gradients。**
4. 为 88 8 ∗ 8 的网格创建直方图,直方图包含了9个bin来对应0,20,40,…160这些角度。 bin 就是 认为直方图中每
一个数据条目.

基于方向梯度直方图(HOG)的人脸检测_第5张图片
上面这张图解释了这个过程。我们用了上一张图里面的那个网格的梯度幅值和方向。根据方向选择用哪个bin,
根据幅值来确定这个bin的大小。先来看蓝色圈圈出来的像素点,它的角度是80,幅值是2,所以它在第五个bin
里面加了2,再来看红色的圈圈出来的像素点,它的角度是 10 10 。 ,幅值是4,刚好介于 020 0 。 − 20 。 的中间
(正好一半),所以把幅值一分为二地放到 0 0 。 20 20 。 两个bin里面去。

基于方向梯度直方图(HOG)的人脸检测_第6张图片
对于在 160180 160 。 − 180 。 之间的角度,由于 0 0 。 180 180 。 是一样的,所以当像素的角度为 165 165 。 的时
候,要把幅值按照比例放到 0 0 。 160 160 。 的bin里面去。
计算公式为:

valuebinafter=directionbinfrebinafterbinfremagnitude v a l u e b i n a f t e r = d i r e c t i o n − b i n f r e b i n a f t e r − b i n f r e ∗ m a g n i t u d e

valuebinfre=binafterdirectionbinafterbinfremagnitude v a l u e b i n f r e = b i n a f t e r − d i r e c t i o n b i n a f t e r − b i n f r e ∗ m a g n i t u d e

注意:与距离成反比的

比如:

63.75=(180165)/2085 63.75 = ( 180 − 165 ) / 20 ∗ 85

21.25=(165160)/2085 21.25 = ( 165 − 160 ) / 20 ∗ 85

按照上面的规则,将这8*8的cell里面所有的像素点都分别加到这9个bin里面去,就构建了一个9-bin的直方图:
基于方向梯度直方图(HOG)的人脸检测_第7张图片
下面是人脸特征向量的图示化结果:

基于方向梯度直方图(HOG)的人脸检测_第8张图片

左图是通过SVM后得到的人脸模式图,右图是检测窗口检测到的特征向量

上述就是计算过程,算法中还有很多计算和处理细节,具体细致的内容可以参考文末的参考引用

参考资料

  • https://www.learnopencv.com/histogram-of-oriented-gradients/
  • 上面网站的中文翻译版本
  • https://blog.csdn.net/zhazhiqiang/article/details/21047207
  • https://medium.com/@ageitgey/machine-learning-is-fun-part-4-modern-face-recognition-with-deeplearning-c3cffc121d78

你可能感兴趣的:(python深度学习)