orbslam2代码解析--局部建图

LocalMapping模块作用是将Tracking中送来的关键帧放在mlNewKeyFrame列表中;处理新关键帧、地图点检查剔除、生成新地图点、Local BA、关键帧剔除。主要工作在于维护地图,也就是SLAM中的Map

Tracking模块会将满足一定条件的图像帧加入关键帧,但是其实ORB-SLAM中关键帧的加入是比较密集的,这样确保了定位的精度。同时LocalMapping线程会对关键帧进行剔除,确保了关键帧的数量不会无限增加,不会对large scale的场景造成计算负担。Tracking模块会判断是否需要将当前帧创建为关键帧,对地图中的关键帧、地图点具体的处理,包括如何加入、如何删除的工作是在LocalMapping线程完成的。

LocalMapping

1 处理新关键帧

LocalMapping::ProcessNewKeyFrame()

处理新关键帧与局部地图点之间的关系。具体步骤如下

  1. **获取关键帧。**从mlNewKeyFrame队列(待插入的关键帧)中弹出队首的关键帧做为当前帧,并计算该关键帧的BoW,后面三角化恢复地图点有用;
  2. **获取关键帧中与关键点关联的地图点。**将TrackLocalMap中跟踪局部地图匹配上的地图点关联到当前关键帧(在Tracking线程中只是利用关键点的匹配关系进行位姿计算,优化当前关键帧姿态)。具体来说,可以分两种情况,地图点没有关联到关键帧,则完成关联(AddObservation),更新地图点normal和描述子,这种地图点是在追踪过程创建并被关键帧关联的,它们在UpdateLastFrame过程就已经有了空间位置;否则记录该地图点为最新添加(这些地图点是在创建关键帧时创建的,已经关联到关键帧),加入mlpRecentAddedMapPoints
  3. **更新共视图连接关系。**使用UpdateConnections函数更新加入当前关键帧之后关键帧之间的连接关系,包括更新Covisibility图和Essential图(最小生成树spanning tree);
  4. 关键帧插入地图。

2.地图点剔除

LocalMapping::MapPointCulling()。任务是对上一函数获取到的最新加入的局部地图点mlpRecentAddedMapPoints进行检查,每个地图点要被保留,在该地图点被创建后的三个关键帧里必须要经过严格的测试,这样保证其能被正确的跟踪和三角化。满足如下条件之一就被剔除:

  1. 该地图点是坏点,直接从检查列表去掉;
  2. 跟踪(匹配上)到该地图点的普通帧帧数(IncreaseFound)<应该观测到该地图点的普通帧数量(25%*IncreaseVisible),即比值mnFound/mnVisible<0.25,设置为坏点,并从检查列表去掉。比值低说明这样的地图点该地图点虽在视野范围内,但很少被普通帧检测到;
  3. 从添加该地图点的关键帧算起,当前关键帧至少是第三个添加该地图点的关键帧的条件下,看到该地图点的帧数<=2(双目和RGBD模式是帧数<=3),设置为坏点,并从检查列表去掉;因此在地图点刚建立的阶段,要求比较严格,很容易被剔除;而且单目的要求更严格,需要三帧都看到;
  4. 若从添加该地图点的关键帧算起,一共有了大于三个关键帧,还存在列表中,则说明该地图点是高质量的,从检查列表中去掉。

3.生成新地图点(三角化方法)

对应LocalMapping::CreateNewMapPoints()函数。任务是根据当前关键帧恢复出一些新的地图点,不包括和当前关键帧匹配的局部地图点(已经在ProcessNewKeyFrame中处理,单目模式除了初始化过程会生成地图点外,其它地图点都在这里生成)。具体步骤如下:

  1. 找出与当前帧有共视关系的10个(单目模式是20个)关键帧,准备使用对极约束搜索匹配并进行三角化,循环进行以下操作,注意是在当前帧和每一帧共视关键帧之间进行;

  2. 检测基线是否过短;

  3. 计算基础矩阵F;

  4. 搜索满足对极约束的匹配;

    matcher.SearchForTriangulation(mpCurrentKeyFrame,pKF2,F12,vMatchedIndices,false);

  5. 通过各种条件判断是不是要三角化这些地图点;

  6. 完成对匹配结果的三角化,创建新的地图点;

  7. 为新的地图点进行一系列配置。

4.临近关键帧搜索更多匹配

对应LocalMapping::SearchInNeighbors()函数。如果关键帧队列中还有新的关键帧,则进行该操作,即在临近的关键帧中搜索到更多的匹配,更新并融合当前关键帧以及两级相连(共视关键帧及其共视关键帧)的关键帧的地图点。

5.Local Bundle Adjustment

对应Optimizer::LocalBundleAdjustment()函数。这里优化的是当前帧,以及与当前帧在covisibility graph里面有连接关系的那些关键帧的位姿,以及这些帧看到的地图点,其实就是对局部地图进行优化。详细分析参见优化部分博客。

6.冗余关键帧剔除

对应LocalMapping::KeyFrameCulling()函数。候选的pKF是LocalMapping中当前处理的关键帧的共视关键帧,不包括第一帧关键帧与当前关键帧。如果一个关键帧检测到的90%的地图点,在其他不少于三个具有相同或更精确尺度的关键帧里面都被检测到,就认定该关键帧冗余(该关键帧的存在提供的地图点观测信息有限),并剔除

Author

imagine

Posted on

2020-09-28

Updated on

2020-12-24

Licensed under

You need to set install_url to use ShareThis. Please set it in _config.yml.
You forgot to set the business or currency_code for Paypal. Please set it in _config.yml.

Comments

You forgot to set the shortname for Disqus. Please set it in _config.yml.