计算机视觉爱好者必看:特征工程HOG特征描述子指南

全文共4499字,预计学习时长9分钟算法

特征工程在机器学习算法领域中能够说是“改变游戏规则”的存在。特征工程是进行最多实验的领域——根据现有内容设计新特征并改善模型的表现。数据库

一些世界上顶尖的数据科学家依靠特征工程提升本身在黑客马拉松中的排行榜得分。微信

那么此项技术能够扩展应用于非结构化数据吗,例如图像?这对计算机视觉爱好者来讲是一个有趣的谜题,本文将揭晓答案。准备好对图像数据应用特征提取技术,从而执行特征工程。机器学习

事实上,特征提取有众多方法。

本文将介绍一种热门的图像特征提取方法——方向梯度直方图(Histogram of Oriented Gradients),称做HOG更为熟知。具体包括:理解HOG特征描述子是什么、工做机制(算法背后完整的数学运算),以及在Python中的应用。函数

目录工具

1. 什么是特征描述子?学习

2. HOG特征描述子介绍ui

3. HOG计算过程人工智能

3.1 数据预处理设计

3.2 梯度计算

3.3 幅值和方向计算

4. 使用梯度和方向建立直方图的方法

5. HOG计算过程

5.1 梯度直方图计算

5.2 梯度规范化

5.3 完整图像特征

6. 在Python中应用HOG特征描述子

什么是特征描述子?

请看下面两张图片。你能辨别出图片中的物体吗?

能够清楚地看到,左图中有一辆汽车,右图中有一条狗。接下来,把这个问题变得稍微复杂点——辨别下图中的物体。

仍是很简单,对吧?你知道两个问题的区别吗?第一组图片包含不少信息,如物体形状、颜色、边缘和背景等。

相比来看,第二组图片中的信息少多了(只有形状和边缘),但这些信息足以辨别图片中物体。

你知道咱们接下来要讲什么了吗?在第二组图片中,能够轻松辨识物体,由于其中包含了识别物体所需的必要信息。而这也就是特征描述子的做用:

特征描述子是图片的简略替代,其中只包含图像最重要的信息。

此外还有不少种特征描述子。如下是最热门的几种:

· HOG: 方向梯度直方图

· SIFT: 尺度不变特征变换

· SURF: 加速稳健特征

本文聚焦HOG特征描述子及其工做机制。如今开始吧!

HOG特征描述子介绍

HOG,也称做方向梯度直方图,是经常使用于提取图像数据特征的一种特征子。其普遍应用于计算机视觉任务以进行目标检测。

一同看看HOG与其它特征描述子的区别:

· HOG特征描述子关注物体的结构或形状。你可能会问,这和提取的图像边缘信息有什么区别?就边缘信息而言,只能辨别此像素是否属于边缘。而HOG还能提供边缘的方向。这是经过提取边缘的梯度和方向实现的。

· 另外,这些方向是在“局部”区域计算得出的。这就意味着一张完整的图片被分红了几个小部分,针对每一个区域计算其梯度和方向。更多相关细节会在下文说起。

· 最后,HOG会分别为这些部分生成直方图。因为它们是使用像素值的梯度和方向创造出来的,因此得名“方向梯度直方图”。

其正式定义为:

HOG特征描述子用于统计和计算图片中局部区域出现的梯度方向。

使用相似OpenCV的工具应用HOG很是简单。因为skimage.feature库中已有被称为hog的预约义函数,因此只需几行代码便可。然而,本文的重点聚焦这些特征究竟是怎样计算出来的。

HOG计算过程

经过上文,想必你对HOG特征描述子已有基本了解。如今该开始研究本文背后的核心思想了。你们共同逐步讨论HOG的计算过程。

思考下图尺寸(180 x 280)。一同详细了解这张图像的HOG特征是如何建立的。

第1步:数据预处理(64 x 128)

大家中大多数人应该都很熟悉这一步。数据预处理在任何机器学习项目中都是关键步骤,处理图像时也不例外。

在此须要对图像进行预处理,将宽高比降为1:2。图像最佳尺寸为64 x 128。这是由于须要将图片分为8*8和16*16的小块以提取特征。使用特定的尺寸(64 x 128)会让后续运算很是简便。实际上,这个数据就是原始论文(http://lear.inrialpes.fr/people/triggs/pubs/Dalal-cvpr05.pdf)中使用的值。

回到本文所给出的例子上,选用64 x 28这一大小的图像做为当前的标准图像尺寸。下图是修改尺寸后的图像。

第2步:梯度计算(x和y方向)

下一步是计算图像中每一像素的梯度。梯度是x和y方向所发生的微小变化。本文中,笔者从图像中取一小块区域,并计算其梯度:

从上图的小块区域中获得像素值。对此区域,生成了以下的像素矩阵(下图所示的矩阵仅用做例子,且不是所示区域的初始像素值):

图源:机器学习应用课程

笔者已将像素值85高亮表示。如今,肯定x方向的梯度(或变化),须要用像素值85右侧值减去其左侧值。相应地,计算y方向的梯度,须要用所选像素值85上方的值减去其下方的值。

由此计算出这一像素在x和y方向的梯度为:

· x方向变化(Gx) = 89 – 78 = 11

· y方向变化(Gy) = 68 – 56 = 8

此过程得出两个新矩阵——一组x方向的存储梯度,一组y方向的存储梯度。这与使用大小为1的索伯算子相似。密度上有剧烈变化时,如边缘周围的密度,幅度则会升高。

目前已分别计算求得x和y方向的梯度。请对图像中全部像素重复同一步骤。下一步就是使用这些值计算出幅值和方向。

第3步:幅值和方向计算

使用上一步中计算出的梯度,而后肯定每一个像素值的幅值和方向。在此步骤中,会运用到勾股定理(是的,就是你在学校学过的那个!)。

请看下图:

梯度基本上对应的都是相似图中的底边和垂直边。因此,上例的Gx为11,Gy为8。 应用勾股定理计算总斜率幅值:

总斜率幅值= √[(Gx)2+(Gy)2]

总斜率幅值= √[(11)2+(8)2] = 13.6

接下来,计算每一个像素的方向。能够用tan计算角度。

tan(Φ) = Gy / Gx

所以,角度值为:

Φ = atan(Gy / Gx)

把值带入函数后,得出的方向值为36。因此至此,已经有每一个像素值的总梯度和方向。而后须要使用这些梯度和方向值生成直方图。

但等等——在深刻了解HOG特征描述子中的直方图是如何建立的以前,先休息一下。把这想做整个过程当中的一个小步骤。文中将先讨论使用已拥有的两个值——梯度和方向来建立直方图的一些简单方法。

使用梯度和方向建立直方图的方法

直方图是展现一组连续数据分布频率的图表。已有x轴上的变量(bin形式)和y轴上的频率。本文中使用x轴上的角度或方向,y轴上的频率。

方法1:

首先是最简单的生成直方图的方式。使用每一个像素值,找出像素的方向并更新频率表。

下图是高亮的像素值(85)的过程。由于此像素的方向值为36,因此针对此值在36上方填入一个数字,以表示频率:

来源: 机器学习应用课程

对全部像素值重复此过程,直至标记完图像中这些角度和出现频率表。这个频率表可以使用x轴的角度值和y轴的频率值生成直方图。

这是建立直方图的一种方法。注意,此处直方图的bin值为1。由此获得约180个不一样的bucket,每一个表明一个方向值。另外一种方法是为更大的bin值建立直方图特征。

方法2:

此法与方法1相似,惟一的不一样是bin的大小为20。因此,得出bucket的数量为9。

随后,检查每一个像素的方向并存储9x1矩阵中方向值的频率。绘制此图得出直方图:

来源: 机器学习应用课程

方法3:

以上两种方法仅用方向值生成直方图,没有将梯度值考虑在内。方法3是生成直方图的另外一种方法——将梯度幅值填入矩阵,而不是频率。请看下图示例:

来源:机器学习应用课程

可能会注意到,使用方向值30,只更新为20的bin值。另外,还应该给其它bin增长一些权重。

方法4:

此法对方法4作出一些微调。在此,将像素梯度的contribution值加到像素梯度任意一边的bin中。请记住,bin值越接近方向值的,contribution更高。


来源:机器学习应用课程

这就是HOG特征描述子建立直方图的方式。

第4步:计算8x8单元(9x1)的梯度直方图

HOG特征描述子中建立的直方图不是为整幅图像生成的。相反,图像被分红8x8的几个单元,且为每一个单元计算定向梯度直方图。你以为这会发生什么呢?

这样作获得更小区域的特征(或直方图),相应地表明整幅图像。在此固然能够将8x8的值改成16x16或32x32。

若是将图像分为8x8单元并生成直方图,相应每一个单元会获得一个9x1的矩阵。此矩阵使用上文提到的方法4生成。

一旦为图片中8x8的区域生成HOG,接下来就是进行直方图规范化。

第5步:在16x16单元(36x1)中进行梯度规范化

理解规范化如何进行以前,先理解这样作的缘由很重要。

尽管已经为图像8x8单元建立了HOG特征,图像的梯度对总体的亮度尤其敏感。这意味着对于一张特定图片,图像的某一部分与其余部分相比会很是明亮。

虽然没法今后图像中完全清除亮度的差异,可是能够经过对16x16区域进行梯度规范化来减弱亮度变化。下图例子能够解释16x16区域是如何建立出来的。

在此合并四个8x8单元建立一个16x16的区域。已知每一个8x8的单元的直方图有一个9x1矩阵。因此,此处应有4个9x1矩阵或者一个36x1矩阵。为对矩阵进行规范化,用每个值除以值的平方和的平方根。给定的向量V的数学表示为:

V = [a1, a2, a3, ….a36]

计算平方和的平方根数值:

k = √(a1)2+ (a2)2+ (a3)2+ ….(a36)2

用向量V中的每个值除以k:

结果将是一个大小为36x1的规范化向量

第6步:完整图像特征

目前处于为图像生成HOG特征的最后一步。至此,已经为图像中的16x16区域建立特征。如今将全部特征合并用于得到最终图片的特征。

你能猜出给定图像最终的特征总数是多少吗?首先须要求出一个64×128图像能够获得多少16×16大小的区域:

105(7x15)块16x16区域。每一块都有一个36x1的向量做为特征。所以,图片的特征总数为105x36x1=3780个。

如今已为一幅图片生成了HOG特征,文末还会验证是否获得了相同数量的特征。

在Python中应用HOG特征描述子

是时候打开Python了!笔者敢保证这是本文最使人期待的部分。一块儿看下去吧。

下文将显示一幅图的HOG特征是如何生成的,以及一样的方法可否应用于更大的数据集。首先下载所需的数据库和即将要建立HOG特征的图像:

#importing required libraries

from skimage.io import imread, imshow

from skimage.transform import resize

from skimage.feature import hog

from skimage import exposure

import matplotlib.pyplot as plt

%matplotlib inline

#reading the image

img = imread('puppy.jpeg')

imshow(img)

print(img.shape)

(663, 459, 3)

由上可见,图像大小为663x459。须要将图像大小变为64x128。请注意,文中所使用的是skimage,其须要输入高度x宽度。

#resizing image

resized_img = resize(img, (128,64))

imshow(resized_img)

print(resized_img.shape)

(128, 64, 3)

本文中将直接使用skimage.features的hog函数。所以没必要单独计算梯度、幅值(总梯值)和方向。hog函数将在内部计算它并返回特征矩阵。
此外,若是设置参数为‘visualize = True’,它将返回一张HOG的图像。
#creating hog features
fd, hog_image = hog(resized_img, orientations=9, pixels_per_cell=(8, 8),
cells_per_block=(2, 2), visualize=True, multichannel=True)
在继续前,先介绍一下这些超参数都表明什么。

· orientations是所建立的bucket数量。由于本文中想获得一个9x1的矩阵,因此将orientations设置为9。

· pixels_per_cell定义所建立直方图的单元尺寸。本文中所涉及的例子都使用了8x8单元,在此将设置相同的值。正如上文所提,你能够选择改变这个值。

· 另外一个超参数cells_per_block指所规范化的直方图上的小块区域大小。本文提到的单元是指每小块区域,而不是像素的数量。因此,此处用2x2表示,而不是16x16。

函数的特征矩阵存储在变量fd中, 图像存储于hog_image中。检查一下特征矩阵的大小:

fd.shape

(3780,)

正如预期那样,共有3780个图像特征,这验证了以前在第7步中所作的计算。你能够选择更改超参数的值,这将提供不一样大小的特征矩阵。

最后,来看一看HOG图像:

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 8), sharex=True, sharey=True)

ax1.imshow(resized_img, cmap=plt.cm.gray)

ax1.set_title('Input image')

# Rescale histogram for better display

hog_image_rescaled = exposure.rescale_intensity(hog_image, in_range=(0, 10))

ax2.imshow(hog_image_rescaled, cmap=plt.cm.gray)

ax2.set_title('Histogram of Oriented Gradients')

plt.show()

留言 点赞 关注

咱们一块儿分享AI学习与发展的干货
欢迎关注全平台AI垂类自媒体 “读芯术”


(添加小编微信:dxsxbb,加入读者圈,一块儿讨论最新鲜的人工智能科技哦~)

相关文章
相关标签/搜索