aaa

1)HOG特征的原始文献

"Histograms of Oriented Gradients for Human Detection" 

"Finding People in Images and Videos" (PhD Thesis) (较为详细)


2) HOG特征算子的网络参考资料

http://www.cnblogs.com/tornadomeet/archive/2012/08/15/2640754.html

http://blog.csdn.net/carson2005/article/details/7841443#

http://blog.csdn.net/abcjennifer/article/details/7365651

http://blog.csdn.net/zouxy09/article/details/7929348#




HOG特征描述算子——原理、思路、步骤

-----------------------------------------------------------------------------------

1. HOG特征描述子的定义

HOG Descriptor: locally normalised histogram of gradient orientation in dense overlapping grids,即局部归一化的梯度方向直方图。


2. HOG特征的基本思想

Histogram of Oriented Gradient descriptors provide a dense overlapping description of image regions,即统计图像局部区域的梯度方向信息来作为该局部图像区域的表征。

HOG有点类似于SIFT特征描述子,区别: 
1)HOG没有选取主方向,也没有旋转梯度方向直方图,因而本身不具有旋转不变性(较大的方向变化),其rotate不变性是通过采用不同旋转方向的训练样本来实现的; 
2)HOG本身不具有scale不变性,其scale不变性是通过改变检测图像的size来实现的;

3)HOG是在dense采样的图像块中求取的,在计算得到的HOG特征向量中隐含了该块与检测窗口之间的空间位子关系,而SIFT特征向量是在一些独立并离散分布的特征点上提取的(dense SIFT除外)。


3. HOG特征的假设和出发点

The hypothesis is that local object appearance and shape can often be characterised rather well by the distribution of local intensity gradient or edge directions, even without precise knowledge of the corresponding gradient or edge positions. 即,在图像中,物体的局部外观和形状能够通过其局部梯度或边缘信息很好地表征和描述。


3. HOG特征描述向量的提取与计算步骤


HOG特征提取的流程图如下图所示:



1)全局图像归一化

目的:减少光照的影响

方法:gamma compression 
a) 对每个颜色通道分别,计算平方根,或者 
b) 对每个颜色通道分别,求log


2)计算图像梯度

目的:通过梯度信息来描述图像中物体的边缘、轮廓、形状等纹理信息

方法:对每个颜色通道分别计算梯度。梯度算子:水平边缘算子: [-1, 0, 1] ;垂直边缘算子: [-1, 0, 1]T 。

最后选择三个通道中具有最大模值norm的梯度vector作为该像素的gradient vector。


3)统计局部图像梯度信息

目的:统计局部图像梯度信息并进行量化(或称为编码),得到局部图像区域的特征描述向量。该特征描述算向量既能够描述局部图像的内容,又能够对该图像区域内的pose或外观的小变化具有不变性。

方法:求取梯度方向直方图

a)将image window划分为多个区域“cell”;

b)为每个“cell”计算一个1-D的加权梯度方向直方图;

其中,直方图包含9个bin,划分区间:0°-180°或0°-360°。

其中,加权采用三线性插值方法,即将当前像素的梯度方向大小、像素在cell中的x坐标与y坐标这三个值来作为插值权重,而被用来插入的值为像素的梯度幅值。

采用三线性插值的好处在于:避免了梯度方向直方图在cell边界和梯度方向量化的bin边界处的突然变化。


4)归一化

目的:对每个block得到的histogram进行归一化后,能够够对光照、阴影、边缘对比度等具有更好的不变性、

方法:

1)将多个临近的cell组合成一个block块,然后求其梯度方向直方图向量;

2)采用L2-Norm with Hysteresis threshold方式进行归一化,即将直方图向量中bin值的最大值限制为0.2以下,然后再重新归一化一次;

注意:block之间的是“共享”的,也即是说,一个cell会被多个block“共享”。另外,每个“cell”在被归一化时都是“block”independent的,也就是说每个cell在其所属的block中都会被归一化一次,得到一个vector。


5)生成特征描述向量

即将所有“block”的HOG descriptors组合在一起,形成最终的feature vector,该feature vector就描述了detect window的图像内容。



4. HOG描述算子的优点:


1)orientation histogram

能够有效地描述图像区域的local shape的特征信息

2)采用“cell”方式进行梯度方向量化,使得特征描述算子具有一些(a small amount of)平移或旋转不变性

通过改变histogram的bin个数,以及“cell”的size,能够控制捕获图像局部区域特征信息的精度和保持特征具有不变性
3)具有光照不变性
Gamma normalisation and local contrast normalisation(局部对比度归一化) contribute another key component: illumination invariance.
4)overlapping blocks
The use of overlapping of blocks provides alternative normalisations so that the classifier can choose the most relevant one.


5. 影响HOG性能的几个因素:
finescale gradients, fine orientation binning, relatively coarse spatial binning, and high-quality local contrast normalisation in overlapping descriptor blocks are all important for good performance.



6.  解释
1)为什么使用orientation histogram?
capture local shape information
2)为什么使用“cell”?
achieve a small amount of spatial invariance
3)为什么使用“overlapping blocks”?
在众多的local contrast normalisation方法中,采用overlapping blocks得到的效果最好。




7. HOG代码

OpenCV中包含了HOG特征的提取和描述类cv::HOGDescriptor。通过该类可以提取指定图像区域的HOG特征。




相关内容:www.icvpr.com

--------------------------------------------------------
< 转载请注明:http://blog.csdn.net/icvpr >



来自http://hi.baidu.com/timehandle/home

去年我做一个作业和调研的时候看了HOG的那篇论文,没怎么看明白,于是就求助于opencv的代码,结果是也没看明白。在网上做了一些求助后只好自己硬着头皮慢慢抠了两周,最后写了matlab的程序《Histograms of Oriented Gradients (HOG)特征 MATLAB 计算》,我的代码长的比较直白,但是干活不给力,很慢。大家问了一些问题,有一些比较类似,我总结了下将回答写成了这个文档。虽然我很想用图把问题描述清楚,但是可是用画图板和PHOTOSHOP三脚猫的功夫只能到这种程度了。还有就是,我不是做行人检测方向的。。。我只是碰巧碰了下HOG。。。

代码中处理globalinterpolate的情况是没有理解HOG的情况下写的,比原始HOG的想法简陋。Localinterpolate的情况是按照原始HOG实现的,是一种naïve实现方式.

关于计算梯度方向角的:

首先用[-1,0,1]梯度算子对原图像做卷积运算,得到x方向(水平方向,以向右为正方向)的梯度分量gradscalx,然后用[1,0,-1]’梯度算子对原图像做卷积运算,得到y方向(竖直方向,以向上为正方向)的梯度分量gradscaly。然后当gradscalx>=0, gradscaly>=0时,说明梯度方向是朝向第一象限的,当gradscalx>=0, gradscaly<0时,说明梯度方向是朝向第二象限的,诸如此类,结合象限信息,就可以利用反正切函数atan求出在signed和unsigned各自情况下正确的梯度角度.

关于扫描循环(四层for循环…有没有快一点的?有!但是我功力不够。。当时没编出来,就只好还是来四层for):

假设检测窗为64(列)*128(行)大小,block为16*16大小,每个block划分为4个cell,block每次滑动8个像素(也就是一个cell的宽),以及梯度方向划分为9个区间,在0~180度范围内统计,以下的说明都以上述假设为例.

btly与btlx分别表示block所在位置左上角点处的坐标。对于前述假设,一个检测窗内会有105个block存在,因此第一个block左上角的坐标是(1,1),第二个是(9,1)…,此行最后一个是block的左上角坐标是(49,1),然后下一个block就需要向下滑动8个像素,并回到最左边,此时的block左上角坐标为(1,9),接着block重新开始新的横向滑动…如此这般,在检测窗内最后一个block的坐标就是(49,113).

block每滑动到一个新的位置,就需要停下来计算它内部的那四个cell中的梯度方向直方图.(bj,bi)就是来存储cell左上角的坐标的(cell的坐标以block左上角为原点).

(j,i)就表示cell中的像素在整个检测窗(64*128的图像)中的坐标.另外,我在程序里有个jorbj与iorbi,这在Localinterpolate的情况下(也就是标准的原始HOG情况),就是bj与bi.

关于hist3dbig:

这是一个三维的矩阵,用来存储三维直方图。最常见的一维的直方图是这个样子,

二维直方图呢?是这个样子,一个一个的柱子是一个统计bin,柱子的高低代表统计值的大小


三维直方图呢?是这个样子,立体的一个一个的小格子,每个小格子是一个统计bin, 小格子用来装统计值。以上面的例子,那么对一个block来说,它的直方图是下面这样的:

再来说线性插值,线性插值时,一个统计值需被“按一定比例分配”到这个统计点最邻近的区间中去,下面的图显示了一维直方图时,落在虚线标记范围内的统计点,它最近邻的区间就是标有红色圆点的两个区间

若是二维直方图,那落在如下虚线矩形中的统计点,周围的这四个统计区间就是它最近邻的区间。这个虚线矩形由四个统计区间各自的1/4组成。

三维直方图,对一个统计点来说,它的最近邻的区间有八个,如下图,可以想象一下,只有当这个统计点落在由如下八个统计区间各自的1/8组成的一个立方体内内时,这八个区间才是对统计点最近邻的。

统计时如何分配权重呢?以一维直方图简单说一下线性插值的意思,对于下面绿色小方点(x)的统计值来说,假设标红点的两个bin的中心位置分别为x1,x2,那么对于x,它的分配权重为左边bin: 1-(x-x1)/s, 即 1-a/s = b/s, 右边bin: 1-(x2-x)/s, 即1-b/s = a/s.

类似,那么对三维直方图来说,统计时的累积式(从Dalal的论文里截来的)就是:

上面,w 就是准备被分配的统计值。(x1,y1,z1)…共八个点表示八个统计区间的中心位置坐标,上式用h(x1,y1,z1)这样的标记来表示所要累积的统计区间。我在编程时就使用的这个式子,只不过我用bin的下标号来表示bin块,就像前面三维直方图示意中(binx=1,biny=2,binθ=9),不过在程序中θ轴是用z轴表示了。

binx1 = floor((jorbj-1+cellpw/2)/cellpw) + 1;

biny1 = floor((iorbi-1+cellph/2)/cellph) + 1;

binz1 = floor((go+(or*pi/nthet)/2)/(or*pi/nthet)) + 1;

binx2 = binx1 + 1;

biny2 = biny1 + 1;

binz2 = binz1 + 1;

这几句,就是用来计算八个统计区间中心点的坐标的。

在计算前面所讲的统计区间的中心坐标,分配权值之前,我为了处理边缘时程序简洁点,就给那个2*2*9的立体直方图外边又包了一层,形成了一个4*4*11的三维直方图(示意图如下),原来的2*2*9直方图就是被包在中间的部分。这样,在原来直方图里坐标为(binx=1,biny=2,binz=9)的bin,在新的直方图里坐标为(binx=2,biny=3,binz=10)。


对上面的4*4*11的直方图来个与xoy平面平行的剖面图:

粗实线框就是原三维直方图的剖面,也就是一个block,对于像落在粗实线框与粗虚线框之间的点,其最近邻区间是不够8个的,我为了写程序时省点脑力。。。,就用外扩了的这一圈bin,这样落在粗实线框与粗虚线框之间的统计点有了8个区间,用matlab编程时,那个四层for循环中的部分就只用把那八个累积公式写上,也不用判断是不是在落在像上面粗实线框与粗虚线框之间的那种区域。在程序中2*2*9的直方图为hist3d,4*4*11的直方图为hist3dbig.当在这个hist3dbig中计算都结束后,我把外层这一圈剥去,就是hist3d了。
有了这些准备,我就可以计算出当前像素点的梯度方向幅值应该往hist3dbig中的哪八个bin块累积了。binx1,biny1,binz1 在这里就是那个八个bin块之中离  当前要统计的像素点在直方图中对应的位置  最接近的bin块的下标。binx2,biny2,binz2对应就是最远的bin块的下标了。x1,y1,z1就是bin块(binx1,biny1,binz1)中心点对应的实际像素所在的位置(x1,y1)与梯度方向的角度(z1). 我仍然以原block(即没扩前的block)左上角处作为x1,y1的原点,因为matlab以1作为图像像素索引的开始,我把原点就认为是(1,1),那(1,1)左边外扩出来的部分,就给以0,-1,-2,-3…这样的坐标,向上也类似,如下图所示,(1,1)位置为红点所示,蓝点处坐标就是(-3,1).

扩展出来的绿块的下标是(binx=1,biny=1,binz1=1),由于像素坐标在红点处为(1,1),而黄块才是block的第一个cell,对应bin块的下标(2,2).因为下标设计的原因,我在求x1,y1,z1时减了1.5而非0.5.

x1 = (binx1-1.5)*cellpw + 0.5;

y1 = (biny1-1.5)*cellph + 0.5;

z1 = (binz1-1.5)*(or*pi/nthet);

上面的式子中x1,y1还加了0.5,因为像素坐标是离散的,而第一个坐标总是从1开始,这样对如图中第一个cell的中心(黑点)处应该是4.5. z1没加0.5,是因为角度值是从0开始的,并且是连续的。

在signed(即梯度方向从0度到360度)情况下,因为实际上角度的投票区间是首尾相接环形的,若统计间隔是40度,那么0-40度和320-360度就是相邻区间,那么在4*4*11的直方图中,投给binz==11区间(相当于360-380度)的值应该返给binz==2(0-40度),投给binz==1区间的值应该返给binz==10区间,如4*4*11直方图中所示,对应在程序中就是

if or == 2

hist3dbig(:,:,2) = hist3dbig(:,:,2) + hist3dbig(:,:,nthet+2);

hist3dbig(:,:,(nthet+1)) = hist3dbig(:,:,(nthet+1)) + hist3dbig(:,:,1);

end


http://hi.baidu.com/susongzhi/item/3a3c758d7ff5cbdc5e0ec172

HOG中的三线性插值

   

                  

                                                             图1 

    所谓的三线性插值指的是在(x,y,theta)这三个参数空间中进行插值,即x方向、y方向和梯度的角度空间,如图1所示,图中的象素点(x,y)在利用梯度幅值作为权重进行投票时,要根据该象素点距离其他格子中心的距离进行加权,同时该象素点的梯度方向也要在其相邻的区间内进行插值,用数学公式描述如下式所示。

                       

 

                    

                                                      图2 三线性插值示意图

     

    三线性插值在具体实现中,可以利用LUT(look-up-table)来快速计算,若是采用积分直方图,则可以采用Wang等[Wang, 2009]提出的卷积三线性插值方法(Convoluted Trilinear Interpolation,CTI)快速计算,更多关于三线性插值的描述见[Pang, 2011]. 以下用一个简单的例子来说明。

    设图2中所示象素点的梯度方向是85度,梯度幅值是100,该象素点距离格子中心的左、右、上、下的距离分别为2、6、2、6。首先考虑梯度方向上的插值,若每20度为一个区间,85介于70和90之间,到第三个和第四个区间中心的距离分别为15和5,因此若投票值为v,则投票到第三个区间的值是(5/20)*v=0.25v,投票到第四个区间的值是(1-1/4)*v=0.75v。接下来考虑在xy方向上的插值,根据象素点距离各个格子中心的距离,可知在x方向上的权重分配系数为6/8、2/8,在y方向上的权重分配系数也为6/8、2/8。所以梯度幅值分配到第一个格子的值为100*6/8*6/8=56.25,分配到第二个格子的值为100*2/8*6/8=18.75,分配到第三个格子的值为100*6/8*2/8=18.75,分配到第四个格子的值为100*2/8*2/8=6.25。最后,根据梯度方向上的投票权重,可知:第一个格子的直方图第三个区间得到的投票值为56.25*0.25=14.0625,第一个格子的直方图第四个区间得到的投票值为56.26*0.75=42.1875;第二个格子的直方图第三个区间得到的投票值为18.75*0.25=4.6875,第二个格子的直方图第四个区间得到的投票值为18.75*0.75=14.0625;以此类推,可求出第三个和第四个格子的直方图特征。

 

参考文献 

[Wang, 2009] X. Wang, X. Han, and S. Yan. A HOG-LBP human de­tec­tor with par­tial oc­clu­sion han­dling [A]. In Proc. of ICCV[C], 2009.

[Pang, 2011] Y. Pang, Y. Yuan, X. Li, et al. Efficient HOG human detection [J]. Signal Processing, 2011, 91: 773-781.

 

Source Code

1. VLFeat中的HOG实现:http://www.vlfeat.org/overview/hog.html#tut.hog.basic



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值