您的位置:首页 > 大数据 > 人工智能

ORB-Slam2详解5 局部建图

2017-12-04 14:28 387 查看
在之前的Tracking中,我们得到了新的关键帧Ki。如下图所示,Local Mapping这部分 包括插入关键帧,剔除冗余的地图点和关键帧,还有进行局部集束调整。接下来按照顺序介绍各部分。 



这一部分通过之前实例化SLAM系统对象时,实例化了一个LocalMapping的对象,并且开启一个线程,运行LocalMapping::Run()函数。整个代码逻辑如下: 




一、关键帧插入

  首先将新的关键帧Ki作为新的节点Ki加入Covibility Graph,并且更新与那些能够共享地图点的关键帧节点相连接的边。同时更新关键帧Ki的生长树,并计算表示关键帧的词袋BOW。这一部分的接口是在LocalMapping.cc中的
// BoW conversion and insertion in Map
ProcessNewKeyFrame();
1
2

计算词袋,整合地图点到新的关键帧,计算法线和描述子的接口如下:
// Compute Bags of Words structures
mpCurrentKeyFrame->ComputeBoW();

// Associate MapPoints to the new keyframe and update normal and descriptor
const vector<MapPoint*> vpMapPointMatches = mpCurrentKeyFrame->GetMapPointMatches();
1
2
3
4
5
6

更新Covisibility Graph,将关键帧插入Map中的接口如下:
// Update links in the Covisibility Graph
mpCurrentKeyFrame->UpdateConnections();

// Insert Keyframe in Map
mpMap->AddKeyFrame(mpCurrentKeyFrame);
1
2
3
4
5


二、当前地图点剔除

  为了保存地图点,必须在创建该点云的前三帧测试通过约束,才能真正被保存,这样才能保证可跟踪且不容易在三角化时出现较大误差。这部分的接口如下:
// Check recent MapPoints
MapPointCulling();
1
2

一个点要被加入Map,需要满足下面条件: 

(1)这个点要在可预测到能够观察到该点的关键帧中,有超过25%的关键帧能够跟踪到这个点; 

(2)如果一个地图点被构建,它必须被超过三个关键帧观察到(在代码中,可以发现如果是单摄像头,这个阈值被设置为2)。

  一旦地图点被创建了,就只有在少于3个关键帧能够观察到该点时才会被剔除。而要剔除关键帧,通常是在局部集束调整剔除外点或者在后面剔除关键帧时才会发生。这样就保证了地图点很少存在外点影响效果。


三、新的地图点创建

  通过将检测到的ORB特征点,找到Covisibility Graph中与之相连的关键帧Kc,进行特征匹配,然后将匹配到的特征点进行三角化。对于没有匹配上的点,本文又与其他关键帧中未被匹配的特征点进行匹配。匹配方法使用的是之前的方法,并且将不满足对极几何约束的匹配点舍弃。ORB特征点对三角化后,检查正向景深、视差、反投影误差和尺度一致性,这时才得到地图点。一个地图点是通过两个关键帧观察到的,而它也可以投影到与之相连的其他关键帧中,这个时候可以使用Tracking部分的跟踪局部地图来在附近的关键帧中找到匹配。得到更多的地图点。这部分接口为:
// Triangulate new MapPoints
CreateNewMapPoints();

if(!CheckNewKeyFrames())
{
// Find more matches in neighbor keyframes and fuse point duplications
SearchInNeighbors();
}
1
2
3
4
5
6
7
8


四、局部集束调整

  局部集束调整(local BA)会将当前处理的关键帧Ki进行优化,优化时如下图所示:现在优化Pos3位置的关键帧。同时参与优化的还有: 

所有在Covibility Graph中与该关键帧相连的关键帧Kc,即下图中的Pos2; 

所以被这些关键帧观察到的地图点,即X1和X2。 

另外还有能观察到地图点的但并未与当前处理的关键帧相连的关键帧,即下图中的Pos1。 

  但要注意的是,诸如Pos1的关键帧,参与优化中的约束,但不作为变量去改变它们的值。优化时得到的外点会在优化的中期或后期被剔除。 



这部分的接口如下:
// Local BA
if(mpMap->KeyFramesInMap()>2)
Optimizer::LocalBundleAdjustment(mpCurrentKeyFrame,&mbAbortBA, mpMap);
1
2
3


五、局部关键帧剔除

  为了控制重建的紧凑度,LocalMapping会去检测冗余的关键帧,然后删除它们。这样的话会有利于控制,随着关键帧数目增长后,集束调整的复杂度。因为除非视角改变了,否则关键帧的数量在相同的环境中不应该无休止地增长。本文将那些有90%的点能够被超过三个关键帧观察到的关键帧认为是冗余关键帧,并将其删除。这个部分的接口如下:
// Check redundant local Keyframes
KeyFrameCulling();
1
2

最后,在所有步骤结束后,会将关键帧记录到数据库列表中。完成LocalMapping工作,将标志设为SetAcceptKeyFrames(true),以允许Tracking线程继续得到关键帧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  人工智能 slam