(一)特征检测算法的综述
计算机视觉理论中的特征描述是常见的目标分析技术之一,关键点的检测和关键点的提取是目标分析的重要手段和重要步骤之一。局部图像特征描述的核心问题是不变性和可分析性,不变性是基于特征描述对于视角变化的不变性、尺度变化的不变性以及旋转变化的不变性,可分性是基于图像的局部内容的可分性。但是,在实际应用中,不变性和可分性是相互矛盾的。OprnCv中有许多特征检测和提取的算法,例如:SIFT、SURF、ORB、LBP、HOG;Harris角点检测算法、FAST角点检测算法、Harr等。
(二)方向梯度直方图HOG的简介
Histogram of Oritentd Gradients,缩写为HOG,是目前计算机视觉、模式识别领域很常用的一种描述图像局部纹理的特征。它通过计算和统计图像的局部区域(Cell和Block)的方向梯度直方图来构成特征,按照我的理解就是,先将一整幅图像像划分为大小相等的Cell小区域,比如说,先将图像划分为20pixel*20pixel的小区域,然后,分别计算这些小区域的梯度方向直方图;然后,再由一定数量的小区域组成稍微大一点的区域Block,比如说由2*2个Cell小区域组成1个Block区域,然后,再由Block区域的方向梯度直方图特征向量组成整幅图像的方向梯度直方图HOG的特征向量;现在,这个特征向量就可以唯一的描述这幅图像,就像一个人的身份证编号(特征向量)一样,可以代表描述一个人。求出一幅图像的HOG特征向量之后,这个特征向量就可以结合SVM,实现目标检测,以图搜图;HOG+SVM刚开始的时候,是被广泛用于行人检测的,当然也可以用于其它方向的检测或者以图搜图等领域。
(三)方向梯度直方图HOG算法的大致步骤如下所示:
1)归一化处理
归一化处理操作的目的是:为了提高图像特征描述符对光照以及环境变化的鲁棒性,降低图像局部的阴影、局部曝光过多及纹理失真,尽可能的抑制图像的干扰噪声。归一化处理操作是先将图像转化为灰度图像,再利用Gamma校正实现。
2)分割图像
因为方向梯度直方图HOG是一个描述图像局部纹理信息的局部特征描述符,因此,如果直接对一大幅图像及逆行特征提取的话,将会得不到好的效果。因此,我们需要先将图像划分为较小的方格单元,比如我们在程序中先将图像划分为20*20大小的放格单元Cell,然后2*2个Cell组成一个Block,最后,所有的Block组成图像。
HOG图像的划分一般有两种策略,重叠和不重叠,即overlap和non-overlap两种。这两种划分策略应该很好理解。就不多说了,直接看一下non-overlap的划分策略示意图,如下图所示:
对于图像I(x,y),计算图像在水平方向和垂直方向上的梯度,这一步我们可以利用OpenCv中的一阶微分算子Sobel计算得到。
3)计算每个Cell的方向梯度直方图
将图像划分为小的Cell之后,接下来就是计算每一个Cell的方向梯度直方图,我们可以利用OpenCv中的一阶微分算子函数Sobel对每一个小区域求解X方向和Y方向上的梯度图像。然后,再根据下面的公式(1)和公式(2)计算每一个小区域中每一个像素点的梯度方向和梯度幅值。

通过上面公式计算出来的梯度方向的角度是一个范围在0~360度的弧度值,为了计算简单,我们将梯度向的范围约束为0~180度,并且分割为9个方向,每个方向20度,再将约束后的角度除以20,则现在的梯度方向角度值就变为范围在[0,9),我们现在将每个小Cell里面的梯度幅值按照这9个方向进行统计,计算完之后,将会产生一个横坐标X为梯度方向,纵坐标Y为梯度幅值的方向梯度直方图。
4)特征向量归一化
为了克服光照不均匀的变化以及前景和背景测对比差异,需要对每个小区域计算出来的特征向量进行归一化处理。在程序中,我们直接使用OpenCV中的normalize函数中的CV_L2范数进行归一化处理。
5)HOG特征向量的生成
首相,我们将图像中的小Cell的HOG特征向量组成比较大的Block的HOG特征向量,具体组合方式就是利用2*2个Cell组成一个Block。然互再将所有的Block的HOG特征向量组成全图像的HOG特征向量。特征向量的具体组合方式是将小的特征向量按照首尾相接的方式组成一个维数比较大的特征向量。比如,一幅图像被分为m*n个Block,每一个Block的特征向量的维数为9维(每一个梯度方向就是一维)。那么,这个图像最终的特征向量维数就是m*n*9。
(四)积分图像
在计算HOG方向梯度直方图特征时,如果按照上面说的直接对每一个小块进行梯度、梯度幅值、角度的计算,然后在进行统计,这样做的话,HOG的计算复杂度将会十分大,因此,我们可以将积分图的概念引入HOG的计算,以便加速HOG的计算性能。
积分图就是:对于一幅灰度图像而言,如果每一像素点的灰度值等于该像素点左上矩形区域所有像素点的灰度值之和,那么这幅图像就是积分图像。
1)为什么要用积分图像
图像直方图的计算方法为:遍历图像中的全部像素并累加计算每个灰度强度值出现的次数。但是,有时候需要计算图像中多个特定区域的直方图的,如果按照上面的计算方法进行计算的话,这个求解过程将会变得十分的耗时。在这种情况下使用积分图像将会极大的提高统计图像子区域像素的效率。
3)OpenCv中计算积分图像的C++接口
按照积分图的概念,P0点的像素强度积分值就是蓝色方框中的所有像素点的强度累加和,P3点的像素强度累加和就是黄色区域所有像素强度的累加和。从上述图像可知,想要从原始图想获得积分图像,只需要对原始图像进行一次扫描。为了防止累加和过大产生溢出现象,积分图像通常使用CV_32S或者CV_32F类型的矩阵或者图像存储。对于多通道图像,每个通道将独立的计算各自的积分图像。
这样的话,如果我们需要计算图像中任意的某一特定区域的像素强度的话,我们只需要进行加减运算,而不需要变量图像。例如现在我们需要计算像素点P0,P1,P2,P3围城的矩形区域的像素强度累加,只需要按照下面的这个公式计算就可以了:
矩形区域的像素强度值 = P3 -P1 - P2 + P0
另外,由于网上关于积分图的概念和定义不是那么的一致,现在我们给出OpenCv官方文档的参考资料,关于积分图的计算介绍如下所示:
(五)基于OpenCv和C++方向梯度直方图HOG特征向量描述符的实现
具体的程序如下所示,至于在HOG中引入积分图思想之后,HOG算法的计算流程,程序中已经做了详细的说明。