ORB_SLAM2源码阅读记录(3):线程LocalMapping

ORB_SLAM2源码阅读记录(3):线程LocalMapping

继续阅读ORB_SLAM2源码,主线程Tracking向局部建图线程LocalMapping插完关键帧后,局部建图线程LocalMapping主要做了哪些工作? 从LocalMapping::Run()函数开始。

局部地图构建线程: 创建新的地图点以及剔除冗余的关键帧。

  • 检查队列插入新的关键帧,处理关键帧队列;
  • 删除不合理的地图点,创建新的地图点,三角化新的地图点,利用local BA 优化局部地图中关键帧的位姿和地图点3D位置;
  •  删除冗余的关键帧和 3D 点,如果关键帧中 90%以上的地图点能被其它至少3 个共视关键帧观测到,则删除该冗余的关键帧。

 

1.SetAcceptKeyFrames(false)函数,根据mbAcceptKeyFrames变量是否为true,标志位决定是否插入关键帧,如果为false,跟踪线程中就不会插入关键帧到队列中了,对应Tracking::NeedNewKeyFrame()函数中bool bLocalMappingIdle = mpLocalMapper->AcceptKeyFrames(); 跟踪线程中会实时读这个值是否局部建图线程空闲。

2.CheckNewKeyFrames()函数检查队列中是否有关键帧,如果有的话,开始处理关键帧队列,

3.ProcessNewKeyFrame()函数,从队列中取出关键帧,计算当前关键帧特征点的BoW映射关系,从当前关键帧的描述子中得到对应的词袋向量和节点的特征向量和特征索引,将地图点与新关键帧关联并更新法线和描述符,更新当前关键帧的地图点和共视关系,将当前关键帧插入地图中。

4.MapPointCulling()函数,删除一些当前关键帧更新的不合理地图点(应该被很多关键帧观测到但是没有,需要剔除当前关键帧更新的不合理地图点)。1.检查最近添加的地图点,2.有几种情况需要删除不合理的地图点,pMP->GetFoundRatio()<0.25,间隔超过三个关键帧。

5.CreateNewMapPoints()函数,

1.在可见的共视图中检索相邻关键帧,

2.对极约束搜索匹配与三角化,

   首先检查基线是否太短

   计算基本矩阵

   搜索匹配满足对极约束

   对每个匹配项进行三角化

  三角化成功,添加地图点和地图点的属性

6. Optimizer::LocalBundleAdjustment(mpCurrentKeyFrame,&mbAbortBA, mpMap);

局部BA

7.KeyFrameCulling(); 冗余关键帧删除,如果关键帧中 90%以上的地图点能被其它至少3 个共视关键帧观测到,则剔除该关键帧。

检查冗余关键帧(仅局部关键帧),如果一个关键帧看到的90%的地图点至少在其他3个关键帧中(在相同或更精细的比例中)看到,则该关键帧被认为是多余的。

if(nRedundantObservations>0.9*nMPs)   

pKF->SetBadFlag();

mpLoopCloser->InsertKeyFrame(mpCurrentKeyFrame);

向回环检测线程中插入当前关键帧。