1.什么是HOG特征?
HOG(Histogram of Oriented Gradient)方向梯度直方图,是一幅用来统计图像中像素点方向梯度的直方图。那么为什么要统计像素的方向梯度呢?
1.1 图像的方向梯度
像素的方向梯度和边缘(物体的轮廓)分不开。一幅图像有很多值不同的像素点构成,我们人能和找到物体的边缘,因为我们知道边缘内和边缘外是不同的,这种不同图像上就体现在像素强度的不同。怎么描述这种像素的变化以便检查出物体的边缘,这里我们就引入了图像的方向梯度。梯度就是反应的变化。
1.2 数学定义
一幅图像可以表示成一个二维函数,其中是平面的坐标,是像素点的强度(灰度)。像素点的变化可以沿着方向,也可以沿着方向,因此
、方向分别求像素点的变化。
因为图像是一个离散的二维函数,其 不可能无限小,图像有一个个的像素组成,所以其取为1。于是图像的方向梯度表示为:
这样我们就分别求得了像素点在水平方向和垂直方向的梯度值,从上面的公式可以看出,图像的梯度的值相当于就是两个像素的差值。所以像素点处的梯度幅值和梯度方向分别为:
1.3 Opencv中方向梯度的计算(以sobel算子为例)
opencv中可使用sobel,Laplacian等梯度算子对图像进行卷积运算来计算图像方向梯度。
import cv2
import matplotlib
import matplotlib.pyplot as plt
img=cv2.imread("square.png")
gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
sobel_x=cv2.Sobel(gray,cv2.CV_64F,dx=1,dy=0)
sobel_y=cv2.Sobel(gray,cv2.CV_64F,dx=0,dy=1)
result=cv2.addWeighted(sobel_x,0.5,sobel_y,0.5,0)
images=[img,gray,sobel_x,sobel_y,result]
titles=["Original","gray","sobel_x","sobel_y","result"]
for i in range(len(images)):
plt.subplot(2,3,i+1)
plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([])
plt.yticks([])
plt.show()
这里为了方便理解方向梯度,我画了一张黑底的白色矩形。其结果如下图:
2.HOG(方向梯度直方图)的绘制过程
- 计算出整张图片的像素方向梯度(大小和方向)
- 把图片分成一个个的小cells(比如一个9X9 像素为一个cell),计算HOG 的bin的值,形成每个cell的HOG。
- 将某几个cells合并在一起形成一个block(比如一个3X3的Block的像素值为27X27),把block内cells的HOG串联起来,就是这个block的HOG。
- 将图像image内的所有block的HOG串联起来就可以得到该image(你要检测的目标)的HOG特征descriptor了。
2.1 HOG计算bin值
梯度方向θ为[0,360°],将其划分成n个bins。例如OpenCV中n=9,即将一个圆均分成9部分,每一部分区间对于bin值,如0≤θ<40对应bin=0,那么当某个梯度方向在[0,40)范围内时,对应着bin=0加1,而幅值是计算bin个数时的权重,接着上面例子,如果M=2,那么bin=0加1*2=2。这样就可以得到每个bin的计数。