本博文为HOG、LBP与Haar算子的学习笔记。
方向梯度直方图HOG
主要参考博文如下:
https://blog.csdn.net/wjb820728252/article/details/78395092(这篇博文翻译水平真的太烂了,可以参考里面给的原链接)
https://blog.csdn.net/liulina603/article/details/8291093
参考书籍:《Opencv图像处理编程实例》
Histogram of Oriented Gradients,HOG是应用在计算机视觉和图像处理领域,用于目标检测的特征描述器。这项技术是用来计算局部图像梯度的方向信息的统计值。是Dalal于2005年针对行人检测问题提出的直方图特征,常用于计算机视觉和图像处理中的目标物体检测与特征分析。(论文原文:https://wenku.baidu.com/view/676f2351f01dc281e53af0b2.html)
方向梯度直方图HOG特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子。它通过计算和统计图像局部区域的梯度方向直方图来构成特征。HOG特征结合SVM分类器已经被广泛应用在行人检测中。
特征描述符是指通过提取有用的信息并抛弃无关的信息来表示这一张图片或者一张图片的一部分。
从图像中提取有用信息,什么是有用信息呢?所提取的特征向量对于查看图像是没有用的,但是对于图像识别或者目标检测等任务则是非常有用。在HOG中,梯度方向(梯度)的分布(直方图)作为特征。图像的梯度的大小在边缘和拐角处(强度突变的区域)较大,而在边和角的形状信息比平面多很多,故此可以以此作为特征。
HOG的主要思想:在一幅图像中,局部目标的表象和形状(appearance and shape)能够被梯度或边缘的方向密度分布很好地描述。(本质:梯度的统计信息,而梯度主要存在于边缘的地方)。
HOG的具体实现方法是:首先将图像分成小的连通区域,我们把它称为细胞单元。然后采集细胞单元中各像素点的梯度或边缘的方向直方图。最后把这些直方图组合起来就可以构成特征描述器。
HOG特征的优点:首先,由于HOG是在图像的局部方格单元上操作,所以它对图像几何的和光学的形变都能保持很好的不变性,这两种形变只会出现在更大的空间领域上。其次,在粗的空域抽样、精细的方向抽样以及较强的局部光学归一化等条件下,只要行人大体上能够保持直立的姿势,可以容许行人有一些细微的肢体动作,这些细微的动作可以被忽略而不影响检测效果。因此HOG特征是特别适合用于做图像中的人体检测的。
HOG原理
图像直方图中特征值为由的像素构成的特征直方图为:
其中,表示像素个数的归一化处理值,特征直方图反映出来的是某一特征的概率分布。对于灰度图像,直方图就是灰度信息统计概率分布,对进行累计,得到对应的累计直方图为:
HOG的原理是通过计算和统计图像局部区域的梯度方向直方图来实现特征描述的。对于一幅图像,它在点处的梯度幅度为:
梯度的方向角为:
其中,与分别为x方向与y方向的梯度,HOG在进行特征描述时将梯度方向角在区间划分为N个均匀空间,像素点在k个梯度方向上的梯度投影为:
HOG特征提取步骤:
图像梯度方向直方图就是对图像中所有像素点K维梯度特征的直方图统计,将图像划分成小部分连通域,对细胞单元的各个像素点进行梯度方向直方图描述,最后组合成相应的特征描述器。
1、预处理
由于颜色信息作用不大,通常先转换为灰度图像。
然后进行归一化处理。归一化操作是为了提高图像特征描述对光照及环境变化的鲁棒性,降低图像局部的阴影、局部曝光过多及纹理失真,尽可能抑制噪声干扰。采用Gamma伽马校正法对输入图像进行颜色空间的标准化(归一化)。目的是调节图像的对比度,降低图像局部的阴影和光照变化所造成的影响,同时可以抑制噪声的干扰。
为了减少光照因素的影响,首先需要对整个图像进行规范化(归一化)。在图像的纹理强度中,局部的表层曝光贡献的比重较大,所以,这种压缩处理能够有效地降低图像局部的阴影和光照变化。
Gamma压缩公式:
特征描述符将大小宽度*高度*3(RGB通道)的图像转换为特征向量数组,长度为n。此处分析中采用64*128。如下图所示,一幅尺寸为720*475的图像,在计算HOG特征描述符时选择大小为100*200的图像,再将该图像提取与剪裁为64*128大小。
2、计算图像梯度
梯度包括了方向和大小。主要是为了捕获轮廓信息,同时进一步弱化光照的干扰。对于图像,计算图像在处的水平方向梯度,竖直方向梯度为,计算水平与竖直方向梯度只需要对图像进行模板卷积即可得到,水平模板为[-1,0,1],竖直模板为。通过使用下图所示的内核滤波图像则可以实现计算水平和垂直梯度。
通过下面公式计算梯度的大小和方向:
使用任意一种梯度算子,例如:Sobel,Laplacian等,对图像进行卷积,计算得到每个像素点处的梯度方向和幅值。
下面给出用opencv实现梯度计算的程序
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("666666.jpg");
imshow("原图", img);
img.convertTo(img, CV_32F, 1 / 255.0);//见下面程序补充,用于转换不同数据类型的Mat
imshow("convertTo", img);
//计算图像梯度
Mat gx, gy;
//求x梯度
Sobel(img, gx, CV_32F, 1, 0, 1);//Sobel边缘检测算子,见下面程序补充
Sobel(img, gy, CV_32F, 0, 1, 1);
imshow("gx", gx);
imshow("gy", gy);
//使用函数cartToPolar计算梯度的大小和方向
Mat mag, angle;
cartToPolar(gx, gy, mag, angle, 1);
imshow("mag", mag);
imshow("angle", angle);
waitKey(0);
return 0;
}
结果如下图所示:
梯度x在垂直方向延伸,梯度y在水平方向延伸。梯度的强度在图像强度突变的地方有急剧的变化。
关于上述代码的补充:
关于openCV中convertTo的用法
关于Sobel函数:
可参考博文:https://blog.csdn.net/poem_qianmo/article/details/25560901
3、统计图像梯度
将图像划分为小的cells,如8*8个方格单元,统计每个cell的梯度直方图(不同梯度的个数),即可形成每个cell的descriptor。
将几个cell组成一个block,如2*2个单元组成一个块,然后对属于块内的像素点进行投票统计,计算每个方块单元的梯度特征,每个像素点梯度方向都采用线性插值,将每个方块单元梯度特征组合在一起。一个block内所有cell的特征descriptor串联起来便得到该block的HOG特征描述子。将图像内的所有block的HOG特征描述子串联起来就可以得到该图像的HOG特征描述子了,这个就是最终可供分类使用的特征向量
(1)为每个细胞单元构建梯度方向直方图。将图像分成若干个“单元格cell”,例如每个cell为6*6个像素。假设我们采用9个bin的直方图来统计这6*6个像素的梯度信息。也就是将cell的梯度方向360度分成9个方向块。如下图所示,例如,如果这个像素的梯度方向是20-40度,直方图第2个bin的计数就加一。这样,对cell内每个像素用梯度方向在直方图中进行加权投影(映射到固定的角度范围),就可以得到这个cell的梯度方向直方图了,就是该cell对应的9维特征向量(因为有9个bin)。而对于梯度的大小,则是作为投影的权值。比如某个像素的梯度方向是20-40度,当它梯度大小是2时,计数就+2;当梯度大小为1时,计数就+1.
(2)把细胞单元组合成大的块(block),块内归一化梯度直方图。由于局部光照的变化以及前景-背景对比度的变化,使得梯度强度的变化范围非常大。这就需要对梯度强度做归一化。归一化能够进一步地对光照、阴影和边缘进行压缩。把各个细胞单元合成大的、空间上连通的区间(block)。这样,一个block内所有cell的特征向量串联起来便得到该block的HOG特征。这些区间是互有重叠的,这就意味着:每一个单元格的特征会以不同的结果多次出现在最后的特征向量中。我们将归一化之后的块描述符(向量)就称之为HOG描述符。
区间有两个主要的几何形状——矩形区间(R-HOG)和环形区间(C-HOG)。R-HOG区间大体上就是一些方形格子,它可以由三个参数来表征:每个区间中细胞单元的数目、每个细胞单元中像素点的数目、每个细胞的直方图通道数目。
例如:行人检测的最佳参数设置是:3*3细胞/区间、6*6像素/细胞、9个直方图通道。则一块的特征数为:3*3*9。
将检测窗口中所有重叠的块进行HOG特征的收集,并将它们结合成最终的特征向量供分类使用。
从博文https://blog.csdn.net/datase/article/details/71374471补充截图如下:
4、特征向量归一化
为克服光照不均匀变化及前景与背景的对比差异,需要对块内特征向量进行归一化处理。首先对每个块内36维特征V进行归一化,即完成操作,其中为很小的常数;然后利用重新进行归一化,同时保持限制V的最大值为0.2。由于相邻块之间可能存在重叠,使得每个单元对块都有影响,因此需要对梯度强度归一化,使每一个单元格特征以不同的结果多次出现在最后的特征向量中。
5、生成特征向量
将图像的每个特征组合在一起,得到图像HOG特征。设定步长为8像素时,相邻块之间会有1~2个相邻单元重叠,每个单元对周围的4个块都有贡献。对于特征维数计算,图像分为m*n个方格单元,且一个方块单元由s*s个方格单元构成,最终得到HOG维数为(m-s+1)*(n-s+1)*(s*s*N)。
把样本图像分割为若干个像素的单元(cell),把梯度方向平均划分为9个区间(bin),在每个单元(cell)里面对所有像素的梯度方向在各个方向区间进行直方图统计,得到9维的特征向量。每相邻的4个单元构成一个块(block),把一个块内的特征向量联起来得到36维的特征向量,用块对样本图像进行扫描,扫描步长为一个单元(cell)。最后将所有块的特征串联起来就得到人体的特征。例如,对于64*128的图像而言,每8*8的像素组成一个cell,每2*2个cell组成一个block,因为每个cell有9个特征,所以每个block内有4*9=36个特征。以8个像素为步长,那么水平方向有7个扫描窗口,垂直方向有15个扫描窗口。也就是说64*128的图像有36*7*15=3780个特征。
下面给出HOG特征的代码:
Opencv中提供了专门用于HOG特征检测的类HOGDescriptor。