文章目录
08 局部建图线程 LocalMapping
8.0 总览
局部建图线程连接了跟踪线程和闭环线程。局部建图线程接收跟踪线程输入的关键帧,利用关键帧的共视关系生成新的地图点,搜索融合相邻关键帧的地图点,然后进行局部地图优化、删除冗余关键帧等操作,最后将处理后的关键帧发送给闭环线程。
成员函数/变量 | 访问控制 | 意义 |
---|---|---|
std::list<KeyFrame*> mlNewKeyFrames | protected | Tracking 线程向 LocalMapping 线程插入关键帧的缓冲队列 |
void InsertKeyFrame(KeyFrame* pKF) | public | 向缓冲队列 mlNewKeyFrames 内插入关键帧 |
bool CheckNewKeyFrames() | protected | 查看缓冲队列mlNewKeyFrames 内是否有待处理的新关键帧 |
int KeyframesInQueue() | public | 查看缓冲队列mlNewKeyFrames 内关键帧个数 |
bool mbAcceptKeyFrames | protected | LocalMapping 线程是否愿意接收 Tracking 线程传来的新关键帧 |
bool AcceptKeyFrames() | public | mbAcceptKeyFrames 的 get 方法 |
void SetAcceptKeyFrames(bool flag) | public | mbAcceptKeyFrames 的 set 方法 |
Tracking
线程所创建的所有关键帧都被插入到 LocalMapping
线程的缓冲队列 mlNewKeyFrames
中。
成员函数 mbAcceptKeyFrames
表示当前 LocalMapping
线程是否愿意接收关键帧,这会被 Tracking
线程函数 Tracking::NeedNewKeyFrame()
用作是否生产关键帧的参考因素之一;但即使 mbAcceptKeyFrames
为 false
,在系统很需要关键帧的情况下 Tracking
线程函数 Tracking::NeedNewKeyFrame()
也会决定生成关键帧。
8.1 局部建图主函数:Run()
成员函数/变量 | 访问控制 | 意义 |
---|---|---|
void SetAcceptKeyFrames(bool flag) | public | mbAcceptKeyFrames 的 set 方法 |
bool CheckNewKeyFrames() | protected | 查看缓冲队列mlNewKeyFrames 内是否有待处理的新关键帧 |
void ProcessNewKeyFrame() | protected | 处理队列中第一个关键帧 |
void MapPointCulling() | protected | |
void CreateNewMapPoints() | protected | |
void SearchInNeighbors() | protected | |
void KeyFrameCulling() | protected |
函数 LocalMapping::Run()
是 LocalMapping
线程的主函数,该函数内部是一个死循环,每3毫秒查询一次当前线程缓冲队列 mlNewKeyFrames
。若查询到了待处理的新关键帧,就进行处理。
8.1.1 处理队列中第一个关键帧: ProcessNewKeyFrame()
8.1.2 剔出坏地图点:MapPointCulling()
冗余地图点的标准,满足以下条件之一就是坏地图点:
① 召回率=实际观测到该地图点的帧数/理论上应当观测到该地图点的帧数<0.25
② 在创建的 3 帧内观测数目少于2(双目小于3)
8.1.3 创建新地图点:CreateNewMapPoints()
将当前关键帧分别与共视程度最高的前 10 (单目相机取 20 )个共视关键帧两两进行特征匹配,生成地图点。
8.1.4 融合当前关键帧和其共视帧的地图点: SearchInNeighbors()
本函数将当前关键帧与其一级和二级共视关键帧做地图点融合,分两步:
- 正向融合: 将当前关键帧的地图点融合到各共视关键帧中;
- 反向融合: 将各共视关键帧的地图点融合到当前关键帧中。
ORBmatcher::Fuse()
将地图点与帧中图像的特征点匹配,实现地图点融合。
在将地图点反投影到帧中的过程中,存在以下两种情况:
-
若地图点反投影对应位置上不存在地图点,则直接添加观测;
-
若地图点反投影位置上存在对应地图点,则将两个地图点合并到其中观测较多的那个。
8.1.5 局部BA优化: Optimizer::LocalBundleAdjustment()
局部 BA 优化当前帧的局部地图。
当前关键帧的一级共视关键帧位姿会被优化,二极共视关键帧会加入优化图,但其位姿不会被优化。
所有局部地图点位姿都会被优化。
8.1.6 剔除冗余关键帧: KeyFrameCulling()
如果一个关键帧的地图点 90% 都能被超过 3 个其他关键帧观测到,则该帧冗余。(具体来说,就是遍历该关键帧的地图点,若某一地图点被超过3个其他关键帧观测到,则该地图点冗余,最终冗余地图点超过 90 %,则该关键帧冗余。)