原文:
towardsdatascience.com/histogram-of-oriented-gradients-hog-in-computer-vision-a2ec66f6e671
简介
方向梯度直方图最初由 Navneet Dalal 和 Bill Trigs 在他们 CVPR 论文[“方向梯度直方图用于人类检测”]中提出。
根据它关注的特征类型,如纹理、颜色或形状,以及它描述的是整个图像还是局部信息,有许多不同的特征提取算法。
HOG 算法是特征提取中最基本的技术之一,因为它是对象检测和识别任务的基础步骤。
在本文中,我们将探讨 HOG 算法的原理和实现。
什么是方向梯度直方图(HOG)?
HOG 是一种全局描述符(特征提取)方法,应用于图像中的每个像素,以提取邻域信息(像素的邻域)如纹理,并将从给定图像中压缩/抽象这些信息到一个称为特征向量的简化/浓缩向量形式,该向量可以描述此图像的特征,这在捕捉图像中的边缘和梯度结构时非常有用。此外,我们可以比较处理后的图像以进行对象识别或对象检测。
HOG 解释
1- 计算梯度图像
为了提取和捕获边缘信息,我们应用由两个小矩阵(滤波器/核)组成的 Sobel 算子,这些矩阵测量灰度中的强度差异( wherever there is a sharp change in intensity)。
作者创作
我们通过卷积将此核应用于图像的像素:
我们使用 3×3 核/滤波器(Sobel 算子)在图像上滑动,逐元素相乘,并将输出相加。(作者创作)
在对图像应用 Sobel 核之后,我们可以计算图像的幅度和方向:
梯度幅度。(作者创作)
梯度方向。(作者创作)
梯度确定了特定点的边缘强度(幅度)和方向(方向)。边缘方向与梯度向量在该点计算位置的方向垂直。换句话说,向量的长度和方向。
2- 计算梯度直方图
对于每个像素,我们有两个值:幅度和方向。为了将此信息组合成有意义的东西,我们使用直方图,这有助于有效地组织和解释这些值。
learnopencv.com/histogram-of-oriented-gradients/,由作者编辑。
我们在这些单元格(8×8)中创建梯度直方图,这些单元格有 64 个值分布在直方图的桶中,每个桶量化为 9 个桶,每个桶为 20 度(跨越 0°到 180°)。每个像素的幅度值(边缘强度)被添加为对应方向的“投票”,以便直方图的峰值揭示了像素的主导方向。
3-归一化
由于梯度幅度取决于光照条件,归一化将直方图缩放以减少光照和对比度变化的影响。
learnopencv.com/histogram-of-oriented-gradients/,由作者编辑。
每个块通常由一个网格状的单元格(2×2)组成。这个块在图像上滑动时会有重叠,意味着每个单元格都包含在多个块中。每个块有 4 个直方图(4 个单元格),这些直方图可以连接起来形成一个 4(单元格)x 9(桶)x 1 的向量=每个块 36 x 1 元素向量;示例中的整体图像:7 行 x 15 列=7x15x36=3780 个元素。这个特征向量被称为HOG 描述符,生成的向量被用作分类算法(如 SVM)的输入。
# we will be using the hog descriptor from skimage since it has visualization tools available for this example
import cv2
import matplotlib.pyplot as plt
from skimage import color, feature, exposure
# Load the image
img = cv2.imread('The path of the image ..')
# Convert the original image to RGB
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# Convert the original image to gray scale
img_gray = cv2.cvtColor(img_rgb,cv2.COLOR_RGB2GRAY)
plt.imshow(img_gray,cmap="gray")
# These are the usual main parameters to tune in the HOG algorithm.
(H,Himage) = feature.hog(img_gray, orientations=9, pixels_per_cell=(8,8), cells_per_block=(2,2),visualize=True)
Himage = exposure.rescale_intensity(Himage, out_range=(0,255))
Himage = Himage.astype("uint8")
fig = plt.figure(figsize=(15, 12), dpi=80)
plt.imshow(Himage)
莫娜丽莎图片由(WikiImages 用户 wikiimages-1897/)提供)pixabay.com/
如您所见,HOG 有效地捕捉了人脸的一般形状(眼睛、鼻子、头部)和手。这是由于 HOG 专注于图像中的梯度信息,使其在检测线条和形状方面非常有效。此外,我们还可以观察到图像中每个点的占主导地位的梯度和它们的强度。
(HOG)图像中人体检测算法
HOG 是计算机视觉中流行的特征描述符,特别适用于检测形状和轮廓,例如人体形状。此代码利用 OpenCV 内置的 HOG 描述符和专门训练用于检测人体的预训练支持向量机(SVM)模型。
# Load the image
img = cv2.imread('The path of the image ..')
# Convert the original image to RGB
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# Convert the original image to gray scale
img_gray = cv2.cvtColor(img_rgb,cv2.COLOR_RGB2GRAY)
#Initialize the HOG descriptor and set the default SVM detector for people
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
# Detect people in the image using the HOG descriptor
bbox, weights = hog.detectMultiScale(img_gray ,winStride = (2,2), padding=(10,10),scale=1.02)
# Draw bounding boxes around detected people
for (x, y, w, h) in bbox:
cv2.rectangle(img_rgb, (x, y),
(x + w, y + h),
(255, 0, 0), 4)
plt.imshow(img_rgb)
在加载测试图像后,我们使用 HOG 的 detectMultiScale 方法来检测人物,winStride 设置为每步跳过一个像素,通过牺牲一点精度来提高速度,这在目标检测中至关重要,因为这是一个计算密集型过程。尽管检测器可能识别出所有人,但有时会出现误报,即一个人的身体部分被检测为另一个人。为了解决这个问题,我们可以应用非极大值抑制(NMS)来消除重叠的边界框,尽管不良的配置(winStride、填充、缩放)有时会偶尔无法检测到对象。
总结
总结 HOG 描述符的计算涉及几个步骤:
-
梯度计算
-
姿态分箱
-
描述符块
-
归一化
-
特征向量形成 在这篇文章中,我们探讨了 HOG 背后的数学原理以及如何通过 OpenCV 在几行代码中轻松应用,这要归功于 OpenCV!希望您觉得这个指南有用,并且喜欢通过这些概念进行工作。感谢阅读,我们下次再见!
-
参考文献
-
L. Daudet, B. Izrar, 和 R. Motreff, 用于人类检测的定向梯度直方图,2010,HAL 开放科学。
-
Satya Mallick, 图像识别和目标检测:第一部分,2016,学习 OpenCV。
-
Satya Mallick, 使用 OpenCV 解释的定向梯度直方图,2016,学习 OpenCV
1万+

被折叠的 条评论
为什么被折叠?



