来自一个小学渣的介绍,仅供参考
ORB特征提取可以分为两部分:
for (v = 0; v <= vmax; ++v)
umax[v] = cvRound(sqrt(hp2 - v * v));
// 计算一个对称的圆形区域
for (v = HALF_PATCH_SIZE, v0 = 0; v >= vmin; --v)
{
while (umax[v0] == umax[v0 + 1])
++v0;
umax[v] = v0;
++v0;
}
2、计算高斯金字塔。该过程较为简单,直接通过图像的缩放就可以达到目的。主要使用的函数就是如下所示的resize函数。
resize(mvImagePyramid[level - 1], mvImagePyramid[level], sz, 0, 0, INTER_LINEAR);
该函数可以通过线性缩放得到需要的图像。
3、特征点提取与分配。为了使接下来计算PnP时能够更加准确,需要保持的原则就是尽量使得特征点能够均匀分布在整个图像中,所以需要将图像分成更小的部分分别提取特征点,并用某种机制来分配。在本项目中,作者提供了两种分配方案分别是八叉树的方法和传统的方法。考虑到在室内场景中并不需要提供太多的特征点,而在1000个特征点以下时,传统的方法表现要由于建造八叉树的方法。所以在实际应用中,都是采用传统的方法,而不去花费大量收时间用于建造八叉树。
void ORBextractor::ComputeKeyPointsOld(std::vector<std::vector > &allKeypoints)
传统方法的第一步就是计算需要将图像分割成多少个元包(cell),对于每个元包分别提取特征点。元包的计算方法为,根据需要提取的特征点数目,假设每个元包中需要提取5个特征点,以此来进行计算需要的cell数目。
接着对上面计算好的元包分别进行特征点的提取。这里注意,由于FAST特征在计算角点时向内缩进了3个像素才开始计算,所以在使用FAST之前还需要对图像加一条宽度为3像素的边。然后就要用到之前初始化的两个阈值参数,首先使用阈值较大的参数作为FAST特征点检测的阈值,如果提取到的特征点数目足够多,那么直接计算下一个元包即可,否则就要使用较小的参数重新提取。在本项目中,特征点数目的阈值设定为3.
然后就涉及到了特征点的数目分配问题。由于图像中不可避免的存在纹理丰富和纹理较浅的区域,在纹理较丰富的区域,角点的数目可能提取很多,而在纹理不丰富的区域,角点的数目可能很少。而在分配各区域选取的特征点数目时,就要考虑前面提到的极可能均匀的问题。所以采用的方法是循环将特征点数目不足的元包中的剩余数目分配到其他所有元包中,知道最后取得足够数量的特征点。当然,如果最初提取的特征点数目就不足预期,那么直接全部选取即可。所以这种方法并不能保证最终得到的特征点数目一定能达到1000。
对于那些特征点数目特别多的元包,采用的是对各个角点的质量进行排序,选择最好的前n个特征点作为最终结果。
4、计算方向。为了使得提取的特征点具有旋转不变性,需要计算每个特征点的方向。方法是计算以特征点为中心以像素为权值的圆形区域上的重心,以中心和重心的连线作为该特征点的方向。
static void computeOrientation(const Mat& image, vector & keypoints, const vector<int>& umax)
{
for (vector ::iterator keypoint = keypoints.begin(),
keypointEnd = keypoints.end(); keypoint != keypointEnd; ++keypoint)
{
keypoint->angle = IC_Angle(image, keypoint->pt, umax);
}
}
5、计算描述子。Brief特征一大特点就是得到的是二进制的描述子,这样可以直接用异或计算汉明距离,从而方便地进行匹配。计算首先将坐标系的X轴旋转到和前面计算的方向重合的方向,然后用之前已经直接给出的随机点计算二进制描述子。这里为了抵御噪声的影响,并没有直接比较两个像素点的灰度值,而是首先计算两个像素点周围5*5像素和然后再比较,这样就相当于进行了一次滤波,能够有效的抑制噪声。
以上的代码部分可以直接在github上下载。我主要研究的是特征提取与描述子生成的部分,所以将这部分单独拿出来分析了。另外,通过实验可知,将FAST算法替换为最先进的AGAST算法可以实现一定程度上的加速。
Raul Mur-Artal, J.M.MMontiel, and Juan D. Tardos ORB-SLAM: a versatile and Accurate Monocular SLAM System ICCV 2010
Ethan Rublee and Vincent Rabaud and Kurt Konolige and Gary Bradski, ORB: an efcient alternative to SIFT or SURF, ICCV 2011