1. HOG特征简介
HOG特征是一种图像局部特征,基本思路是对图像局部的梯度幅值和方向进行投票,形成基于梯度特性的直方图,然后将局部特征拼接起来作为总特征。局部特征是指将图像划分为多个子块。
HOG+SVM工作流程:
2. HOG特征原理
2.1 图像预处理
预处理包括灰度化和Gamma变换。灰度处理是可选操作,方便计算梯度图。Gamma矫正是为了调节图像对比度,减少光照对图像的影响。
代码:
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()
3. 计算图像梯度
为了得到梯度直方图,需要计算图像水平方向和垂直方向的梯度。
一般使用特定的卷积核对图像滤波实现,OpenCV利用soble水平和垂直算子与图像卷积计算:
计算图像幅值:
角度:
注意:梯度方向和图像边缘方向是相互垂直的。
代码:
mport cv2
import numpy as np
# Read image
img = cv2.imread('*.jpg')
img = np.float32(img) / 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)
4. 计算梯度直方图
将图像分成多个8x8的cell,计算每一个cell的直方图,将0-180度分成9等份,称为9个bins,然后对每个bin中梯度的贡献进行统计:
统计方法是加权投票统计。加权公式为:
20度对应的bin:((40-36) / 20) x 13.6 分母的20表示20等份,而不是20度。
40度对应的bin:((36-20) / 20) x 13.6 分母的20表示20等份,而不是20度。
对整个cell进行投票统计,最后得到9个数值组成的向量---梯度方向图:
6. Block归一化
HOG特征将8x8的一个局部区域作为一个cell,再以2x2个cell作为一个组,称为一个block。我们可以通过对block进行归一化来减少对整体光照的敏感度。
归一化的方法有:L1-normal、L2-normal、max/min等,一般采用L2-normal。
7. 获取HOG描述子
每一个block都会得到一个长度为36的特征向量,进行归一化。获得HOG特征向量就可以用可视化和分类了。对于多维的HOG可以使用SVM。
8. 代码实现
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
if __name__ == '__main__':
src = cv.imread("*.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("hog-detector", src)
cv.imwrite("hog-detector.jpg",src)
cv.waitKey(0)
cv.destroyAllWindows()
结果展示: