HOG特征提取

HOG特征的提取

本文对Dalal提出的Hog特征提取的过程进行了详细分析,它通过计算和统计图像局部区域的梯度方向直方图来构成特征。HOG+SVM进行行人检测的方法是法国研究人员Dalal在2005的CVPR上提出的,已经被广泛应用于图像识别中,如今虽然有很多行人检测算法不断被提出,但基本都是以HOG+SVM的思路为主。


1.HOG的winsize、blocksize和cellsize

1.1 winsize

patch_crop_resize

这里有张图是720 x 475的,我们首先需要用打标签的一些工具如labImg框出我们需要的目标,框出的目标信息将保存图片上面两个点的坐标,即红色虚线框左上角和右下角坐标。假设我们框出的patch大小为100 x 200的,我们需要先将其resize成64 x 128的patch。

winsize示意图

以此图为例,resize之后的patch的大小为:64 x 128,这里我们换个说法,称这个patch的大小为选择窗口大小(winsize),即winsize为64 x 128.

1.2 blocksize和blockstride

blockszie和blockstride示意图

blocksize移动示意图

此时winsize为64x128,blocksize为16x16,而块滑动增量(blockstride)为8x8(每次只能左右移动8个pixel或者上下移动8个pixel),意味着每行block需要移动(64 - 16) / 8 = 6次,得到7个block;每列block需要移动(128 - 16) / 8 = 14次,得到15个block,故总共需要移动 6 x 14 = 84 次,得到 7 x 15 = 105 个block

1.3 cellseize

cellsize示意图

上面已经说到,blocksize为16x16,cellsize我们默认为8x8,每个blocksize是由4个cellsize构成,HOG中文名是方向梯度直方图,它是以cellsize为基本单元所做出相关的运算,然后得到我们所需要的直方图。此时我们单独对cellsize进行分析,来看看hog特征的计算。


2.HOG特征的计算

2.1 幅度和角度的计算

用以下公式来计算梯度的幅值和方向:

梯度的幅值和方向的计算公式

可以用OpenCV的cartToPolar函数计算:

// C++ Calculate gradient magnitude and direction (in degrees)
Mat mag, angle; 
cartToPolar(gx, gy, mag, angle, 1);

x轴方向的梯度主要凸显了垂直方向的线条,y轴方向的梯度凸显了水平方向的梯度,梯度幅值凸显了像素值有剧烈变化的地方。

在每个像素点,都有一个幅值(magnitude)和方向,对于有RGB图片,会有三个channel,若直接计算梯度,则在3个channel上都计算梯度,也就是说梯度将会被计算三次,取三个channel上最大的幅值为相应的幅值,方向是最大幅值所对应的角度。不过我们一般对RGB图像进行HOG特征计算的时候,可以先经过灰度化(一般方法有平均值法、最大值法、加权平均值法以及单色法,从而得到灰度图像)和gamma校正(通过对比度修正使得杂物变少,其次使得亮度变化较大的图像归一化到亮度比较平均的水平下,以此来提高识别效率,减少漏检和误检)然后再来计算梯度,这样一来计算梯度的次数会明显减少。

之前说过cellsize的大小为8x8,如下图给出了一个cellsize内的梯度大小及方向的示意图

一个cellsize内的梯度大小及方向的示意图

中间的图是用箭头的方向和大小表示梯度的方向和大小,右边的图直接用数字表示梯度的大小和方向,二者传达的都是同种信息,只是表达方式不同而已。

从右边不难看出,梯度方向矩阵中角度的范围是0-180度,而不是0-360度,这种被称之为"无符号"梯度(“unsigned” gradients)。因为一个梯度和它的负数是用同一个数字表示的,也就是说一个梯度的箭头以及它旋转180度之后的箭头方向被认为是一样的。那为什么不用0-360度的表示呢?在作者所做的测试中发现unsigned gradients比signed gradients在行人检测任务中效果更好。一些HOG的实现中可以让你指定signed gradients。

2.2 单个cell内HOG的获取

cellsize内HOG特征加权计算

我们将直方图的横坐标分别设为0、20、40…160度,我们根据方向选择映射到哪个bin, 根据幅值来确定这个bin中的增量的权值的大小。以蓝色圈圈出来的像素点为例,它的角度是80度,幅值是2,所以它直接在第5个bin里面加了2;再来看红色的圈圈出来的像素点,它的角度是10度,副值是4,因为角度10介于0-20度(0 x 0.5 + 20 x 0.5 = 10),所以把幅值的0.5加到第1个bin里面去,再把幅值的0.5倍加到第2个bin里面去。

cellsize中HOG的加权求值

那么绿色的圈圈如何解读呢?165度介于160度和180度(也就是0度)之间(160 x 0.75 + 180 x 0.25 = 165),因此把幅值的0.75倍加到第9个bin内,再把幅值的0.25倍加到第1个bin内即可。

将这8x8的cellsize里面所有的像素点的梯度都按照此规则分别加到这9个bin里面之后,就构建了一个9-bin的直方图,上面的网格对应的直方图如下:

HOG特征直方图

上述已经说到,一个cellsize内有9个bin,相当于一个cellsize内有9维特征,一个blocksize由4个cellsize构成,那么一个blocksize中就包含9 x 4 = 36维特征。为什么我们需要选定步长blockstride从而遍历整个图像呢?

2.3 梯度幅度归一化

由于局部光照的变化以及前景和背景对比度的变化,使得梯度幅度的变化范围非常大(从0 ~ 256)。这就需要对梯度幅度做归一化。归一化能够进一步地对光照、阴影和边缘进行压缩。其本质是起到了提升性能的作用。

那么如何对梯度幅度做归一化呢?作者采取的办法是:把各个cellsize组合成大的、空间上连通的blocksize。这样,一个blocksize内所有cellsize的特征向量串联起来便得到该blocksize的HOG特征。这些blocksize是互有重叠的,这就意味着:每一个cellsize的特征会以不同的结果多次出现在最后的特征向量中。我们将归一化之后的块描述符(向量)就称之为HOG描述符。

以1.3为例,一个block内有4个cell,我们将其命名为cell1、cell2、cell3、cell4,假设分别经过运算得到单个cell内的HOG如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Tzj8EwV-1606221250853)(D:\My\TIDSP\KCF相关\HOG特征提取\cell_HOG.PNG)]

为了直观,我们将其表示成向量:v_cell1 = [1, 2, 4, 7, 3, 8, 2, 6, 3]、v_cell2 = [7, 1, 4, 7, 5, 7, 5, 9, 6]、v_cell3 = [3, 1, 9, 3, 6, 5, 8, 2, 1]、v_cell4 = [5, 1, 9, 9, 1, 3, 5, 7, 9],他们都是1 x 9维向量,首尾拼接,得到一个1 x 36维的向量:v_cell = [1, 2, 4, 7, 3, 8, 2, 6, 3, 7, 1, 4, 7, 5, 7, 5, 9, 6, 3, 1, 9, 3, 6, 5, 8, 2, 1, 5, 1, 9, 9, 1, 3, 5, 7, 9]。接下来就是对这个36维的向量进行归一化,论文中作者提出了4种归一化的方法:L2-norm、L2-Hys、L1-norm以及L1-sqrt,其定义如下:

L2-norm、L2-Hys、L1-norm以及L1-sqrt的定义

并分别对其进行了测试,发现L2-Hys、L2-norm、L1-sqrt的表现差不多一样好,简单的L1-norm会使性能下降5%,如果完全不进行归一化会导致性能下降27%。这里我们以L2-norm为例来说明上述操作。其具体操作为:先求出这个36维向量的L2范数,即:L2 = sqrt(12+22+42+…+72+9^2)=33.26,然后v_cell1 / L2、v_cell2 / L2、v_cell3 / L2、v_cell4 / L2就可以得到归一化之后的HOG,例如v_cell1归一化操作之后即为:v_cell1_norm = [0.03, 0.06, 0.12, 0.21, 0.09, 0.24, 0.06, 0.18, 0.09](这里博主为了计算方便所以取值较为简单,只是为了让大家明白归一化这个具体的操作过程)


3.总结

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

另外,Dalal提出的Hog特征提取过程中,直方图的方向bin在0度-180度(无符号梯度)或者0度-360度(有符号梯度)之间均分,增加bin的个数可以显著提高检测器的性能,直到大约9个bin为止,文中所用的是无符号梯度的0度-180度均分方向直方图。如果包括梯度符号信息(方向范围为0度-360度,类似SIFT描述子中使用的方向直方图)会导致性能下降,即使bin的个数加倍来保存原始方向信息也不行。对于人体检测来说,衣服和背景颜色的多变可能使得梯度符号信息无意义,但对于其他目标检测,例如汽车、摩托车,梯度符号信息是有用的。

其次,作者文中对于cellsize和blocksize的选择做了很多实验,首先是确定cellsize的尺寸,比如4 x 4, 6 x 6,8 x 8, 10 x 10等等,然后再确定一个block中含有多少个cell,例如:一个block中含有1 x 1,2 x 2 ,3 x 3还是4 x 4个cell。

作者给出了在10^(-4)FPPW(每个窗口的误报率)时漏检率随不同的细胞单元和块尺寸的变化情况,如下图所示:

漏检率随不同的细胞单元和块尺寸的变化情况

对于人体检测,每个block内含3 x 3个cell,每个cell含6 x 6个像素时最优,此时漏检率大约为10.4%。

:在阅读时cellsize = cell, blocksize = block

Histograms of Oriented Gradients for Human Detection原文翻译

HOG源码解析

  • 40
    点赞
  • 168
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: HOG(Histogram of Oriented Gradients)是一种计算机视觉中的特征提取算法,常用于目标检测和行人识别等任务中。在Python中,可以使用OpenCV或scikit-image等库来实现HOG特征提取。 以scikit-image为例,可以通过以下代码实现HOG特征提取: ``` from skimage.feature import hog from skimage import data, exposure # 读取图像 image = data.astronaut() # 计算HOG特征 fd, hog_image = hog(image, orientations=8, pixels_per_cell=(16, 16), cells_per_block=(1, 1), visualize=True, multichannel=True) # 对HOG特征进行可视化 hog_image_rescaled = exposure.rescale_intensity(hog_image, in_range=(0, 10)) # 显示原始图像和HOG特征图像 import matplotlib.pyplot as plt fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4), sharex=True, sharey=True) ax1.axis('off') ax1.imshow(image, cmap=plt.cm.gray) ax1.set_title('Input image') hog_image_rescaled = exposure.rescale_intensity(hog_image, in_range=(0, 10)) ax2.axis('off') ax2.imshow(hog_image_rescaled, cmap=plt.cm.gray) ax2.set_title('Histogram of Oriented Gradients') plt.show() ``` 其中,`image`代表输入的图像,`orientations`指定方向的个数,`pixels_per_cell`指定每个细胞的像素数,`cells_per_block`指定每个块包含的细胞数。`fd`表示提取得到的HOG特征向量,`hog_image`表示HOG特征图像。最后,使用`matplotlib`库进行可视化,显示原始图像和HOG特征图像。 ### 回答2: HOG(Histogram of Oriented Gradients)特征提取是一种用于计算图像特征的方法,最初是由Navneet Dalal和Bill Triggs在2005年提出的。它在计算机视觉领域被广泛应用于物体检测和图像分类任务。 HOG特征提取的过程可以分为以下几个步骤: 1. 归一化图像大小:为了保持计算效率,首先需要将图像缩放为固定的大小。通常,使用缩放后的图像尺寸在64x128到128x256之间。 2. 计算梯度:对于每个像素,通过计算其在水平和垂直方向上的梯度,确定其梯度的大小和方向。这些梯度用于描述图像的边缘和纹理信息。 3. 划分图像为小单元:将缩放后的图像划分为一系列重叠的小单元。每个小单元通常为8x8像素。 4. 创建梯度方向直方图:对于每个小单元,根据其中像素的梯度方向和大小,创建梯度方向直方图。一个直方图通常包含9个方向的梯度值。 5. 归一化块:将相邻的若干小单元组合成块,并对每个块内的直方图进行归一化处理。这有助于提高特征的鲁棒性和可区分性。 6. 拼接特征向量:将所有块的特征向量拼接在一起,形成最终的HOG特征向量。 HOG特征提取通过描述图像中梯度的方向信息来提取特征,而不是关注像素的具体值。这使得HOG特征对于光照变化和几何变换相对不敏感,具有较好的鲁棒性。在图像处理和计算机视觉任务中,HOG特征已被广泛应用于人体检测、行人检测、物体识别等领域。 ### 回答3: HOG(方向梯度直方图)是一种计算机视觉领域常用的特征提取算法,它用于对图像进行描述和识别。Python中有各种库和模块可以用来实现HOG特征提取HOG特征提取的步骤如下: 1. 图像预处理:将图像转化为灰度图,如果图像尺寸较大,还可以进行降采样。 2. 计算图像的梯度:使用Sobel等算子计算图像在水平和竖直方向上的梯度。计算梯度的目的是为了检测图像中的边缘和纹理。 3. 划分图像为小的块(cells):将图像分割为大小固定的小块,每个小块包含多个像素。 4. 计算每个小块的梯度直方图:对于每个小块,统计其内像素的梯度方向和强度,并将其组织成直方图。 5. 归一化梯度直方图:对于每个小块的梯度直方图,可以对其进行归一化,使得特征对光照等变化更加不敏感。 6. 将小块的特征组合成一个全局的特征向量:将所有小块的特征向量进行串联,形成一个用于描述整个图像的全局特征向量。 通过以上步骤,我们可以得到一个用于描述图像的HOG特征向量。这个特征向量可以用于识别和分类任务,比如行人检测、物体识别等。 在Python中,我们可以使用第三方库如OpenCV或scikit-image来实现HOG特征提取。这些库提供了方便的函数和方法,可以直接使用。 例如,使用OpenCV库,我们可以使用以下代码来实现HOG特征提取: ```python import cv2 def hog_feature_extraction(image): # 图像预处理 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 创建HOG对象 hog = cv2.HOGDescriptor() # 计算HOG特征向量 features = hog.compute(gray) return features ``` 上述代码中,我们首先将彩色图像转换为灰度图像,然后创建一个HOG对象,并使用`compute`函数计算图像的HOG特征向量。 总结来说,Python中可以使用第三方库实现HOG特征提取,该特征提取方法可以用于图像描述和识别任务,具有良好的性能和鲁棒性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值