CV笔记11:HOG特征


一、写在前面

图像描述子,简单来说就是包含了一张图像主要信息的数据集,它是对图像的简化表示,仅仅含有了图像的重要信息。就如对一篇繁长的文章做了一次简写或概述一样。专业一点,图像描述子,也就是我们常提到的“提取图像特征”中的图像特征,这些特征能够更好地让机器理解图象,直白地说就是该特征能够更好的让决策模性进行分类等决策。图像描述子可以分为人工设计的特征和模性学习到的特征。在本篇中主要讲讲人工设计的HOG图像描述子,重点放在描述子的求解和原理上面,而实现都可以通过opencv等工具包直接实现。

二、HOG(Histogram of Oriented Gradient)特征

Hog特征,中文就是带方向的梯度直方图,是通过计算图像中某一区域的不同梯度方向上的梯度幅值的累加而得到的直方图(当然还有其他的求解方式)。

2.1 Hog特征的求取步骤

  • 图像预处理
  • 计算每个像素的梯度(幅值M和方向)
  • 将图像分成小的cells(如8×8的cells)
  • 统计每个cell的方向梯度直方图,每个cell得到一个使用直方图向量描述图像的特征(描述子)
  • 将每n×n个cell组成一个block,让每个cell的描述子拼接起来,得到该block的描述子
  • 将每一个block的描述子拼接起来,并进行归一化,便得到了整个图像的描述子

我们可以根据以上的流程,先放一个图片进行理解一下,这个图还会在下面过程详细介绍。
在这里插入图片描述

2.2.1 图像预处理

图像预处理一般包括图形的灰度化、伽马矫正(伽马归一化)、降噪、resize等操作。灰度化就是将图像转化为灰度图像以方便计算图像梯度,其实彩色图像也可以直接处理,不过是分别对三个通道的颜色值进行梯度计算,最后选择最大的梯度。伽马矫正是为了减少光照对图像的影响。
除了上面的操作,我们还一般还会对图像的输入尺寸做限定。根据《图像学习-HOG特征》一文中,在计算Hog特征时,输入图像可以为一张图像的一个区块(Patch),也可以是一整张图像。下面都以一个Patch为输入图像。Patch可以是任意的尺寸,但是有一个固定的比列,比如当patch宽高比1:2,那patch大小可以是100×200, 128×256或者1000×2000但不可以是101×205。比如,我们设定Patch宽高比设置为1:2,这时输入图像大小最好是64×128,这是因为我们可以将输入图像分成8×8和16×16的cell来提取特征,在具有指定的大小(64×128)的情况下将使我们的所有计算相当简单,同时多个cell又可以组成block。当然,图像的Patch、cell和block可以根据自己的需求自行定义,在原始论文中使用的Patch宽高比为1:2,cell为8×8。
具体讲讲Gamma变换:
伽马矫正,调节图像对比度,减少光照对图像的影响(包括光照不均和局部阴影),使过曝或者欠曝的图像恢复正常,更接近人眼看到的图像。
伽马矫正公式:

f ( I ) = I γ f(I)=I^\gamma f(I)=Iγ

I I I表示图像, γ \gamma γ表示幂指数。

如图,当 γ \gamma γ取不同的值时对应的输入输出曲线( γ = 1 \gamma=1 γ=1时输入输出保持一致) :
1) 当 γ < 1 \gamma<1 γ<1时,输入图像的低灰度值区域动态范围变大,进而图像低灰度值区域对比度得以增强;在高灰度值区域,动态范围变小,进而图像高灰度值区域对比度得以降低。 最终,图像整体的灰度变亮。

2) 当 γ > 1 \gamma>1 γ>1时,输入图像的高灰度值区域动态范围变小,进而图像低灰度值区域对比度得以降低;在高灰度值区域,动态范围变大,进而图像高灰度值区域对比度得以增强。 最终,图像整体的灰度变暗。
在这里插入图片描述

2.2.2 计算每个像素梯度和方向

为了方便得到梯度直方图,我们预先计算每个像素的梯度(幅值M和方向)。一般使用特定的卷积核对图像滤波实现,可选用的卷积模板有:soble算子、Prewitt算子、Roberts模板等等。具体的梯度计算讲解可以参照文章《CV笔记6:图像边缘检测之一阶微分算子、二阶微分算子、Canny边缘检测(基于python-opencv实现)》的第二节。

2.2.3 将图像分割成小的区域

在实际应用中,我们一般不会直接对一张大幅图像做特征提取,而是把图像分割成很多区块,然后对每个区块计算HOG特征,这样做将能够将图像几何(位置)特性包含进去。这是因为只有图像区域比较小的情况,基于统计原理的直方图对于该区域才有表达能力,如果图像区域比较大,那么两个完全不同的图像的HOG特征,也可能很相似。但是如果区域较小,这种可能性就很小。图像的分割方式一般来说有overlap(右图)和non-overlap(左图)两种,如下图所示。overlap指的是分割出的区块(patch)互相交叠,有重合的区域。non-overlap指的是区块不交叠,没有重合的区域。
在这里插入图片描述
对于overlap,这种分割方式可以防止对一些物体的切割,以眼睛为例,如果分割的时候正好把眼睛从中间切割并且分到了两个patch中,提取完HOG特征之后,将会影响之后的分类效果,但是如果两个patch之间overlap,那么至少在一个patch会有完整的眼睛。overlap的缺点是计算量大,因为重叠区域的像素需要重复计算。
对于non-overlap,缺点就是上面提到的,有时会将一个连续的物体切割开,得到不太“好”的HOG特征,优点是计算量小,尤其是与Pyramid(金字塔)结合时,这个优点更为明显。

2.2.4 计算区块的方向梯度直方图

经过计算,对于每一个像素点都会得到两个值:梯度幅值/梯度方向。在这一步中,我们假设输入的patch被分成若干个8×8的cell,例如我们的patch为64x128的大小,那么这幅图像就被划分为8x16个8x8的cell单元,并为每个8×8的cell计算梯度直方图。当然,cell的划分也可以是其他值:16x16,8x16等,根据具体的场景确定。
以8x8的cell为例,一个8x8的cell包含了8x8x2 = 128个值,因为每个像素包括梯度的大小和方向。
在HOG中,每个8x8的cell的梯度直方图本质是一个由9个数值组成的向量, 对应于0、20、40、60…160的梯度方向(角度)。那么原本cell中8x8x2 = 128个值就由长度为9的向量来表示,用这种梯度直方图的表示方法,大大降低了计算量,同时又对光照等环境变化更加地鲁棒。

首先,看下图:
在这里插入图片描述

左图是衣服64x128的图像,被划分为8x16个8x8的cell;中间的图像表示一个cell中的梯度矢量,箭头朝向代表梯度方向,箭头长度代表梯度大小。

右图是 8×8 的cell中表示梯度的原始数值,注意角度的范围介于0到180度之间,而不是0到360度, 这被称为“无符号”梯度,因为两个完全相反的方向被认为是相同的。

接下来,我们来计算cell中像素的梯度直方图,将0-180度分成9等份,称为9个bins,分别是0,20,40…160。然后对每个bin中梯度的贡献进行统计:

在这里插入图片描述

统计方法是一种加权投票统计, 如上图所示,某像素的梯度幅值为13.6,方向为36,36度两侧的角度bin分别为20度和40度,那么就按一定加权比例分别在20度和40度对应的bin加上梯度值,加权公式为:

20度对应的bin:((40-36)/20) * 13.6,分母的20表示20等份,而不是20度;
40度对应的bin:((36-20)/20) * 13.6,分母的20表示20等份,而不是20度;

还有一个细节需要注意,如果某个像素的梯度角度大于160度,也就是在160度到180度之间,那么把这个像素对应的梯度值按比例分给0度和160度对应的bin。如左下图绿色圆圈中的角度为165度,幅值为85,则按照同样的加权方式将85分别加到0度和160度对应的bin中。

在这里插入图片描述

对整个cell进行投票统计,正是在HOG特征描述子中创建直方图的方式,最终得到由9个数值组成的向量—梯度方向图:

在这里插入图片描述

2.2.5 Block 归一化

HOG特征将8×8的一个局部区域作为一个cell,再以2×2个cell作为一组,称为一个block,也就是说一个block表示16x16的区域。

我们可能会想,为什么又需要分block呢?

这是因为,虽然我们已经为图像的8×8单元创建了HOG特征,但是图像的梯度对整体光照很敏感。这意味着对于特定的图像,图像的某些部分与其他部分相比会非常明亮。

我们不能从图像中完全消除这个。但是我们可以通过使用16×16个块来对梯度进行归一化来减少这种光照变化。

由于每个cell有9个值,一个block(2×2个cell)则有36个值,HOG是通过滑动窗口的方式来得到block的,如下图所示:
在这里插入图片描述

前面已经说明,归一化的目的是为了降低光照的影响,因为梯度对整体光照非常敏感,比如通过将所有像素值除以2来使图像变暗,那么梯度幅值将减小一半,因此直方图中的值也将减小一半,我们就需要将直方图“归一化”。

归一化的方法有很多:L1-norm、L2-norm、max/min等等,一般选择L2-norm。

例如对于一个[128,64,32]的三维向量来说,模长是 12 8 2 + 6 4 2 + 3 2 2 = 146.64 \sqrt{128^2+64^2+32^2}=146.64 1282+642+322 =146.64,这叫做向量的L2范数。将这个向量的每个元素除以146.64就得到了归一化向量 [0.87, 0.43, 0.22]。

采用同样的方法,一个cell有一个梯度方向直方图,包含9个数值,一个block有4个cell,那么一个block就有4个梯度方向直方图,将这4个直方图拼接成长度为36的向量,然后对这个向量进行归一化。

而每一个block将按照上图滑动的方式进行重复计算,直到整个图像的block都计算完成。

2.2.6 获得HOG描述子

每一个16 * 16大小的block将会得到一个长度为36的特征向量,并进行归一化。 那会得到多少个特征向量呢?

例如,对于上图被划分8 * 16个cell ,每个block有2x2个cell的话,那么cell的个数为:(16-1)x(8-1)=105。即有7个水平block和15个竖直block。

每个block有36个值,整合所有block的特征值,最终获得由36 * 105=3780个特征值组成的特征描述符,而这个特征描述符是一个一维的向量,长度为3780。

获得HOG特征向量,就可以用来可视化和分类了。

三、opencv之HOG API

OpenCV中的HOG特征提取功能使用了HOGDescriptor这个类来进行封装,其中也有现成的行人检测的接口。
先看看HOGDescriptor所在的头文件,了解它的构造函数需要哪些参数。

    CV_WRAP HOGDescriptor() : winSize(64,128), blockSize(16,16), blockStride(8,8),
    	cellSize(8,8), nbins(9), derivAperture(1), winSigma(-1),
        histogramNormType(HOGDescriptor::L2Hys), L2HysThreshold(0.2), gammaCorrection(true), 
        nlevels(HOGDescriptor::DEFAULT_NLEVELS)
    {}
CV_WRAP HOGDescriptor(Size _winSize, Size _blockSize, Size _blockStride,  
              Size _cellSize, int _nbins, int _derivAperture=1, double _winSigma=-1,  
              int _histogramNormType=HOGDescriptor::L2Hys,  
              double _L2HysThreshold=0.2, bool _gammaCorrection=false,  
              int _nlevels=HOGDescriptor::DEFAULT_NLEVELS)  
: winSize(_winSize), blockSize(_blockSize), blockStride(_blockStride), cellSize(_cellSize),  
nbins(_nbins), derivAperture(_derivAperture), winSigma(_winSigma),  
histogramNormType(_histogramNormType), L2HysThreshold(_L2HysThreshold),  
gammaCorrection(_gammaCorrection), nlevels(_nlevels)  
{}  
CV_WRAP HOGDescriptor(const String& filename)  
{  
    load(filename);  
}  
HOGDescriptor(const HOGDescriptor& d)  
{  
    d.copyTo(*this);  
}  

我们看到HOGDescriptor一共有4个构造函数,前三个有CV_WRAP前缀,表示它们是从DLL里导出的函数,即我们在程序当中可以调用的函数;最后一个没有上述的前缀,所以我们暂时用不到,它其实就是一个拷贝构造函数。
下面我们就把注意力放在前面的构造函数的参数上面吧,这里有几个重要的参数要研究下:winSize(64,128), blockSize(16,16), blockStride(8,8), cellSize(8,8), nbins(9)。上面这些都是HOGDescriptor的成员变量,括号里的数值是它们的默认值,它们反应了HOG描述子的参数。这里做了几个示意图来表示它们的含义。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

参考

OpenCV HOGDescriptor 参数图解
图像学习-HOG特征
Histogram of Oriented Gridients(HOG) 方向梯度直方图
图像特征工程:HOG特征描述子介绍
HOG特征

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值