转载请注明出处:http://blog.csdn.net/c602273091/article/details/54411989
地图初始化的目的就是计算两帧之间的位姿来三角化一系列初始的点云。这个自动化应该使得地图初始化可以独立于场景(平面或者是非平面的),当然不需要人的参与(不然还叫什么自动)文章中提出两个初始化模型:针对于平面的homography和针对非平面场景的fundamental matrix。根据实际情况从中选取一个模型进行初始化,使得初始化过程会有较低的视差。
具体步骤如下:
1、找到两幅图片的对应特征点:提取ORB特征(当前帧和参考帧之间),如果没有足够多的对应点那么重置参考帧。寻找对应特征点使用的是RANSAC(这个可以看我之后发的博客)。
2、同时计算这两个模型:
左边那个计算的是homography,右边的是fundamental matrix。计算homography使用Direct Linear Transformation(DLT),计算fundamental matrix的话需要做SVD分解计算它的解(具体计算看我之后发的关于SFM的博客)。为了方便比较,计算模型时使用的特征点和迭代次数都是提前固定的。(fm有8个,hm有4个)每次迭代为每个模型计算一个Score(S)
S计算的是根据计算的模型,把参考帧的特征点映射到当前帧的位置和原本的特征点之间的误差和当前帧映射到参考帧的误差。( TM 是计算RANSAC的在95%下找到正确的对应特征点,误差不超过1像素情况下的阈值) 然后保留score最高的一组。如果没有模型被找到,那么就重新回到1。
3、模型选择:对于平面来说,选择homography;否则就是fundamental matrix。平面情况下视觉差低,可以用hompgraphy恢复运动,恢复的误差比fundamental matrix的误差小。
在模型选择方面,使用以下简单的式子即可以:
大于0.45的时候选择homography,否则是fundamental matrix。
4、运动恢复:当我们选择好模型以后,就可以使用SFM恢复点云的位置。如果是homography的话,使用【23】中的方法计算。这里会有一个test,test失败那就回到1重新计算。计算fundamental matrix的时候。计算essential matrix【2】:
5、使用full BA初始化地图。
论文提出它的初始化地图的方法很好:PTAM和LSD-SLAM都初始化为homography。
为了确保角点分布均匀,把一幅不同规格的图片分成不同的cell。每个cell至少5个角点。然后自适应调整角点的数量。接着计算方向和ORB描述子。
如果上一帧成功追踪,使用匀速模型去预测位姿和找到上一帧匹配的点。如果匹配不够,那么使用更加宽泛的距离去寻找对应的点进行相应的优化位姿。
如果追踪的话,那么就需要进行重定位。把当前帧转化为bow,并且从数据库中做匹配。使用RANSAC计算匹配的特征点,然后找到最接近的。之后采用PnP算法计算相机的位姿【41】只要有足够多的inlier,那么就可以对丢失的帧进行位姿的优化。
我们对相机位姿进行了一个估计,并且计算当前帧的特征点与之前帧的匹配。我们定义集合K1(与当前帧有交集的帧),然后是K2(与K1有交集与当前帧无交集)这样形成的一个covisibility graph。在K1中与当前帧有最多的匹配点的帧叫做 Kf
接下来在K1和K2中都可见的点云x将会做以下的操作:
1、把x映射到当前帧,如果越界就删除;
2、计算当前帧的视角向量v和特征点的平均视角n,去除如果vn < cos(60)
3、计算特征点到摄像头中心的距离,如果在特征点的scale invariant region,那么就删除;
4、计算特征点的scale,d/dmin
5、计算当前帧中没有匹配的描述子D,在预测的scale范围内并且靠近x的就把当前帧这个为未匹配的特征点和最匹配的联系起来。
最后摄像头的pose就是由匹配的点来进行完全优化。
插入当前帧为关键帧的条件是:
1、从上一次的全局重定位已经经过了超过20f;(good rel)
2、局部地图已经暂停,或者是距离上次插入关键帧超过20帧;
3、当前帧追踪到了大于等于50个特征点(good tracking);
4、当前帧相比于参考帧追踪到了超过90%(visual change)。
这部分描述的就是对每个新的关键帧进行的局部地图去冗余、局部优化等等。
插入之后会更新covisibility graph和essential graph,计算该帧的bow,这对新的点进行数据相关的三角化有比较大的意义。
特征点想要保留下来,必须通过超过三帧的特征点匹配。因为这样才说明它是可追踪的而不是错误的三角化。这个点必须满足:
1、追踪的过程中发现这个特征点可以在超过25%的情况下预料可见;
2、特征点必须被至少三个关键帧察觉到。
当然即使点云通过以上测试,还是有可能被删除。比如某个关键帧被删除,局部BA的outlier剔除。
新建立的关键帧有的特征点可以匹配上,而有些是新的。这些新的也要经过各种测试。然后还要通过local BA的测试。
local BA处理的有当前帧Ki,与Ki在covisibility graph向连的帧Kc,与Kc相连的一些帧。在local BA中也会删除一些outliers。
一个关键帧被删除如果90%的特征点已经在至少三帧出现过或者是在fine scale上有这么多特征点。
闭环检测处理的是最近处理的关键帧,判断它是否与之前的关键帧存在闭环。
计算最近处理的关键帧Ki与它的covisibility graph的bow的相似度( θmin 最小是30),保留最小的score Smin 。 从database中去掉与Ki的score小于 Smin 的帧。 同时把连着Ki的帧都从候选项中去掉。接着从剩下的帧中选取候选项,候选项必须是连续的三帧以上的才能作为候选项。
在单目SLAM里面,有7个自由度(DoFs)可以漂移:三个平移([X,Y,Z]),规格因子(scale factor),三个旋转分量(yaw、patchg、row)
Ki与Kl(回环帧)之间的计算可以得知累计的误差,计算相似度可以作为闭环的有效性的检测。
首先是找到对应ORB特征的匹配点,然后计算bow,计算相似度。在每个闭环的候选帧中,我们构建出3D到3D的一个对应关系。然后使用RANSAC,试着找到其中的变换【42】如果找到了对应的,就进行优化。通过guided search找到更多的response。我们再次优化。如果 Sil 有足够多的inlier,那么 Kl 就是一个闭环帧。
有的时候很多个环都是同一个,那么需要在建图的时候对这些环进行融合。如果是很多个环重叠的时候,检测闭环的时候,连续的很多帧都有很高的相似度。和V-D中的做法一样,找到相应的匹配帧,然后在covisibility graph中添加边。
为了有效的闭环,在关键图(essential graph)上进行一个优化。在关键图上优化,计算对应的错误偏移然后矫正【6】优化之后,每个点云由观测该点云的关键帧进行矫正。
看看人家是怎么做实验的。
测试集采用的是NewCollege、TUM的RGBD的benchmark还有KITTI的数据集。
目前为止可以把这个数据集做得很好的单目SLAM。下图是重建之后的效果:
通过闭环检测以后,这个偏移得以矫正。
整个序列的结果如下:更大的环是与内环相反方向的,而没有检测出这个环进行融合,所以表现不是很好。
帧率可以达到25~30,这个还是可以的。
这个测试主要是体现闭环的效果。
在fr3_nostructure_texture_far上面表现错误,没有检测到。其余的表现ORB-SLAM更加优秀。可能是ORB-SLAM在优化相机位姿的时候,也会优化点云、传感器测量结果等等。最终结果如下:
ORB-SLAM和PTAM进行结果比较,发现ORB-SLAM可以检测出77.9%的回环,PTAM是0。
为了测试ORB-SLAM可以画很长的地图,所以有了这部分的比较。
与PTAM比较插入关键帧,PTAM的关键帧一直在插入,ORB-SLAM则是会考虑场景变化。比完静态场景,接着是比较动态场景。动态场景下,比较了TUM的几个序列。有的表现可以,有的表现不是很好,表现不好的可能是动态场景下没有做得很好。
通过这个部分的实验,体现了ORB-SLAM是跟随着场景变化而增加,不是像PTAM是随着时间。
ORB-SLAM可以追踪除了01之外的所有数据集,00、02、05、06、07、09的闭环正确检测到。09有时候无法正确检测到。
08没有比哈un,所以误差比较大,偏移无法矫正回来。在做full BA的时候,只需要20次迭代就足够达到比较精确的效果。
在这里特别说明一下 θmin 的作用。下表可以比较清楚的展现这个关系:
我们可以发现essential graph的优化很有用处。
ORB-SLAM很牛逼,很全面。是那个时候精度最高、适用范围最广、可以在多场景使用的单目SLAM。与稠密法比较呢,稠密法的试用范围可能会更广,比如VR、AR,需要的关键帧是以像素展现。但是稠密法就是容易受到比如曝光、关照、颜色等等影响比较大。同时关键帧的表示比较冗余,没有去冗余机制。