ORB-SLAM3 单目地图初始化(终结篇)

本文详细解析ORB-SLAM3单目地图初始化过程,包括CreateInitialMapMonocular函数的8个步骤,涉及描述子转BoW、关键帧插入地图、3D点生成、全局BA优化、尺度归一化等。文中探讨单目初始化的挑战,如逆深度参数初始化、基础矩阵与单应矩阵的选择,并介绍共视图、地图点与关键帧、图优化和g2o库的使用方法。最后总结图优化与相机模型的重要性,并提供参考资料。
摘要由CSDN通过智能技术生成

点击上方“计算机视觉工坊”,选择“星标”

干货第一时间送达

一、前言

请阅读本文之前最好把ORB-SLAM3的单目初始化过程再过一遍(ORB-SLAM3 细读单目初始化过程(上)超详细解读ORB-SLAM3单目初始化(下篇)),以提高学习效率。单目初始化过程中最重要的是两个函数实现,分别是构建帧(Frame)和初始化(Track)。接下来,就是完成初始化过程的最后一步:地图的初始化,是由CreateInitialMapMonocular函数完成的,本文基于该函数的流程出发,目的是为了结合代码流程,把单目初始化的上下两篇的知识点和ORB-SLAM3整个系统的知识点串联起来,系统化零碎的知识,告诉你平时学到的各个小知识应用在SLAM系统中的什么位置,达到快速高效学习的效果。

二、CreateInitialMapMonocular 函数的总体流程

1. 将初始关键帧,当前关键帧的描述子转为BoW;

2. 将关键帧插入到地图;

3. 用三角测量初始化得到的3D点来生成地图点,更新关键帧间的连接关系;

4. 全局BA优化,同时优化所有位姿和三维点;

5. 取场景的中值深度,用于尺度归一化;

6. 将两帧之间的变换归一化到平均深度1的尺度下;

7. 把3D点的尺度也归一化到1;

8. 将关键帧插入局部地图,更新归一化后的位姿、局部地图点。

三、必备知识

1. 为什么单目需要专门策略生成初始化地图

根据论文《ORB-SLAM: a Versatile and Accurate Monocular SLAM System》,即ORB-SLAM1的论文(中文翻译版[ORB-SLAM: a Versatile and Accurate Monocular SLAM System](https://blog.csdn.net/weixin_42905141/article/details/102857958))可知:

1) 单目SLAM系统需要设计专门的策略来生成初始化地图,这也是为什么代码中单独设计一个CreateInitialMapMonocular()函数来实现单目初始化,也是我们这篇文章要讨论的。为什么要单独设计呢?就是因为单目没有深度信息。

2) 怎么解决单目没有深度信息问题?有2种,论文用的是第二种,用一个具有高不确定度的逆深度参数来初始化点的深度信息,该参数会在后期逐渐收敛到真值。

3) 说了ORB-SLAM为什么要同时计算基础矩阵F和单应矩阵H的原因:这两种摄像头位姿重构方法在低视差下都没有很好的约束,所以提出了一个新的基于模型选择的自动初始化方法,对平面场景算法选择单应性矩阵,而对于非平面场景,算法选择基础矩阵。

4)说了ORB-SLAM初始化容易失败的原因:(条件比较苛刻)在平面的情况下,为了保险起见,如果最终存在双重歧义,则算法避免进行初始化,因为可能会因为错误选择而导致算法崩溃。因此,我们会延迟初始化过程,直到所选的模型在明显的视差下产生唯一的解。

2. 共视图 Covisibility Graph

共视图非常的关键,需要先理解共视图,才能更好的理解后续程序中如何设置顶点和边。

2.1 共视图定义

共视图是无向加权图,每个节点是关键帧,如果两个关键帧之间满足一定的共视关系(至少15个共同观测地图点)他们就连成一条边,边的权重就是共视地图点数目。

2.2 共视图作用

2.2.1 跟踪局部地图,扩大搜索范围

• Tracking::UpdateLocalKeyFrames()

2.2.2 局部建图里关键帧之间新建地图点

• LocalMapping::CreateNewMapPoints()

• LocalMapping::SearchInNeighbors()

2.2.3 闭环检测、重定位检测

• LoopClosing::DetectLoop()、LoopClosing::CorrectLoop()

• KeyFrameDatabase::DetectLoopCandidates

• KeyFrameDatabase::DetectRelocalizationCandidates

2.2.4 优化

• Optimizer::OptimizeEssentialGraph

3. 地图点 MapPoint 和关键帧 KeyFrame

地图点云保存以下信息:

1)它在世界坐标系中的3D坐标

2) 视图方向,即所有视图方向的平均单位向量(该方向是指连接该点云和其对应观测关键帧光心的射线方向)

3)ORB特征描述子,与其他所有能观测到该点云的关键帧中ORB描述子相比,该描述子的汉明距离最小

4)根据ORB特征尺度不变性约束,可观测的点云的最大距离和最小距离

4. 图优化 Graph SLAM

可先看看这些资料[《计算机视觉大型攻略 —— SLAM(2) Graph-based SLAM(基于图优化的算法)》](https://blog.csdn.net/plateros/article/details/103498039),还有《概率机器人学》的第11章,深入理解图优化的概念。

我们在文章开头说过,单目初始化结果得到了三角测量初始化得到的3D地图点Pw,计算得到了初始两帧图像之间的相对位姿(相当于得到了SE(3)),通过相机坐标系Pc和世界坐标系Pw之间的公式,(参考[《像素坐标系、图像坐标系、相机坐标系和世界坐标系的关系(简单易懂版)》](https://blog.csdn.net/shanpenghui/article/details/110481140))

得到相机坐标系的坐标Pc,但是这样还是不能和像素坐标比较。我们接着通过相机坐标系Pc和像素坐标系P(u,v)之间的公式

5. g2o使用方法

关于g2o库的使用方法,可以参考[《G2O图优化基础和SLAM的Bundle Adjustment(光束平差)》](http://zhaoxuhui.top/blog/2018/04/10/g2o&bundle_adjustment.html#2g2o%E5%BA%93%E7%AE%80%E4%BB%8B%E4%B8%8E%E7%BC%96%E8%AF%91%E5%AE%89%E8%A3%85)和[《理解图优化,一步步带你看懂g2o代码》](https://www.cnblogs.com/CV-life/p/10286037.html)。一般来说,g2o的使用流程如下:

5.1创建一个线性求解器LinearSolver

5.2创建BlockSolver,并用上面定义的线性求解器LinearSolver初始化

5.3创建总求解器solver,并从GN, LM, DogLeg 中选一个,再用上述块求解器BlockSolver初始化

5.4创建终极大boss 稀疏优化器(SparseOptimizer),并用已定义的总求解器solver作为求解方法

5.5定义图的顶点和边,并添加到稀疏优化器(SparseOptimizer)中

5.6设置优化参数,开始执行优化

四、代码

1. 将初始关键帧,当前关键帧的描述子转为BoW

pKFini->ComputeBoW();
pKFcur->ComputeBoW();

不展开词袋BoW,只需要知道一点,就是我们在回环检测的时候,需要用到词袋向量mBowVec和特征点向量mFeatVec,所以这里要计算。

2. 向地图添加关键帧

mpAtlas->AddKeyFrame(pKFini);
mpAtlas->AddKeyFrame(pKFcur);

3. 生成地图点,更新图(节点和边)

3.1 遍历

for(size_t i=0; i<mvIniMatches.size();i++)

因为要用三角测量初始化得到的3D点,所以外围是一个大的循环,遍历三角测量初始化得到的3D点mvIniP3D。

3.2 检查

if(mvIniMatches[i]<0)
continue;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值