第14期(六月)组队学习 Task4:HOG特征描述算子-行人检测

1 简介

HOG(Histogram of Oriented Gradients)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子。通过计算和统计图像局部区域的梯度方向直方图来构成特征。Hog特征结合SVM分类器已经被广泛应用于图像识别中,在图像手工特征提取方面具有里程碑式的意义,在行人检测中获得了极大的成功。
HOG是对图像局部的梯度幅值和方向进行投票统计,从而形成基于梯度特性的直方图,最后将局部特征拼接起来作为总特征。即将图像划分为多个子块,每个子块内的特征进行联合拼接得到总特征。

2 相关流程

HOG结合SVM的工作流程如下图:
在这里插入图片描述
第一步输入图像并预处理,第二步计算像素点的梯度幅值和方向,第三步投票统计形成梯度直方图,第四步对blocks进行归一化,第五步将收集到HOG特征放到SVM进行监督学习,通过以上步骤实现行人检测。

2.1 图像预处理

图像预处理主要包含灰度化和Gamma变换,灰度化是可选操作,其实灰度图像和彩色图像均可以计算梯度图,但是彩色图需要先对三通道颜色值分别计算梯度,然后将梯度值最大的那个通道作为该像素点的梯度。
使用伽马矫正调节图像对比度,降低光照不均匀和局部阴影对图像的影响,即将图像恢复到接近人眼看到的图像。伽马矫正公式如下:
f ( I ) = I γ f(I)=I^\gamma f(I)=Iγ

其中 I I I为 输入图像, γ \gamma γ为幂指数,
在这里插入图片描述
上图为 γ \gamma γ取不同的值时对应的输入输出曲线,
1)当 γ > 1 \gamma>1 γ>1时,输入图像的高灰度值区域动态范围变大,则低灰度值区域对比度降低,高灰度值区域对比度增强,图像整体灰度变暗;
2)当 γ < 1 \gamma<1 γ<1时,输入图像的低灰度值区域动态范围变大,则低灰度值区域对比度增强,高灰度值区域对比度降低,图像整体灰度变亮;

参考代码

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('task4.jpg', 0)
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
img2 = np.power(img/float(np.max(img)),5/2.2)
cv2.imshow("result", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
在这里插入图片描述

2.2 计算图像梯度

计算图像水平方向和垂直方向梯度需要使用特定的梯度算子对输入图像进行滤波实现,常用算子有Sobel、Prewitt算子、Roberts算子等等。
利用Sobel算子求取图像水平方向和垂直方向梯度。
S x = [ 1 2 1 0 0 0 − 1 − 2 − 1 ] S_x=\begin{bmatrix}1 & 2 & 1\\\\0 &0 & 0\\\\\\-1 &-2 &-1\end{bmatrix} Sx=101202101
S y = [ 1 0 − 1 2 0 − 2 1 0 − 1 ] S_y=\begin{bmatrix}1 & 0 & -1\\\\2 &0 & -2\\\\\\1 &0 &-1\end{bmatrix} Sy=121000121
G x = I ( x , y ) ∗ S x G_x=I(x,y)*S_x Gx=I(x,y)Sx
G y = I ( x , y ) ∗ S y G_y=I(x,y)*S_y Gy=I(x,y)Sy
由图像水平方向和垂直方向梯度得到图像梯度幅值和角度
M ( x , y ) = G x 2 ( x , y ) + G y 2 ( x , y ) M(x,y)=\sqrt{G_x^2(x,y)+G_y^2(x,y)} M(x,y)=Gx2(x,y)+Gy2(x,y)
θ = a r c t a n ( G y / ( G x ) \theta=arctan(G_y/(G_x) θ=arctan(Gy/(Gx)
在这里插入图片描述
如上图所示,图像梯度方向与边缘方向是相互正交。

参考代码

import cv2
import numpy as np

# Read image
img = cv2.imread('airplane.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)
print("gx:")
print(gx)
print("gy:")
print(gy)
# 计算合梯度的幅值和⽅向(⻆度)
mag, angle = cv2.cartToPolar(gx, gy, angleInDegrees=True)
print("mag:")
print(mag)
print("angle:")
print(angle)
print(gx.shape,gy.shape,mag.shape,angle.shape)

2.3 计算梯度直方图

将图像分成若干个 8 ∗ 8 8*8 88的子块,先将图像压缩至 64 x 128 64x128 64x128的尺寸,图像就被分成 8 ∗ 16 8*16 816 8 ∗ 8 8*8 88的子块,计算所有子块的梯度直方图。
在这里插入图片描述
上图为划分示意图,中间图像为一个子块的梯度矢量,箭头朝向代表梯度方向,箭头大小代表梯度大小。
在这里插入图片描述
在这里插入图片描述
对整个子块进行投票统计得到由9个数值组成的向量—梯度方向图。
在这里插入图片描述

2.4 Block 归一化

在这里插入图片描述
参考代码

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
if __name__ == '__main__':
   src = cv.imread("test2.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)
   print(rects, weights)
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()

致谢

感谢Datawhale提供的资料和帮助

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值