HoG描述子

前言

  • 首先声明下,这篇文章不是原创文章,翻译自这http://www.learnopencv.com中的.
  • 原链接:http://www.learnopencv.com/histogram-of-oriented-gradients/
  • 翻译水平有限,不要喷我
  • 没有一字一句的翻译,有些东西我翻译不出来,但是核心我都翻译出来了

开始翻译


介绍与心理鸡汤

 在本文中,我们将学习HoG描述子的细节。我们将学习他的细节,以及在OpenCV,MATLAB中是怎么计算这个HoG的。
 其实很多事情看起来都是神秘复杂的,但是你只要花时间去学习,那这些东西就不在神秘了。如果你是个初学者(在CV领域)并且发现CV很难很神秘,你只需要记住下面这段话:
Q : How do you eat an elephant ?
A : One bite at a time!

描述子是什么

 特征描述子是用来描述一副包含有用信息的图像或者图像patch(注:这个单词真的不知道怎么翻译)。
 一个特征描述子是把一副图像(大小为宽 x 高 x 3)转化成为一个长度为n的特征向量或者数组。在HoG中,输入图像大小为64 x 128 x 3 ,那么输出特征向量的长度为3780。
 首先我们要知道什么是“有用”的信息或者什么是“无用”的信息,在定义“有用”的信息前,我们要知道什么是有用的信息。很显然,特征向量对于在观察图像的时候是没用的,但是在一些任务(图像识别,目标检测)中是有用的。通过HoG中生成的特征向量在SVM应用的非常好。
 但是什么类型的特征是对分类任务有用的,我们将通过一个例子来讨论它。假设我们要创建一个目标检测器去检测衬衫和外套的纽扣。纽扣是圆并且一般会有几个缝纫孔,当你运行一个边缘检测器,通过单独观察图像边缘,很容易知道是否为纽扣。在这个例子中,边缘信息就是“有用”颜色信息就是“没用”。另外,特征需要有判别能力,比如说一个好的特征能够告诉我们,与其他衣服上的纽扣有不同的地方。
 在HoG中,特征是梯度方向的分布,图像中的梯度(x和y的导数)是非常有用的,因为图像中的边缘角点说对应的梯度值是非常大的,我们知道边缘角点比起的区域能够提供很多关于目标形状的信息。

梯度怎么计算?

在接下来的章节会结合例子,详细描述

步骤1:预处理

 在本文中我们把要处理的图像的宽高比限制在1:2,我们在计算HoG前,我们从 720×475中的图像中,用一个100×200的patch提取一张图片,并且缩放到64×128
HoG描述子_第1张图片

步骤2:计算图像的梯度

 为了计算HoG,我们首先要分别计算水平和垂直方向的梯度,最后我们计算梯度直方图。计算梯度我们可以通过下图的kernels计算
HoG描述子_第2张图片
 接下来,我们用下面的公式计算梯度的方向和大小
HoG描述子_第3张图片

 得到下面这个结果
HoG描述子_第4张图片
 梯度图像移除了不必要的信息,但是高亮了轮廓线。换句话说,你看着这个梯度图像,非常容易知道有个人在图像上。
 在每一个像素上,梯度都有大小和方向。对于彩色图像,3个通道的梯度都将被计算出来。然而图像素的梯度值为3个通道中最大的梯度值,角度也是最大角度

步骤3:在 8×8 cells中计算梯度直方图

 在此步骤中,图像被划分成8×8 cells ,并且在8×8 cells 在中计算梯度直方图。
 在学习直方图前,我们先明白为什么要把图像划分成 8×8 cells。一个比较重要的原因是使用特征描述器去描述patch,是因为它能提供紧凑的表示。在8×8的patch中包含了8x8x3 = 192的像素值,patch中的每一个像素的梯度值包含了大小和方向两个值,加起来一共为8x8x2 = 128。在这一节最后我们将明白如何把这128个值如何用9-bins的直方图来表示,并且存储在一个长度为9的数组。这种方法不仅使得表达紧凑,而且使得对噪声鲁棒性更好。
 但是为什么是8×8,这个根据你想要提取的特征来决定,直方图有9个bins,把180度划分成0, 20, 40, 60 … 160.让我们看下8×8patch以及他的梯度。这里写图片描述
 接下来我们要在8×8的patch中创建一个9-bins的直方图在下面例子中,在蓝色圈中的像素的方向是80度,大小为2,所以我们在bin为80的格子里面加2。在红色圈中的像素为10度,大小为4,但是bin中没有10这个值,只有0和20,所以我们把4平均分配到bin为0和20的格子中。
这里写图片描述
还有一点需要注意到的如果某个像素的方向超过了160,但是bins中并没有180的格子,在这里我们要注意这个直方图是首尾相连的(即180就是0,想象成一个圆),然后我们把像素值按比例分配(根据像素的角度距离谁近,谁就分配的多的原则)到0和160的格子中,如下图。
这里写图片描述
然后我们对patch中所有的像素做同样的操作,就得到下图了。通过图我们可以知道,直方图中接近于0度(180)的比例很大,所以这个patch的方向可以认为是向上或者向下
这里写图片描述

步骤4:标准化16×16 Block

 首先解释下为什么要标准化,我们前面得到的直方图,但是它对光照的大小非常敏感。比如说,我们的图像值全部减少了一倍,那么梯度值也为减少一倍,但是我们不希望图像值影响到梯度值,所以我们要标准化它。
 接下来解释下,为什么标准化可以使得梯度值不受图像值变化的影响。假设一个 RGB 颜色向量为 [ 128, 64, 32 ]. 它的长度为146.64,这个值是用L2范数公式来计算的。接着我们让颜色向量同时除以长度得到 标准化向量[0.87, 0.43, 0.22]。然后我们将颜色向量下面的变换2 x [ 128, 64, 32 ] = [ 256, 128, 64 ],我们按同样方法计算标准化向量得到的依旧是[0.87, 0.43, 0.22]。
 现在我们知道了如何标准化向量,接下来就是对16x16的block(里面有4个cell)进行标准化。从下图中我们可以知道,蓝色窗口通过每次移动8个像素点来计算一个 36×1的标准化向量。
HoG描述子_第5张图片

步骤5:计算HoG特征向量

 通过连接36×1的标准化向量来形成一个大向量。向量的大小为7×15×36= 3780.这里面的7代表的意思是:上图中蓝色的block从左移动到右需要7次,15就是从上到下需要15次,也就是说一共有7×15个blocks。36就是一个block中的4个cells(每个cells有9个bins)的bins的总和。所以最后这个patch的向量大小为3780。

你可能感兴趣的:(opencv,hog)