OpenCV HOG+SVM行人检测

方向梯度直方图(Histogram of Oriented Gradient, HOG)是一种常见的特征提取算法,基本思想是统计图像局部区域的梯度方向信息作为该局部图像区域的表征。HOG特征提取+SVM训练,在行人检测中获得了极大成功。该方法是法国研究人员Dalal在2005的CVPR上提出的,如今虽然有很多行人检测算法不断提出,但基本都是以HOG+SVM的思路为主。

HOG特征提取的流程如下:

1灰度化

将输入的彩色图像转化为灰度图像。

2 标准化gamma空间

为减少光照的影响,需要将整个图像进行规范化(归一化),这种处理能够有效地降低图像局部的阴影和光照变化。

3 计算图像梯度

计算图像横坐标和纵坐标方向的梯度,并据此计算每个像素点位置的梯度方向值。

图像中像素点(x,y)的梯度为:

Gx(x, y) = H(x+1, y) – H(x-1, y)

Gy(x, y) = H(x, y+1) – H(x, y-1)

式中,H(x, y)表示像素点(x, y)的像素值。像素点(x, y)处的梯度幅值和梯度方向分别为:

OpenCV HOG+SVM行人检测_第1张图片

4 Cell分割与Block

将图像分成8*8像素块,每一个块为一个Cell,每个2*2大小的Cell称为一个Block。每个Cell根据角度与权重建立直方图。例如:如果一个像素的梯度方向是20-40度,直方图第2个bin的计数就加一。这样,对cell内每个像素用梯度方向在直方图中进行加权投影,就可以得到这个cell的梯度方向直方图了,就是该cell对应的9维特征向量。梯度方向用到了,梯度大小呢?梯度大小是作为投影的权值的。例如:一个像素的梯度方向是20-40度,梯度大小是2,那么直方图第2个bin的计数就不是加一,而是加二。

OpenCV HOG+SVM行人检测_第2张图片

每20度为一个bin,每个Cell得到9个值、每个Block得到36个值(4*9)。然后以每个Block为单位进行L2数据归一化,抵消光照、迁移的影响。L2归一化的公式如下:

5 生成描述子

统计每个cell的梯度直方图(不同梯度的个数),即可形成每个cell的descriptor;一个block内所有cell的特征descriptor串联起来便得到该block的HOG特征descriptor。将图像image内的所有block的HOG特征descriptor串联起来就可以得到该image的HOG特征descriptor,即最终可供分类使用的特征向量。

6 总结

HOG特征提取的过程:把样本图像分割为若干个像素的单元(cell),把梯度方向平均划分为9个区间(bin),在每个单元里面对所有像素的梯度方向在各个方向区间进行直方图统计,得到一个9维的特征向量,每相邻的4个单元构成一个块(block),把一个块内的特征向量联起来得到36维的特征向量,用块对样本图像进行扫描,扫描步长为一个单元。最后将所有块的特征串联起来,就得到了人体的特征。例如,对于64(列)*128(行)的图像而言,每8*8的像素组成一个cell,每2*2个cell组成一个块,因为每个cell有9个特征,所以每个块内有4*9=36个特征。以8个像素为步长,那么,水平方向将有7个扫描窗口,垂直方向将有15个扫描窗口。也就是说,64*128的图片,总共有36*7*15=3780个特征。

代码:

"""
HOG+SVM行人检测
"""
import cv2

image = cv2.imread(r'D:\anoconda\test\test\img\pedestrain.jpg')
cv2.imshow("input", image)

#初始化HOG描述子和行人检测器
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())

#检测图像中的人 
#image:图像
#winStride:HOG检测窗口移动时的步长
#padding:在原图外围添加像素,适当的pad可提高检测的准确率
#scale:可控制金字塔的层数,参数越小,层数越多。通常scale在1.01-1.5之间
(rects, weights) = hog.detectMultiScale(image, winStride=(4, 4),
        padding=(8, 8), scale=1.05)

for (x,y,w,h) in rects:
    cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0), 2)

cv2.imshow("hog-detector", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

你可能感兴趣的:(opencv)