ORBSLAM2地图更新策略简介
地图的更新目标在于如何插入新的关键帧和地图点,同样,怎么剔除多余的关键帧和没用的地图点。
接下来,笔者会从下面几个方面来介绍地图的更新策略:
1. 统计当前关键帧的共视图关键帧,构建临时的局部地图;
2. 剔除当前关键帧中质量较差的地图点;
3. 局部地图重投影获取更多匹配对;
4. 剔除冗余的关键帧。
共视图关键帧
共视图是ORBSLAM2中一个非常重要的概念,他的目的是将与当前帧有共同观测的关键帧集合起来,构建一个临时地图,通过构建更强和更多的约束条件来优化相机的位姿。接下来,我们来看看ORBSLAM2的共视图是如何构建的。
首先,我们引用ORBSLAM论文里的一个图,从这个图中我们看到了四种颜色。蓝色表示地图中的关键帧,绿色表示当前帧,红色表示共视图关键帧的共同观测,黑色表示当前帧观测不到的地图点。显然,我们构建的共视图,就是和当前帧一起观测到这些红色地图点的所有关键帧构成的。
有了一个直观的认识,我们再来具体看看在细节上,ORBSLAM2是怎么做的。同样,为了方便大家理解,笔者还是以列提纲的形式,将其主要思路罗列出来。
构建共视图的具体流程是:
1. 读取当前关键帧的所有地图点;
原因:只是为了方便遍历索引。
2. 遍历当前帧所有地图点,将其按观测情况进行分类。已有共同观测,则更新观测信息和地图点;没有共同观测的,则临时存储;
原因:主要是区分新创建的地图点和已有的地图点,目的是保留高质量的地图点。
3. 对当前帧所有地图点提取观测信息(每个地图点包含多个观测,每个观测是一个映射,表示关键帧指针和对应的特征点ID),统计各个关键帧与当前帧的共同观测数量并排序。将共同观测数量大于15的关键帧加入共视图中,若无满足条件的,则将共同观测数量最多的关键帧加入共视图中,并取共同观测数量最大的作为当前帧的父节点。
原因:共视图的含义即是与当前关键帧有共同观测的关键帧所组成的图,当时ORBSLAM2在更新地图的时候,将约束条件增强了,只取共同观测数量较多的关键帧加入共视图中,在优化相机位姿时具有很好的帮助。
剔除地图点
有些新创建的地图点需要通过严格的筛选机制,才能确定是否加入地图中,对每一个地图点的筛选机制如下:
1. 在预测该地图点可见的所有关键帧中,实际跟踪到该地图点的关键帧数量必须占总数的25%以上;
原因:在预测可见的关键帧中却没有跟踪到该地图点,显然该地图点是比较劣质的,但是ORBSLAM2放宽了条件,只要求其25%以上的关键帧能跟踪到即可。
2. 该地图点被观测到的次数过少,并且从上一次观测到该点过后连续两帧没观测到;
原因:地图点筛除机制的目的是保持地图的紧凑性,以及保证跟踪的质量。因此,插入地图点的条件严苛些,其实是为了更好的定位。
3. 该地图点在被观测到后,连续三帧内未被继续观测到;
原因:地图点的作用主要是为了更好的跟踪,一个新建的地图点,在创建后就跟踪不到了,显然这个地图点的质量是非常差的,因此必须剔除。
在剔除了不满足要求的地图点后,剩下的地图点都是要插入地图的。因此需要三角化新的地图点,由于涉及一些理论知识,限于篇幅,笔者将单独一讲介绍地图点的三角化。
获取更多匹配对
由于在特征匹配阶段,ORBSLAM2只留下质量比较高的特征点,那些被筛除的特征点实际上比例非常高。因此ORBSLAM2通过构建局部地图,在局部地图中为这些筛除掉的特征点查找最优匹配。具体的查找方式同我们先前介绍的匹配方法类似,不过问题的规模稍微比之前的要大一些。具体流程如下:
1. 在如前所述的共视图关键帧中,从每个关键帧各自的共视图中取出共同观测最多的前5帧关键帧,如下图所示。以此来构建更大的共视图网络。
原因:扩大搜索范围,能够更容易为当前关键帧的每个特征点找到最优匹配。
2. 遍历上述共视图所有的关键帧,将当前关键帧的所有地图点逐个投影到共视图中的关键帧。假设关键帧为 $KF_{covis}$,旋转为 $R_{covis}$, 位移为 $t_{covis}$ ,当前关键帧为 $KF_{curr}$,当前关键帧中的一个地图点 $P_{w}$,相机内参为 $K$,则:
首先将当前关键帧的地图点变换到关键帧 $KF_{covis}$ 相机坐标系中: $P_{covis} = R_{covis}P_{w} + t_{covis}$ ;
再将其投影到关键帧 $KF_{covis}$ 的像平面中: $p_{covis} = KP_{covis}$ 。
在像平面以 $p_{covis}$ 为中心的圆内找最优匹配。匹配的方法我们前面已经介绍过了,与这里的并无二致,笔者就不再赘述了。
原因:投影的目的是为当前帧的所有地图点找到最优匹配点。
3. 除了将当前帧的所有地图点投影到共视图所有关键帧的像平面中去查找最优匹配点,ORBSLAM2还采用了逆过程,将共视图所有关键帧的地图点投影到当前关键帧中,查找最优的匹配。为当前关键帧的地图点找到更优的匹配点。
原因:由于前一次匹配的点,质量可能有提高的空间,再次匹配的时候可以用更好的代替。
4. 匹配了所有地图点后,需要更新地图点的描述子和法向量以及深度信息;
原因:也是为了保证地图点更有分辨力,可以将该地图点表示邻域地图点的一个聚类中心。
剔除冗余关键帧
在更新了地图点之后,ORBSLAM2还执行了一次局部Bundle Adjustment。通过将共视图关键帧和当前关键帧全部设置为优化变量,并将共视图关键帧的共视图作为固定节点,将共同观测作为约束的边,放入Bundle Adjustment中进行优化,最后得到更好的位姿。优化的思路同之前介绍的PNP方法有些类似,但不完全一样。笔者将在闭环这一节中再详细介绍Bundle Adjustment。这里就是稍稍略过,让大家知道这里实际上有一次优化过程。
优化以后,需要进行关键帧的筛除,具体如下:
1. 对于共视图中的任意一个关键帧,统计其所有地图点重复观测的数量,若其重复观测的数量超过其地图点总量的90%,则说明这个关键帧是冗余的,予以剔除。
原因:ORBSLAM2坚持使用最小的信息冗余度来保持地图的紧凑性,除了保证跟踪的质量,也能避免内存和计算资源的消耗。
筛除冗余的关键帧后,将当前关键帧输入回环检测线程,同时终止全局Bundle Adjustment,执行回环检测,相关内容笔者会在后续介绍。
总结:
在这一讲中,我们主要介绍了ORBSLAM2地图的更新策略,包括共视图关键帧的创建,地图点的剔除和插入以及关键帧的剔除策略。
在这一讲需要涉及的,但是没有细讲的内容包括地图点的三角化,局部Bundle Adjustment和全局Bundle Adjustment,这些内容笔者会在接下来的内容中为大家介绍。
下一讲,笔者将为大家介绍ORBSLAM2地图点的三角化。
PS:
如果您觉得我的博客对您有所帮助,欢迎关注我的博客。此外,欢迎转载我的文章,但请注明出处链接。
对本文有任何问题可以在留言区进行评论,也可以在泡泡机器人论坛:http://paopaorobot.org/bbs/index.php?c=cate&fid=1中的SLAM技术交流模块发帖提问。
我的github链接是:https://github.com/yepeichu123/orbslam2_learn。