HOG全称histogram of oriented gradients.就是根据方向梯度直方图寻找图像的特征。它可以用来表示图像的物体特征,因此能够检测出这类物体。(下图就是HOG提取的特征)
HOG特征描述子提取过程:
为了得到梯度直方图,那么首先需要计算水平和垂直梯度,这可以通过使用以下内核过滤图像来实现,分别用于计算水平梯度和垂直梯度。
#调节图像对比度,减少光照对图像的影响
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('*.png', 0)
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
img2 = np.power(img/float(np.max(img)),1/2.2)
plt.imshow(img2)
plt.axis('off')
plt.show()
img = np.float32(img2) / 255.0 # 归一化
# 计算x和y方向的梯度
gx = cv2.Sobel(img, cv2.CV_32F, 1, 0, ksize=1)
gy = cv2.Sobel(img, cv2.CV_32F, 0, 1, ksize=1)
# 计算合梯度的幅值和方向(角度)
mag, angle = cv2.cartToPolar(gx, gy, angleInDegrees=True)
分割为8*8=64像素的cell网格(下图绿色格子),对每个cell求取方向直方图。
每个8*8cell的梯度直方图本质是一个由9个数值组成的向量, 对应于0、20、40、60…160的梯度方向(角度),也就是9个bins。然后对每个bin中梯度的贡献进行统计。
将2×2的网格单元组合成为一个大的块(block),对每个块之间有1/2部分是重叠区域。
主要是将每个cell的直方图合并为一个大的直方图(bin索引不变,在0-8之间)
从上图可以看到,更多的点的梯度方向是倾向于0度和160度,也就是说这些点的梯度方向是向上或者向下,表明图像这个位置存在比较明显的横向边缘。因此HOG是对边角敏感的,由于这样的统计方法,也是对部分像素值变化不敏感的,所以能够适应不同的环境。
归一化的方法有很多:L1-norm、L2-norm、max/min等等,一般选择L2-norm。
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
if __name__ == '__main__':
src = cv.imread("D:/python_opencv/stand.jpg")
cv.imshow("input", src)
hog = cv.HOGDescriptor()
hog.setSVMDetector(cv.HOGDescriptor_getDefaultPeopleDetector())
# Detect people in the image
(rects, weights) = hog.detectMultiScale(src,
winStride=(2,4),
padding=(8, 8),
scale=1.2,
useMeanshiftGrouping=False)
for (x, y, w, h) in rects:
cv.rectangle(src, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv.imshow("peoples", src)
#cv.imwrite("peoples.jpg",src)
cv.waitKey(0)
cv.destroyAllWindows()