orbslam3建图相关
2022-01-28 12:05:01 23 举报
orbslam3,跟建图相关部分,仅供参考
作者其他创作
大纲/内容
step1:遍历当前帧的地图点,标记这些地图点不参与之后的投影匹配step2:遍历所有局部地图点中除当前帧地图点外的点,判断是否在当前帧视野范围内• 如果在视野内,则该mappoint被观测的统计值加1,参与之后的投影匹配step3:当前帧mCurrentFrame通过投影匹配,获得更多的匹配关系• 调用SearchByProject
CreateNewKeyFrame()
Essential图
OK
system线程
上一帧跟踪成功
step1:从缓冲队列中取出一帧关键帧step2:计算该关键帧特征点的Bow信息step3:当前处理关键帧中有效的地图点,更新normal,描述子等信息step4:更新关键帧间的连接关系(共视图)step5:将该关键帧插入到地图中
构造Frame
当前帧跟踪失败
法向量和深度
处理新的关键帧
局部地图跟踪失败
剔除质量不佳的地图点
track线程
mpReplaced属性
当前帧跟踪成功
非OK
Active地图(1个新地图)
mbOnlyTracking(false)
处理列表中的关键帧,包括计算BoW、更新观测、描述子、共视图,插入到地图等
是
LOST
PoseOptimization()最小化投影误差优化位姿
初始化
生成关键帧
return
MonocularInitialization()
注:mpIniORBextractor相比mpORBextractorLeft提取的特征点多一倍
Visible属性
step4:删除在BA中检测为外点的地图点
重定位失败
NeedNewKeyFrame()
step3.2:关键帧插入到列表 mlNewKeyFrames中,等待local mapping处理
mState系统状态
Frame
mlNewKeyFrames
GrabImageMonocular(im)
检查并融合当前关键帧与相邻关键帧帧(两级相邻)中重复的地图点。1.先完成相邻关键帧与当前关键帧的地图点的融合(在相邻关键帧中查找当前关键帧的地图点)2.再完成当前关键帧与相邻关键帧的地图点的融合(在当前关键帧中查找当前相邻关键帧的地图点)
mbBad属性
false
LocalBundleAdjustment()LocalInertialBA()InitializeIMU()
tracking线程主要任务就是为当前帧跟踪尽可能多的地图点:1.TrackReferenceKeyFrame()通过SearchByBoW(),上一帧中包含了地图点,对这些地图点进行跟踪,由此增加当前帧的地图点2.TrackWithMotionModel()通过SearchByProjection(),将上一帧的地图点投影到当前帧(根据速度模型可以估计当前帧的Tcw),在投影点附近根据描述子距离选取匹配,以及最终的方向投票机制进行剔除3.TrackLocalMap()的SearchLocalPoints()通过 SearchByProjection(),只对除了 <新增加的,即 TrackReferenceKeyFrame() 函数中匹配上的>地图点进行 SearchByProjection(),以向mCurrentFrame增加新的地图点.
nObs属性
注:在跟踪线程中,涉及到建图的更多是每一帧的地图点
true
上一帧跟踪失败
设置true,即为坏点,相当于擦除了该地图点(实际上要等程序结束,调用析构函数才能回收分配的内存)。成员函数 MapPoint::EraseObservation() 、Replace() 函数(详细解释参见mpReplaced属性)和 MapPoint::SetBadFlag() 函数会设置该属性
step1:在当前关键帧的共视关键帧中找到共视程度最高的n帧相邻关键帧(单目为20)step2:遍历step1中选取的n帧相邻关键帧2.1:判断相机运动的基线/视差角是不是足够长2.2:根据两个关键帧的位姿计算它们之间的基础矩阵2.3:查找特征匹配,通过BoW加速匹配,生成新的匹配点对(借助F矩阵剔除Outlier)2.4:对每对匹配点通过三角化生成3D点2.5:将3D点构造为MapPoint并mlpRecentAddedMapPoints进行一致性观测检查
局部地图跟踪成功
局部BA优化/IMU初始化一阶段
非OK
step3:按需求添加关键帧
收集mvpLocalKeyFrames中每帧关键帧的Mappoints -->mvLocalMapPoints
共视图是一个加权无向图,图中每个节点是相机位姿,若两个关键帧观测到的相同关键点达到一定数量,认为两者具有共视关系。即生成了一条边,边的权重与共视点数量有关。
SetAcceptKeyFrames(true)
Atlas地图集
地图点
UpdateLocalKeyFrames()更新局部关键帧
Non-Active地图(n个旧地图)
step1:根据相机类型设置不同的观测阈值step2:遍历检查的新添加的地图点作用:剔除mlpRecentAddedMapPoints中不好的MapPointsmlpRecentAddedMapPoints来自于:• 通过CreateNewMapPoints函数,关键帧之间三角化恢复一些MapPoints剔除MapPoint的标准为(观测一致性,从被创建开始,未被连续可靠观测到):• mnFound / mnVisible < 25%• 从MapPoint被创建开始,到现在已经过了不小于2帧关键帧,但是该MaPoints被观测到的关键帧数小于阈值(单目为2)• 从MapPoint被创建开始,到现在已经超过帧关键帧
KeyFrameCulling()
InitializeIMU()ScaleRefinement()
MapPoints
Mono: mImGray
Replace()函数会对该属性操作,有两个地方会对该属性进行修改:1.在形成闭环的时候,会更新关键帧与地图点之间的关系,<闭环帧的中地图点> 对应的描述子与 <当前帧的地图点> 对应的描述子相近(即二者匹配上了),就认为这两个地图点是同一个地图点(因为它们是来自同一个特征点),那么就使用闭环帧对应的地图点替换当前帧中地图点2.local mapping线程中,由于当前关键帧产生新的地图点点后,这些地图点有可能会被其他关键帧找到,所以在SearchInNeighbors() 中,分别与一级二级相邻帧(的地图点)中重复的进行合并,将会出现下面两种情况:(1)如果地图点能匹配关键帧的特征点,并且该点有对应的地图点,那么将两个地图点合并(选择观测数多的)(2)如果地图点能匹配关键帧的特征点,并且该点没有对应的地图点,那么为该点添加地图点。
LocalMapping线程
最小生成树
orb关键点具有旋转不变性和尺度不变性。一个地图点会被许多相机观测到,因此每次插入对某个关键帧的Observation后,需要调用 UpdateNormalAndDepth():1.由该地图点的3D位置到所有 <该MapPoint的观测到关键帧光心> 向量均值确定法向量。2.由它在参考关键帧(创建该地图点时指定)对应的关键点的金字塔层,更新该地图点的最大深度mfMaxDistance和最小深度mfMinDistance
转为灰度图
step2:判断IMU模式并且还未进行IMU初始化
是否生成关键帧
共视图
关键帧
参考帧第一次观测到该点的关键帧
SearchLocalPoints()获得局部地图与当前帧的匹配
当前帧与邻域帧地图点融合
step2:清除观测不到的地图点
bOK跟踪状态
font color=\"ff0000\
UpdateConnections()
CheckNewKeyFrames()
将LocalMapping线程设为空闲
step1:更新匀速运动模型
Relocalization()
地图词袋DBoW2全部子地图共用
step1:统计与当前关键帧每个地图点存在共视关系的关键帧,统计结果放在KFcounterstep2:找到对应权重最大的关键帧(共视程度最高的关键帧)step3:如果没有连接到关键(超过阈值的权重),则对权重最大的关键帧建立连接step4:对共视程度比较高的关键帧对更新连接关系及权重(从大到小)step5:更新生成树的连接
从当前共视关键帧中剔除冗余关键帧
UpdateLocalPoints()更新局部地图点
局部地图跟踪
step1:能观测到当前帧的Mappoints的关键帧-->keyframeCounterstep2:除去无效的关键帧--> mvpLocalKeyFrames• mvpLocalKeyFrames中与其它(共视)连接最多的关键帧作为参考帧mpReferenceKFstep3:共视关键帧也添加进来• mvpLocalKeyFrames中每一帧共视比较好的10帧也添加进来• 自己的子关键帧• 自己的父关键帧
CreateNewMapPoints()
否
相机位姿跟踪
UpdateLocalMap()//更新局部地图
step3.1:将该Frame构建成KeyFrame关键帧
将LocalMapping线程设为繁忙
地图超过10个关键帧时RECENTLY_LOST
ProcessNewKeyFrame()
MapPointCulling()
记录哪些关键帧的那个特征点能观测到该地图点,单目+1。注意,该属性只对关键帧有效这个函数是建立关键帧共视关系的核心函数,能共同观测到某些地图点的关键帧是共视关键帧.
位姿跟踪
IMU时为RECENTLY_LOST
重置当前地图,退出当前跟踪
为当前帧添加地图点
TrackReferenceKeyFrame()
生成新的MapPoints:1.初始化时,使用H矩阵或者F矩阵得到R,t后,使用线性三角化生成新的MapPoints2.local mapping线程CreateNewMapPoints() 通过线性三角化方式生成新的MapPoint
创建新的地图点
共视图连接关系非常稠密,不利于实时的优化。于是构建了Essential图,Essential 图中的节点是全部关键帧的位姿,边包含三种边:生成树的边、共视图中共视关系强(共视点数量超过100)的边、回环形成的边。
注:局部建图线程,首先处理单帧关键帧,更新Atlas需要的词袋、共视图、生成树等。然后优化地图点的质量(包括剔除不好的地图点,产生新的地图点),再降低地图点的数量(与邻域帧融合地图点),最后剔除冗余关键帧。
检查是否有新的关键帧
上一帧跟踪失败(LOST)
step1:取出与当前关键帧共视的所有关键帧vpLocalKeyFrames|step2:对于vpLocalKeyFrames中每个关键帧判断是否是冗余关键帧• 取出该关键帧对应的MapPoints---> vpMapPoints• 如果vpMapPoints中有90%的MapPoints可被至少3帧尺度近似的关键帧观测到,则为冗余关键帧
该属性表示,能观测到该地图点的图像帧数目计数器:1.在track线程跟踪局部地图时,使用 SearchLocalPoints() 向当前帧增加新的地图点时, 首先对当前帧已经匹配上地图点各自的Visible属性增加计数 然后搜索局部地图,只要该地图点满足到当前帧的投影条件,就增加一次计数。2.满足上面的投影条件就增加计数,但这些地图点并不一定能和当前帧的特征点匹配上,这就是 SearchByProjection() 函数要做的事情. 注意,这里并没有对这些匹配上的地图点与当前帧进行关联,仅仅是把匹配上的地图点添加到当前帧mvpMapPoints属性中3.在local mapping中fuse当前关键帧新生成的地图点时、以及形成闭环时,会调用 Replace() 函数进行替换,会对观测更多的地图点增加计数,增加的数目为原来那个地图点的计数值.
step1:获得当前关键帧在共视图中权重排名前n的邻接关键帧(单目为10)step2:存储一级相邻关键帧及其二级相邻关键帧step3:将当前帧的地图点分别与一级二级相邻关键帧地图点进行融合 -- 正向step4:将一级二级相邻关键帧地图点分别与当前关键帧地图点进行融合 -- 反向step5:更新当前帧地图点的描述子、深度、观测主方向等属性step6:更新当前帧的地图点后,更新与其它帧的连接关系
SearchInNeighbors()
输入图像
重定位成功
跟踪
剔除冗余关键帧
TrackWithMotionModel()
SetAcceptKeyFrames(false) 线程状态同步
InsertKeyFrame()
产生新的地图点
一个地图点可能被很多关键帧观测到,使用ComputeDistinctiveDescriptors() 函数选择最具代表性的描述子,因此当地图点添加了新的关键帧观测后,需要判断是否更新当前点的最适合的描述子.选取规则是,先获得当前点的所有描述子,然后计算描述子之间的两两距离,最好的描述子与其他描述子应该具有最小的距离中值
生成树用最少的边连接所有关键帧节点(即共视图中所有的节点)。当一个关键帧被加入到共视图当中后,这个关键帧与共视图中具有最多观测点的关键帧之间建立一个边,完成生成树的增长
关键帧加入闭环检测队列
mbOnlyTracking(true)
step3:创建新的地图//即地图关键帧超过5帧&&纯视觉模式||IMU模式且已初始化
IMU初始化二、三阶段
step1:判断地图中关键帧数量是否小于5帧
mDescriptor属性
收藏
收藏
0 条评论
下一页