概述
ORBSLAM2学习笔记(3)——局部地图
LocalMapping初始化
在上一章我们完整地走完了程序的主线程,然而丝毫没有看到局部建图和闭环的身影。这两个功能的入口是在哪里呢? 回到最初的起点,在实例化system对象时,system类的构造函数有如下段落:
//Initialize the Local Mapping thread and launch
mpLocalMapper = new LocalMapping(mpMap, mSensor==MONOCULAR);
mptLocalMapping = new thread(&ORB_SLAM2::LocalMapping::Run,mpLocalMapper);
//Initialize the Loop Closing thread and launch
mpLoopCloser = new LoopClosing(mpMap, mpKeyFrameDatabase, mpVocabulary, mSensor!=MONOCULAR);
mptLoopClosing = new thread(&ORB_SLAM2::LoopClosing::Run, mpLoopCloser);
这些语句实例化了建图和闭环对象,并且开辟了新的线程来执行后端建图和闭环的Run函数。我们先从localMapping看起吧。
该函数是一个大的while循环。在循环的开始,通过SetAcceptKeyFrames(false)来告诉tracking线程自己在忙,不要发送关键帧给我了。之后,从等待列表中取出一帧关键帧,计算它的bow描述子,遍历该帧匹配上的地图点,为这些地图点更新观测信息。最后进行帧相关的操作,即依据该帧更新共视图和将该帧插入图中。
共视图的更新
什么是共视图呢?共视图就是反映帧与帧之间联系关系的一种图。在建立共视图之间,只有帧和关键点之间有联系。共视图会记录下与每个关键帧共同地图点最多的前几关键帧。
1.遍历当前帧的地图点,统计能观测到这些地图点的关键帧及其观测到地图点的数目,存放在KFcounter中。
2.遍历KFcounter,对其中共同地图点数目大于阈值的关键帧通过AddConnection(this,mit->second)函数建立链接,其实就是把这一帧存放在当前帧的mConnectedKeyFrameWeights中。
3.更新生成树。生成树即一颗链接关键帧的最小树,每个关键帧都将共视程度最高的树作为自己的父树。
地图点的删除、更新和融合
在插入新关键帧和创建新地图点后,这些点的质量可能不太ok,所以需要通过函数MapPointCulling()来删除。可删除的情况有以下几种:
1.观测到该点的帧数与理论上可观测到该点的帧数比小于1/4
2.从该关键点被创建开始以及过了两个以上关键帧,但能观测到该点的关键帧数却小于阈值(单目试是3,双目是2)。
之后,会调用CreateNewMapPoints()通过相邻帧的三角化恢复一些地图点。
1.得到当前帧共视程度最高的前n帧,称为相邻帧。之后求出当前帧和相邻帧的世界坐标以此来求出基线长度,当基线足够长,景深
也不太长时才去生成地图点。
2.计算两帧之间的基本矩阵,调用
matcher.SearchForTriangulation(mpCurrentKeyFrame,pKF2,F12,vMatchedIndices,false);
通过极线约束限制匹配时的搜索范围,进行特征点匹配。匹配之后使用三角法进行重建,确定该点在相机前方后再计算重投影误差,小于阈值则认为匹配有效。之后,把该点包装为Mappoint就好啦。
最后,需要做的是地图点的融合,因为要有可能出现这样的情况,明明是同一个空间点,却通过不同方式多次添加为地图点。方法如下
1.找出当前帧的相邻关键帧和相邻关键帧的相邻关键帧。
2.将当前帧的地图点与相邻关键帧的特征点进行匹配,匹配上之后,如果该特征点以及有地图点了,就融合这两个地图点。之后,将相邻关键帧的地图点与当前帧的地图点匹配。
最后,做一些更新工作,例如地图点的描述子,平均观测方向,共视图等等。
这些步骤完成后,会进行一次localBA来优化位姿与地图点.调用KeyFrameCulling删除冗余帧(90以上的地图点都能被三个关键帧观测到),将当前帧加入到闭环检测队列中,就完成了一次建图循环.
最后
以上就是优雅茉莉为你收集整理的ORBSLAM2学习笔记(3)——局部地图ORBSLAM2学习笔记(3)——局部地图的全部内容,希望文章能够帮你解决ORBSLAM2学习笔记(3)——局部地图ORBSLAM2学习笔记(3)——局部地图所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复