方向梯度直方图(HOG)第一步:梯度幅值・梯度方向
求出imori.jpg
的 HOG 特征量的梯度幅值和梯度方向吧!
HOG(Histogram of Oriented Gradients)是一种表示图像特征量的方法。特征量是表示图像的状态等的向量集合。
在图像识别(图像是什么)和检测(物体在图像中的哪个位置)中,我们需要:
- 从图像中获取特征量(特征提取);
- 基于特征量识别和检测(识别和检测)。
由于深度学习通过机器学习自动执行特征提取和识别,所以看不到 HOG,但在深度学习变得流行之前,HOG 经常被用作特征量表达。
通过以下算法获得HOG:
- 图像灰度化之后,在x方向和y方向上求出亮度的梯度:
- 从gx和gy确定梯度幅值和梯度方向:
-
将梯度方向[0,180]进行9等分量化。也就是说,对于[0,20]量化为 index 0,对于[20,40]量化为 index 1……
-
将图像划分为N×N个区域(该区域称为 cell),并作出 cell 内步骤3得到的 index 的直方图。
-
C x C个 cell 被称为一个 block。对每个 block 内的 cell 的直方图通过下面的式子进行归一化。由于归一化过程中窗口一次移动一个 cell 来完成的,因此一个 cell 会被归一化多次,通常ϵ=1:
h(t)=∑ h(t)+ϵh(t)
以上,求出 HOG 特征值。
这一问,我们完成步骤1到3。
为了使示例答案更容易看出效果,gra
是彩色的。此外,mag
被归一化至[0,255]。
python实现:
import cv2
import numpy as np
import matplotlib.pyplot as plt
def HOG_step1(img):
def BGR2GRAY(img):
gray = 0.2126 * img[..., 2] + 0.7152 * img[..., 1] + 0.0722 * img[..., 0]
return gray
def get_gradXY(gray):
H, W = gray.shape
gray = np.pad(gray, (1, 1), 'edge')
gx = gray[1:H+1, 2:] - gray[1:H+1, :W]
gy = gray[2:, 1:W+1] - gray[:H, 1:W+1]
gx[gx == 0] = 1e-6
return gx, gy
def get_MagGrad(gx, gy):
magnitude = np.sqrt(gx ** 2 + gy ** 2)
gradient = np.arctan(gy / gx)
gradient[gradient < 0] = np.pi / 2 + gradient[gradient < 0] + np.pi / 2
return magnitude, gradient
def quantization(gradient):
gradient_quantized = np.zeros_like(gradient, dtype=np.int)
d = np.pi / 9
for i in range(9):
gradient_quantized[np.where((gradient >= d * i) & (gradient <= d * (i + 1)))] = i
return gradient_quantized
gray = BGR2GRAY(img)
gx, gy = get_gradXY(gray)
magnitude, gradient = get_MagGrad(gx, gy)
gradient_quantized = quantization(gradient)
return magnitude, gradient_quantized
img = cv2.imread("imori.jpg").astype(np.float32)
magnitude, gradient_quantized = HOG_step1(img)
_magnitude = (magnitude / magnitude.max() * 255).astype(np.uint8)
cv2.imwrite("out_mag.jpg", _magnitude)
H, W, C = img.shape
out = np.zeros((H, W, 3), dtype=np.uint8)
C = [[255, 0, 0], [0, 255, 0], [0, 0, 255], [255, 255, 0], [255, 0, 255], [0, 255, 255],
[127, 127, 0], [127, 0, 127], [0, 127, 127]]
for i in range(9):
out[gradient_quantized == i] = C[i]
cv2.imwrite("out_gra.jpg", out)
cv2.imshow("result", out)
cv2.waitKey(0)
cv2.destroyAllWindows()
输入(imori.jpg):

梯度幅值(answer_66_mag.jpg):

梯度方向(answer_66_gra.jpg):
