【中级】图像特征工程:HOG 特征描述符

英文原文:
https://www.analyticsvidhya.com/blog/2019/09/feature-engineering-images-introduction-hog-feature-descriptor/
边翻译边学习

前言

特征工程是机器学习算法领域重要的角色。这是进行最多次试验的地方:从现有特征中设计新特征并提高我们模型的性能。世界上一些顶级数据科学家们依靠特征工程来提高他们在黑客马拉松中的排行榜分数。我相信你甚至会在结构化数据上使用各种特征工程技术。

我们能否将此技术扩展到非结构化数据,比如图像?对于计算机视觉爱好者来说,这是一个有趣的问题,我们将在本文中解释它。准备好以特征提取的形式对图像数据进行特征工程吧!

我假设你已经阅读了:【初级】使用 Python 从图像数据中提取特征

在本文中,我将向您介绍一种流行的图像特征提取技术——定向梯度直方图( Histogram of Oriented Gradients 或 HOG)。我们将了解什么是 HOG 特征描述符,它的工作原理(算法背后的完整数学),最后,将会在 Python 中实现它。

什么是特征描述符(Feature Descriptor)

下面的两个图像。你能区分图像中的物体吗?


图1

我们可以清楚地分辨右图有一只狗,左图有一辆汽车。现在让这个任务稍微复杂一点,识别下图中显示的物体:


图2

我想你还是可以分辨出吧?图1 有包含很多信息,比如物体的形状、颜色、边缘、背景等。而图2 的信息相对少得多(只有形状和边缘),但足以区分两个图像。

我想你已经对特征描述符有一些感觉了吧?在图2 中,我们很容易区分对象,因为它具有识别对象所需的必要信息。这正是特征描述符的作用:它是图像的简化表示,仅包含有关图像的最重要信息。

以下是一些最受欢迎特征描述符的:

  • HOG:Histogram of Oriented Gradients
  • SIFT:Scale Invariant Feature Transform
  • SURF:Speeded-Up Robust Feature

在本文中,我们将重点介绍 HOG (定向梯度直方图)特征描述符及其工作原理。让我们开始吧!

HOG 特征描述符简介

HOG,是一种特征描述符,常用于从图像数据中提取特征。它广泛用于计算机视觉任务中的目标检测。

让我们看一下 HOG 与其他特征描述符不同的一些重要方面:

  • HOG 描述符侧重于对象的结构或形状。现在您可能会问,这与我们为图像提取的边缘特征有何不同?在边缘特征的情况下,我们只识别像素是否是边缘。HOG 也能够提供边缘方向。这是通过提取边缘的梯度和方向来完成的。
  • 此外,这些方向是在“局部”部分计算的。这意味着完整的图像被分解为更小的区域,并为每个区域计算梯度和方向。
  • 最后,HOG 会分别为这些区域中的每一个生成直方图。直方图是使用像素值的梯度和方向创建的,因此名称为“定向梯度直方图”

对此进行正式定义:HOG 特征描述符是计算图像局部梯度方向的出现次数。

计算 HOG 的过程

我们现在应该对 HOG 特征描述符是什么有了一个基本的了解。是时候深入研究其背后的核心思想了。让我们开始讨论计算 HOG 的分步过程。

考虑以下尺寸 (180 x 280) 的图像。让我们详细了解一下如何为该图像创建 HOG 特征:


0x00 预处理数据 (64 x 128)

这是大多数人都非常熟悉的步骤。预处理数据是任何机器学习项目中的关键步骤,处理图像时也不例外。

我们需要对图像进行预处理并将宽高比降低到 1:2。图像大小最好是 64 x 128。这是因为我们将把图像分成 88 和 1616 块来提取特征。具有指定的大小 (64 x 128) 将使我们所有的计算变得非常简单。事实上,这是原始论文中使用的确切值。

回到我们的例子,让调整原图像为 64 x 128。这是调整后的图像:


0x01 计算梯度(x 和 y 方向)

下一步是计算图像中每个像素的梯度。梯度是 x 和 y 方向的微小变化。这里将从图像中取出一小块并计算其梯度:


我们将获得此区域的像素值。假设我们在给定的区域生成以下像素矩阵(此处显示的矩阵仅用作示例,这些不是给定区域的原始像素值):


图三

这里突出显示了像素值 85。首先确定 x 方向的梯度(或变化),我们需要从右侧的像素值中减去左侧的值。同样,为了计算 y 方向的梯度,我们将从所选像素上方的像素值中减去下方的像素值。

因此,该像素在 x 和 y 方向上的梯度为:

  • X 方向的变化G_x = 89 – 78 = 11
  • Y 方向的变化G_y = 68 – 56 = 8

这个过程会给我们两个新矩阵——一个存储 x 方向上的梯度,另一个存储 y 方向上的梯度。这类似于使用大小为 1 的 Sobel Kernel。当强度发生急剧变化时,例如边缘周围,幅度会更高

我们分别计算了 x 和 y 方向的梯度。对图像中的所有像素重复相同的过程。下一步是使用这些值找到大小和方向。

0x10 计算幅度和方向

使用我们在上一步中计算的梯度,我们现在将确定每个像素值的大小和方向。在这一步中,我们将使用毕达哥拉斯定理,如下图所示:


梯度分为是水平和竖直,对于前面的示例,我们将 G_xG_y 设为 11 和 8。应用勾股定理来计算总梯度幅度:
总梯度幅度 = \sqrt {(G_x)^2+(G_y)^2} \\ = \sqrt {11^2+8^2} = 13.6

接下来计算其方向:
tan(Φ) = \frac {G_y}{G_x}

因此,角度的值将是:
Φ = atan(\frac {G_y}{G_x})

计算结果是 36。对于每个像素值,我们都能计算出其梯度值和方向。我们需要使用这些梯度值和方向生成直方图。

使用梯度和方向创建直方图的不同方法

直方图是显示一组连续数据的频率分布的图。x 轴表示数据值,y 轴表示其频率。在这里,我们将用x 轴表示角度,用y 轴表示频率。

0x00 方法1

让我们从最简单的生成直方图的方法开始。我们将获取每个像素值,找到像素的方向并更新频率表?;故翘致弁既械暮焐袼?85。由于该像素的方向是 36,我们将在角度值 36 上添加一个数字,表示频率:


对所有像素值做重复相同的操作,我们最终得到一个频率表,表示角度和这些角度在图像中的出现次数。此频率表可用于生成 x 轴上的角度值和 y 轴上的频率的直方图。这是创建直方图的一种方法。由于每个桶的是1,所以此处生成了180个大小相同的桶。

0x01 方法2

这种方法与前面的方法类似,不同之处在于这里的每个桶的大小为 20。因此,在这里得到的桶数为 9。同样,对于每个像素,我们将检查方向,并以 9 x 1 矩阵的形式存储方向值的频率?;嬷普饨颐翘峁┲狈酵迹?/p>

0x10 方法3

在这里,我们将像素梯度的贡献添加到像素梯度任一侧的 bin 中。更高的贡献应该是对更接近方向的 bin 值。


这正是在 HOG 特征描述符中创建直方图的方式。

计算 8×8 单元格中梯度的直方图

在 HOG 特征描述符中创建的直方图不是为整个图像生成的。相反,图像被分成 8×8 个单元格,并为每个单元格计算定向梯度的直方图。通过这样做,我们获得了较小块的特征(或直方图),这些块又代表了整个图像。我们当然可以在这里将这个值从 8 x 8 更改为 16 x 16 或 32 x 32。如果我们将图像分成 8×8 个单元格并生成直方图,我们将为每个单元格得到一个 9 x 1 的矩阵。该矩阵是使用我们在上一节中讨论的方法 3 生成的。


一旦我们为图像中的 8×8 块生成了 HOG,下一步就是对直方图进行归一化。

标准化 16×16 单元格中的梯度

我们在了解这是如何完成之前,首先了解为什么要这样做很重要。尽管我们已经为图像的 8×8 单元创建了 HOG 特征,但图像的梯度对整体照明很敏感。这意味着对于特定图片,图像的某些部分与其他部分相比会非常亮。我们无法从图像中完全消除这一点。但是我们可以通过采用 16×16 块对梯度进行归一化来减少这种光照变化。这是一个可以解释如何创建 16×16 块的示例:


在这里,我们将组合四个 8×8 的单元格来创建一个 16×16 的块。我们已经知道每个 8×8 单元格都有一个 9×1 的直方图矩阵。因此,我们将有四个 9×1 矩阵即一个 36×1 矩阵。为了标准化这个矩阵,我们将这些值中的每一个除以这些值的平方和的平方根进行归一化,结果将是大小为 36×1 的归一化向量。

提取完整图像的特征

我们现在处于为图像生成 HOG 特征的最后一步。到目前为止,我们已经为图像的 16×16 块创建了特征。现在,我们将结合所有这些来获得最终图像的特征。

您能猜出给定图像的特征总数是多少吗?我们首先需要找出一张 64×128 的图像有多少这样的 16×16 块?我们将有 105 (7×15) 个 16×16 的块。这 105 个块中的每一个都有一个 36×1 的向量作为特征。因此,图像的总特征将为 105 x 36×1 = 3780 个特征。我们现在将为单个图像生成 HOG 特征,并验证我们最终是否获得相同数量的特征。

在 Python 中实现 HOG 特征描述符

我们将看到如何在单个图像上生成 HOG 特征,以及是否可以将其应用于更大的数据集。

'''
HOG FEATURES
'''

# importing required libraries
from skimage.io import imread, imshow
from skimage.transform import resize
from skimage.feature import hog
from skimage import exposure



#reading the image
img = imread('puppy.jpeg')
#resize image
resized_img = img

#generating HOG features
fd, hog_image = hog(resized_img, orientations=9, pixels_per_cell=(8, 8),
cells_per_block=(2, 2), visualize=True, multichannel=True)

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()

如果不进行 resize,结果如下:


image.png

当然这也会导致速度变慢

这时我们就提取出了对象识别时输入到机器学习中的图片HOG特征了。

最后编辑于
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351