前言
前言这种东西已经写不动了,被代码按在地上摩擦,快起火了。
在研读源码期间,看到了旋转直方图,初次见的时候理解了,现在第二次在其他地方看到又忘了,特写此文记录学习。
如果要深入学习,还是需要阅读《Histogram of Oriented Gradients(方向梯度直方图)》论文。
一、基础知识
1. 梯度(gradient)
在向量微积分中,标量场的梯度是一个向量场,标量场中某一点上的梯度指向标量场增长最快的方向,梯度的长度是最大的变化率。
图像处理实现(详细见CSDN@gloomyfish):利用X方向与Y方向分别实现一阶微分,求取振幅,实现图像梯度效果。
2. 一阶微分
对于离散的图像来说,一阶微分的数学表达相当于两个相邻像素的差值,根据选择的梯度算子的不同,效果可能有所不同,但基本原理不变。
图像处理实现(详细见CSDN@gloomyfish):最常见的算子为Roberts算子,其它常见还有Sobel,Prewitt等算子。
3. 图像梯度计算(图像微分)的应用
图像微分(梯度计算)是图像边缘提取的重要的中间步骤,根据X、Y方向的梯度向量值,可以得到如下两个重要参数:振幅magnitude,角度theta。
计算公式如下:
magnitude(振幅)表示边缘强度信息
theta(角度)预测边缘的方向走势。
假如对一幅数字图像,求出magnitude之后与原来每个像素点对应值相加,则图像边缘将被大大加强,轮廓更加明显,是一个很典型的sharp filter(锐化)的效果。
来源:CSDN@HySmiley
4. 卷积
通过一个卷积模板在待处理的图像上移动,对每个卷积模板覆盖的区域进行点乘,得到的值作为中心像素点的输出值。
常用于信号处理中,而图像数据可以看做是一种信号数据,故可以对图像进行卷积操作。
二、方向梯度直方图(旋转直方图)
1. HOG特征
方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子,其通过计算和统计图像局部区域的梯度方向直方图来构成特征。
HOG+SVM的思路常被用于行人检测的图像识别中,ORB-SLAM2中只涉及HOG。
(1)核心思想
在一幅图像中,局部目标的表象和形状(appearance and shape)能够被梯度或边缘的方向密度分布很好地描述。
本质:梯度的统计信息,而梯度主要存在于边缘的地方。
(2)实现方法
首先将图像分成小的连通区域,并称其为细胞单元(cell),然后采集细胞单元中各像素点的梯度的或边缘的方向直方图,最后把这些直方图组合起来就可以构成特征描述器。
(3)进一步优化
把这些局部直方图在图像在更大的范围内(称其为区间或block)进行对比度归一化(contrast-normalized)。
采用的方法是:先计算各直方图在这个区间(block)中的密度,然后根据这个密度对区间中的各个细胞单元做归一化。通过这个归一化后,能对光照变化和阴影获得更好的效果。
(4)优点:具有尺寸不变性和光照不变性
2. 具体实现步骤(参考论文并结合ORB-SLAM2总结)
(1)选择需进行特征处理的图像,并进行预处理
选择需进行处理的image(假设尺寸为64x128),然后进行灰度化和颜色空间的归一化。
归一化的目的:调节图像的对比度,降低图像局部的阴影和光照变化所造成的影响,同时可以抑制噪音的干扰。但是并不够,即性能提升效果较小。
(2)计算图像梯度
这个由于选择的梯度算子计算方式的不同,可能计算梯度的效果会不太一样,但基本原理是一样的。
**最常用的实现方法:**首先用[-1,0,1]梯度算子对原图像做卷积运算,得到x方向的梯度分量xGradient
,然后用[1,0,-1]T梯度算子对原图像做卷积运算,得到y方向的梯度分量yGradient
。最后用相应的算子计算公式计算该像素点的梯度大小和方向。
注:x方向上的分量不一定就是水平方向,同理,y也不一定就是竖直方向,例如Roberts算子计算时运用的是对角线。
最普通的计算梯度公式为:
(3)划分cell单元,为每个cell构建梯度方向直方图
设定细胞单元cell的尺寸大小(由x个像素构成),确定直方图储存cell梯度信息的bin的数目。
例如,假设细胞单元cell为8x8个像素构成,采用9个bin的直方图来统计这些8x8个像素的梯度信息。
一个 8×8 的图像块包含 8x8x3 = 192 个像素值。该补丁的梯度包含每个像素的 2 个值(幅度和方向),总计为 8x8x2=128 个数字。将cell的梯度方向360度分成9个方向块。
如图所示:例如:如果这个像素的梯度方向是20-40度,直方图第2个bin的计数就加一,这样,对cell内每个像素用梯度方向在直方图中进行加权投影(映射到固定的角度范围),就可以得到这个cell的梯度方向直方图了,就是该cell对应的9维特征向量(因为有9个bin)。
cell可以是圆形、矩形、星形等不同形状的。
如何分配每个cell中的bin值权重,见opencv官网:histogram-of-oriented-gradients
(4)将cell组合成更大的块(block),块内归一化,构建直方图
由于局部光照的变化以及前景-背景对比度的变化,使得梯度强度的变化范围非常大。这就需要对梯度强度做归一化。归一化能够进一步地对光照、阴影和边缘进行压缩。
采用方法:把各个细胞单元组合成大的、空间上连通的区间(blocks)。一个block内所有cell的特征向量串联起来便得到该block的HOG特征。这些区间是互有重叠的,这就意味着:每一个单元格的特征会以不同的结果多次出现在最后的特征向量中。我们将归一化之后的块描述符(向量)就称之为HOG描述符。
如将4个上述8x8的cell拼凑成一个16x16的block,一个block有4个91的直方图,故block组合成了一个361的向量(HOG特征)。然后做归一化,将block窗口移动8个像素遍历图像的所有像素点,在这个窗口上计算36*1向量的归一化。
(5)计算Oriented-Gradients特征向量的直方图
在整幅image上,有 7 个水平位置和 15 个垂直位置,总共 7 x 15 = 105 个16x16的block可以移动(扫描)的位置。
每个 16×16 块由一个 36×1 向量表示。因此,当我们将它们全部连接成一个增益向量时,我们获得了一个 36×105 = 3780维的向量。
所以一幅64x128的图像,总共有3780个特征,即其HOG特征的维度为3780。
所以这一幅图像的HOG特征就这么求出来了。
其实这个64x128在论文中只是一张图中的一小块,论文中计算了这一小块的HOG特征。
三、ORB-SLAM2使用的地方(210821更,持续更新)
1. 单目初始化
源代码路径:void Tracking::MonocularInitialization()
中的SearchForInitialization()
;
作用:在单目初始化中进行参考帧(第一帧)和当前帧(第二帧)的匹配中,筛选“非关键”的匹配特征点。
2. 关键帧跟踪
源代码路径:bool Tracking::TrackReferenceKeyFrame()
中的SearchByBoW()
;
作用:当前普通帧对关键帧跟踪过程中,根据方向剔除误匹配的点。
Reference(宝藏链接,虽然都差不多):
- https://blog.csdn.net/m0_37264397/article/details/77824975(内容最多)
- https://www.leiphone.com/category/yanxishe/ZKsGd2JRKr766wEd.html(3打不开,看这个)
- https://learnopencv.com/histogram-of-oriented-gradients/(opencv官方文章)
- 《OpenCV4快速入门》