根据六老师所说,orb-slam2的局部建图线程包括如下作用
输入的关键帧来自跟踪里新建的关键帧。为了增加局部地图点数目,局部地图里关键帧
之间会重新进行特征匹配,生成新的地图点,局部BA会同时优化共视图里的关键帧位姿和地图点,
优化后也会删除不准确的地图点和冗余的关键帧。
对于这个描述,我有如下疑问:
1. 在tracklocalmap中,orb-slam2有增加每一帧对于地图点的观测的操作,但是没有直接增加地图点,而在localmapping中,增加地图点的操作是否和它有所关联呢?
2. 共视图有多大?关键帧的数目有多少?那些关键帧会算作共视图的关键帧?
3. 优化后删除的地图点,如何判断它不准确?
4 什么样的关键帧回被认为是冗余的?
CreateNewMapPoints(), SearchInNeighbors()
CreateNewMapPoints的逻辑包括如下:
const vector vpNeighKFs = mpCurrentKeyFrame->GetBestCovisibilityKeyFrames(nn);
寻找与当前帧共视关系最高的n帧关键帧
将当前帧与NeighKFs匹配,寻找共视特征点,利用三角化构建地图点。在三角化后,还要对相关数据结构进行一定的维护。值得主义的是,三角化后得到的点之后将会被进行严格的筛选。
-
- // Step 6.9:为该MapPoint添加属性:
- // a.观测到该MapPoint的关键帧
- pMP->AddObservation(mpCurrentKeyFrame,idx1);
- pMP->AddObservation(pKF2,idx2);
-
- mpCurrentKeyFrame->AddMapPoint(pMP,idx1);
- pKF2->AddMapPoint(pMP,idx2);
-
- // b.该MapPoint的描述子
- pMP->ComputeDistinctiveDescriptors();
-
- // c.该MapPoint的平均观测方向和深度范围
- pMP->UpdateNormalAndDepth();
-
- mpMap->AddMapPoint(pMP);
-
- // Step 6.10:将新产生的点放入检测队列
- // 这些MapPoints都会经过MapPointCulling函数的检验
- mlpRecentAddedMapPoints.push_back(pMP);
之前三角化得到了很多特征点,但是很多特征点可能是重复的,因此,我们需要把特征点的信息技进行合并,融合。
将当前帧的地图点投影到一级关键帧和二级关键帧,
1.如果地图点能匹配关键帧的特征点,并且该点有对应的地图点,那么选择观测数目多的替换两个地图点
2.如果地图点能匹配关键帧的特征点,并且该点没有对应的地图点,那么为该点添加该投影地图点
将两级关键帧的特征点投影到当前帧,寻找匹配点对应的地图点进行融合,称为反向投影融合。
融合过程中,需要对地图点的描述子进行更新,其更新的策略就是使用到其他帧描述子距离最近的点。
Optimizer::LocalBundleAdjustment()
LocalBundleAdjustment() provides a BA optimization when the current keyframe number larger than 2, 值得注意的是,这里同时优化了地图点的位置和关键帧的位姿。
现在可以回答之前的问题了。
1. 在tracklocalmap中,orb-slam2有增加每一帧对于地图点的观测的操作,但是没有直接增加地图点,而在localmapping中,增加地图点的操作是否和它有所关联呢?
YES,在localmapping中,通过三角化,地图点以及各帧对于地图点观测的数目都大大增加。
2. 共视图有多大?关键帧的数目有多少?那些关键帧会算作共视图的关键帧?
共视图包含一级关键帧和二级关键帧,其中一级关键帧的数目取决于相机模式,在单目情况下,可以达到20帧,其他情况10帧。然后,以一级相邻关键帧的共视关系最好的5个相邻关键帧 作为二级相邻关键帧
3. 优化后删除的地图点,如何判断它不准确?
其实,没有删除,只是融合,融合的依据主要是描述子的相似度,地图点到关键帧的光心距离(太远或者太近都不行),根据所在金字塔尺寸选择合适的搜索距离。
这么一看,融合的要求还是很严格的
4. 什么样的关键帧回被认为是冗余的?
在函数KeyFrameCulling()中, 如果一个关键帧有90%的点被其他关键帧观测超过3次以上,那么认为这个关键帧是冗余的。