01 什么是HOG特征
1.1 HOG特征简介
我们先来从字面入手分析一下HOG特征的名字。
HOG特征是图像的一种特征,图像的特征其实就是图像中某个区域的像素点在经过某种四则运算后所得到的结果。
它可以是一个具体的数值,可以是一个向量,可以是一个矩阵,当然他还可以是一个n维的数组。
它远没有名字看上去那么神秘。。。。。
说过了我认为的图像特征的定义,我们再来看今天的主角,HOG特征。 它的全名应该叫做Histogram Of Oriented Gradient , 中文是方向梯度直方图。
HOG 是由 Navneet Dalal & Bill Triggs 在 CVPR 2005发表的论文中提出来的,目的是为了更好的解决行人检测的问题。
我们看一下百度百科上对于HOG特征的定义: 方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子。HOG特征通过计算和统计图像局部区域的梯度方向直方图来构成特征。
其实从名字上来看,我们应当不难理解HOG特征所描述的是什么,或者说他描述的是图像的哪种特征。
方向梯度直方图 可以看出他描述的是关于梯度的一些东西,它的本质是个直方图。
说到直方图,你脑海中最先想到的画面是什么呢?
是它嘛?????
反正,说到直方图,在我的脑海里最先想到的就是小学课本上关于概率的数学题的配图。。。。
其实HOG特征所描述的和它相似。
横轴取了一定间隔的值的范围,纵轴表示某个区间的值有多少个(频数)。
给出一组数据(下图矩阵)让我们来简单的动手画一下它的直方图。
我们首先要考虑的是X轴上的取值间隔问题,比如我们取10,那么数字0-9看成一类、10-19看成一类,如此类推。
如图所示,0-9有{6、5、9} 3个,10-19有{12、17}两个。。。。。
我们绘制出如下的直方图
我们姑且称他为 一组随机数的直方图
那么我们再来类比HOG(方向梯度直方图),是不是可以认为HOG特征统计的就是某个方向区间内的梯度呢?
我们后面再来看
1.2 HOG特征的主要思想:( 摘自百度百科 )
在一副图像中,局部目标的表象和形状能够被梯度或边缘的方向密度分布很好地描述。其本质为:梯度的统计信息,而梯度主要存在于边缘的地方。
1.3 HOG特征的优缺点
与其他的特征描述方法相比,HOG有很多优点。
首先,由于HOG是 在图像的局部方格单元上操作,所以它对图像几何的和光学的形变都能保持很好的不变性,这两种形变只会出现在更大的空间领域上。
其次,在粗的空域抽样、精细 的方向抽样以及较强的局部光学归一化等条件下,只要行人大体上能够保持直立的姿势,可以容许行人有一些细微的肢体动作,这些细微的动作可以被忽略而不影响 检测效果。
因此HOG特征是特别适合于做图像中的人体检测的 。
02 HOG算法的实现
2.1 预备部分
名词解释
在说具体的算法之前,要先对HOG特征中需要用到的一些名词做一定的了解。
边看图边想象边理解吧。。。。
图中我标出了序号,下面开始对号入座。。。。
(1) image
这个不需要过多的解释,就是整个输入。
(2) Window
(看了很多博客,少有提到这个概念,如果说错了可以留言让我改正)
window就是包含你要检测的整个目标的一个窗口。 可以脑补一下上面的图其实是这样的一张图像,一个人站在一片开满了油菜花的田野里,嗯哼?就是这样。。。。你要检测行人,你就需要用这个window把你的行人给框住。因为window是整个HOG计算的最顶层,也就是说我们每次计算HOG特征,计算的并不是整幅图像的,而是一个window范围内的HOG特征。
( 因为后续要用到对于size的计算,所以我们简单的提一下
我们的window可以是任意尺寸的(arbitrary的),这里使用官方推荐的 64 x 128 )
(3) block
可以看出,block是window中的一个滑框。
window的长和宽最好是block长宽的整数倍, 这里依旧使用官方推荐的16x 16
(4) cell
cell 又是block的下一级了,这里注意,cell是不可滑动的
size 依旧是官方推荐,,,,8x8
(5) bin
bin在图中并没有给出,它代表的是直方图区间;
上面我们在说到普通直方图绘制的时候提到过这个区间的问题,当时我们选择的是10,即0-9为一组。
HOG叫做方向梯度直方图,这个直方图的X轴代表的是像素梯度的方向,所以我们也要考虑其区间问题。
方向肯定是以角度来描述的,这个区间的意思就是说要将360度分为几份(或者是180度,后面会说到这个)。
( 这里可能会有些费解,但是我实在是想不到什么好方法来描述了。。 )
一般来说bin的值为9
HOG特征的维度
与我们之前说到的haar特征不同,HOG特征有很高的维度。其具体的计算方式如下:
xxxxxxxxxxxxxx
( 维度不能脱离图像的尺寸存在,我们图像的尺寸与cell,block的尺寸均为上述的官方推荐值 )
对于最小的计算单元cell, 8x8尺寸的cell,其所产生的方向梯度直方图在最后会被转换成为一组单维向量,
因为bin的值为9,所以每个cell产生9个特征。
每4个cell 组成一个block,(注意,cell 是不滑动的)。
对于64*128的图像而言,若将Block的滑动步长取为8,那么水平方向将有7个扫描窗口,垂直方向将有15个扫描窗口,
共计105个扫描窗口。
所以 一个64*128大小的图像最后得到的特征数为9*4*7*15=3780个。
2.2 算法实现
HOG特征的具体提取步骤如下
(这是百度百科上扒下来的,可能有些不太好懂,后面我会结合我自己的一些理解。)
1、色彩和伽马归一化
为了减少光照因素的影响,首先需要将整个图像进行规范化(归一化)。在图像的纹理强度中,局部的表层曝光贡献的比重较大,所以,这种压缩处理能够有效地降低图像局部的阴影和光照变化。
2、计算图像梯度
计算图像横坐标和纵坐标方向的梯度,并据此计算每个像素位置的梯度方向值;求导操作不仅能够捕获轮廓,人影和一些纹理信息,还能进一步弱化光照的影响。
最常用的方法是:简单地使用一个一维的离散微分模板在一个方向上或者同时在水平和垂直两个方向上对图像进行处理,更确切地说,这个方法需要使用滤波器核滤除图像中的色彩或变化剧烈的数据。
3、构建方向的直方图
细胞单元中的每一个像素点都为某个基于方向的直方图通道投票。投票是采取加权投票的方式,即每一票都是带有权值的,这个权值是根据该像素点的梯度幅度计算出来。可以采用幅值本身或者它的函数来表示这个权值,实际测试表明: 使用幅值来表示权值能获得最佳的效果,当然,也可以选择幅值的函数来表示,比如幅值的平方根、幅值的平方、幅值的截断形式等。细胞单元可以是矩形的,也可以是星形的。直方图通道是平均分布在0-1800(无向)或0-3600(有向)范围内。经研究发现,采用无向的梯度和9个直方图通道,能在行人检测试验中取得最佳的效果。
4、将细胞单元组合成大的区间
由于局部光照的变化以及前景-背景对比度的变化,使得梯度强度的变化范围非常大。这就需要对梯度强度做归一化。归一化能够进一步地对光照、阴影和边缘进行压缩。
采取的办法是:把各个细胞单元组合成大的、空间上连通的区间。这样,HOG描述符就变成了由各区间所有细胞单元的直方图成分所组成的一个向量。这些区间是互有重叠的,这就意味着:每一个细胞单元的输出都多次作用于最终的描述器。
区间有两个主要的几何形状——矩形区间(R-HOG)和环形区间(C-HOG)。R-HOG区间大体上是一些方形的格子,它可以有三个参数来表征:每个区间中细胞单元的数目、每个细胞单元中像素点的数目、每个细胞的直方图通道数目。
5、收集HOG特征
把提取的HOG特征输入到SVM分类器中,寻找一个最优超平面作为决策函数。
自己的理解(与上面的算法实现步骤一一对应):
首先是关于 色彩和伽马归一化 , 这一步应该算是一个图像的预处理过程,这里我们着重说HOG特征的提取部分,暂时略过这个预处理过程,这里我们只需要知道这一步的作用就OK了。
关于计算图像梯度
求方向梯度直方图(HOG)嘛,那自然不能少了梯度的计算了,这里的梯度指的是每一个像素的梯度。
cell是计算直方图的基本单位, 我们从cell开始来入手分析HOG特征的实现。
(这里的cell我们默认为8x8大小)我们计算cell中每个像素的梯度,
要描述一个像素的梯度,需要从两方面入手,即幅值与方向。
我们这里也使用模板来计算特征。
首先用 [-1,0,1] 梯度算子对原图像做卷积运算,得到水平方向(以向右为正方向)的梯度分量 a 。
然后用 [1,0,-1]T 梯度算子对原图像做卷积运算,得到竖直方向(以向上为正方向)的梯度分量 b 。
幅值 = 根号下 ( a^2 + b^2 )
角度 = arctan( a/b)
之后我们要为这8x8个像素计算直方图。
这次的x轴表示的是梯度的方向,我们将其定义为9个区间
这里在区间定义上,我发现了两种方法:
一种是在180度上,每20度定义一个;
另一种是在360度上,每40度定义一个(但这40度并不是连续的,而是0-20 加上 180-200)。
期初我以为其中有一个是错误的,但其实这两种都是可以的,
(直方图通道是平均分布在0-1800(无向)或0-3600(有向)范围内。经研究发现,采用无向的梯度和9个直方图通道,能在行人检测试验中取得最佳的效果。)-----节选自百度百科
说了这么多,不如举个例子来的实在;
譬如我们选取了一个size 为3x3的cell ,这个cell里有9个像素点,我们的bin(直方图区间)也为 9 个,
(注意,这里两个取值虽然都是9,但是并没有一丝丝丝丝丝丝的关系,不要随便做出联想。)
我们使用上述的模板计算出了梯度的幅值与方向
幅值: →
方向 : →
各个区间先列出来,分别是:0-20、20-40、40-60、60-80、80-100、100-120、120-140、140-160、160-180,区间的右端点是不包含的。
我们计算的时候先看方向矩阵,首先左上角的值是 90度,那就落在了 80-100 的区间,幅值矩阵对应位置的值是 6,因此 80-100 这个区间的 y 轴值加 6。再看方向矩阵的第一行第二列,也是 90,幅值矩阵对应值是 12,于是 80-100 这个区间再加 12,现在总的值是 18 了,相信到这里你已经看懂了,如此类推继续算下来,就可以得到这样一个直方图:
我们将其称为cell的 descriptor(描述子)
【关于bin的投影】
【如果角度正好在这个bin区域的中心,则幅值大小取原值;若不在中心位置,则需要乘上一个夹角相关的函数】
到这里就完成了cell 部分的计算了,接下来是它的上一层,也就是block的计算,,,,
block是由多个cell所组成的,典型的组合方式是 2x2 个 cell 组成成一个 block,也就是跟图示的一样。
我们知道每个 cell 上面都有一个 9 维的表示直方图大小的向量,那么一个 block 上就有 2x2x9 = 36维的向量。
既然在cell中都已经做出方向梯度直方图了,那么block的作用是什么呢????
其实,在block要做的操作就是把每一次选中的这 36 维向量做规范化(normalization),得到新的 36 维向量。
规范化的方法有多种可选:
将block内所有cell的descriptor串联起来, 便得到该block的 HOG特征描述子 descriptor。
将window内的所有block的HOG特征descriptor串联起来就可以得到最终(你要检测的目标)的HOG特征descriptor了。
这个就是最终的可供分类使用的特征向量了,你可以将它送入SVM中,从而得到最终的输出结果。
文中的案例与部分章节参考于这为朋友的文章,万分感谢。
https://www.jianshu.com/p/ed21c357ec12
采用梯度幅值量级本身得到的检测效果最佳,而使用二值的边缘权值表示会严重降低效果。采用梯度幅值作为权重,可以使那些比较明显的边缘的方向信息对特征表达影响增大,这样比较合理,因为HOG特征主要就是依靠这些边缘纹理。