一步步带你看懂orbslam2源码--总体框架(一)


ORB-SLAM2目录:

   一步步带你看懂orbslam2源码–总体框架(一)
   一步步带你看懂orbslam2源码–orb特征点提取(二)
   一步步带你看懂orbslam2源码–单目初始化(三)
   一步步带你看懂orbslam2源码–单应矩阵/基础矩阵,求解R,t(四)
   一步步带你看懂orbslam2源码–单目初始化(五)


引言

   谈谈SLAM技术,其实更准确地说来应该是SLAM框架.距今为止,SLAM其实已经发展了近30多年的历史,其理论框架已经大体成熟与定型,基本上都是分为前端视觉里程计,后端基于滤波或者非线性优化,回环检测以及建图等.该技术属于底层技术,主要是服务于上层应用的需求,目前的应用点有移动机器人,自动驾驶,无人机,AR,VR等.

   SLAM从构建地图的种类进行划分,有稀疏地图,半稠密地图和稠密地图.顾名思义就是所构建地图的地图点数量的程度.从使用的传感器种类方面进行划分,有纯视觉SLAM(仅用相机),激光SLAM(纯用激光),视觉+IMU(Inertial measurement unit–惯性测量单元) SLAM,以及激光+视觉+IMU的方案.目前激光SLAM技术已经成熟,市面上的大多数扫地机器人还是采用纯激光的SLAM,但是目前激光雷达制造成本久居不下,市面价格更是及其离谱,好的激光,可能光光一个激光雷达就顶起来整辆车的价格(贵的十几万一个…),正是由于这样的原因,才促成了视觉SLAM和其他各种传感器方案的诞生.由于相机的廉价,且相机能提供丰富的场景信息,因此被广泛采用,许多学者也相继研究如何利用相机感知周围环境,构建出周围地图以及估计出自身运动轨迹.这些年来也诞生了许多优秀的纯视觉SLAM的(vSLAM)开源系统方案出来,例如:

  • 稀疏地图:
  • ORB-SLAM2(单目,双目,RGB-D,立体相机)
    半稠密地图:
  • LSD-SLAM(单目,双目,RGB-D)
  • DSO(单目)
  • SVO(单目,其实不能算一个完整的SLAM,仅VO)
    稠密地图:
  • RGB-D SLAM2(RGB-D)
  • Kintinuous(RGB-D)
  • Elastic Fusion(RGB-D)
  • Bundle Fusion(RGB-D)
  • InfiniTAM(RGB-D)
  • RTAB-Map(RGB-D,双目,LIDAR)

  然而,纯vSLAM方案虽然价格便宜,但是相机一直存在噪声大,易受曝光度的干扰,易受相机抖动的干扰,而IMU的测量频率非常高,且短时间内能够准确地测量出物体的三轴姿态角,具有较强的抗抖动干扰性能,与相机正好成互补.因此,相机+IMU的多传感器融合方案也被实际应用中广泛使用.例如,百度的Apollo5.0平台均采用了 视觉+IMU+激光雷达/毫米波雷达 的解决方案(当然,实际上远远不止那么简单…)目前,也拥有了一些比较优秀的多传感器融合方案,例如:

  • VINS(单目+IMU,双目+IMU)
  • OKVIS(单目+IMU,双目+IMU)
  • ROVIO(单目+IMU)
  • RKSLAM(单目+IMU)
  • Cartographer(LIDAR+IMU)
  • V-LOAM(LIDAR+单目)

  当然,随着这几年深度学习,机器学习的火起(虽然理论上貌似没有什么突破性进展,主要得益于计算机算力资源的巨大提升以及大量的数据,好像目前论文上也比较多水…同个方法改改应用场景等等…),笔者对此并没有深入了解,目前了解的开源方案就有:

  • CNN-SLAM:将LSD-SLAM里的深度估计和图像匹配都替换成基于CNN的方法,并可以融合语义
  • VINet: Visual-inertial odometry as a sequence-to-sequence learing problem:利用CNN和RNN构建了一个VIO,即输入image和IMU信息,直接输出估计的pose
  • 3DMV: Joint 3D-Multi-View Prediction for 3D Semantic Scene Segmentation: 联合3D多视图预测网络在室内环境中进行RGB-D扫描的3D语义场景分割
  • ScanComplete: Large-Scale Scene Completion and Semantic Segmentation for 3D Scans: 将场景的不完整3D扫描作为输入,能够预测出完整的3D模型以及每个体素的语义标签
  • DeepVO: A Deep Learning approach for Monocular Visual Odometry
  • Lightweight Unsupervised Deep Loop Closure: 用CNN解决闭环问题

ORB-SLAM2 概述

  好了,接下来开始介绍orb-slam2的内容,在以后的讲解过程中,笔者会先进行相关理论的解释,虽然有许多其他的文章也针对了orb-slam2进行讲解,但是大多数要么就仅限于理论上的讲解,缺乏细节上的把握,要么就是单单代码上的讲解(尽管也不尽详尽…).可能在笔者看来是极其简单的,可能就一句话带过了的内容(例如–采用金字塔提取ORB 特征点…),但在初学者看来可能就云里雾里了.因此,笔者会尽量讲解的通俗易懂,从理论出发,又紧紧抓住实现细节,结合部分orb-slam2源码进行讲解,使得初入门的读者也能够根据笔者所写的该系列教程,读懂orb-slam2源码.

  咳咳咳~~,扯得有点多了,开始步入正题,同学们,跟紧啦!!!

  orb-slam2总共有三个线程: Tracking , Local Mapping , Loop Closing线程(实际上其实还多了个Viewer线程,用于显示界面),Tracking 线程主要负责定位相机以及决定是否插入一个新的关键帧.将输入的每一个帧进行提取ORB Features,并且以此估计相机位姿.Local Mapping 线程主要负责处理新的关键帧以及执行局部BA以此来优化相机位姿.此外,负责新的 Map Points 的创建和剔除掉冗余的KeyFrames. Loop Closing 线程主要负责回环检测(本文利用了DBOW视觉词袋的形式进行检测回环)和全局地图优化,减少位姿累计误差漂移,将误差均匀化,使得总体误差最小.

  本系统主要有如下贡献:

  1. 将ORB特征点运用于该系统的所有环节.

  2. 在大环境下,仍然能够保持实时性的性能,使用了covisibility graph(共视图,其实就是能够观测到相同Map Points的帧,观测到相同Map Points越多,得分越高)

  3. Loop Closing 线程应用了Pose Graph来实现实时全局优化,所谓的Pose Graph 就是只考虑Pose 的优化,而不考虑Map Points的优化,需要优化的东西一下子少掉了所有的Map Points , 你说能不快吗…

  4. 拥有良好视角和光照不变性的实时重定位.

  5. 基于模型选择的自动初始化流程,利用一定的计算方式,在平面模型和非平面模型之间进行自动切换,即在恢复相机Pose 时,是通过计算E或F矩阵,还是通过计算H矩阵.

  6. 严格的Map Points 和 Keyframe 剔除机制,及时剔除冗余的Map Points 和 Keyframe , 保证系统不需要优化过多的变量,在一定程度上也提高了系统在长时间运行下的鲁棒性和实时性.

  7. 提供了单目,双目,RGB-D,Stereo多个版本

  在接下来博客的讲解中,笔者将会以 monocular版本为例进行讲解,因为笔者认为在单目,双目,RGB-D和Stereo这几种版本下,单目版本最为复杂,实现难度最高.单目模式需要通过相机之间的移动,从而进行三角测量得到其深度,而双目相机实际上就是一个现成版的相机移动模型,只不过人家已经内部集成了,根据双目相机左右眼之间的关系,计算出点的深度.而RGB-D和立体相机则更为简单,相机可以通过内部机理直接获得点的深度.


实践环节

  首先,介绍orbslam2源码中的 变量命名规则:

m: 代表类成员变量(member)
t: 线程类型变量(thread)
l: 代表list类型变量
n: 代表int类型变量
p: 代表指针类型变量(pointer)
b: 代表bool类型变量
v: 代表vector类型变量
s: 代表set 类型变量

  然后,让我们看看整个程序的main()函数入口吧,其流程图如下所示:orbslam2系统中包含了四个线程(有一个用于显示,所以论文上是说三个线程).其中,Tracking线程位于主线程之中(main函数),而Local Mapping 线程和 Loop Closing线程则位于主线程中的系统初始化之中.

// Create SLAM system. It initializes all system threads and gets ready to process frames.
ORB_SLAM2::System SLAM(argv[1],argv[2],ORB_SLAM2::System::MONOCULAR,true);

  具体说来,下面的函数负责将 rgb.txt (这个是数据集中的文档) 文档中的timestamp-filename序列存入到vTimestamps和vstrImageFilenames之中.

LoadImages(strFile, vstrImageFilenames, vTimestamps);//vstrImageFilenames存储图片,vTimestamps存储对应的时间轴

  而

 SLAM.TrackMonocular(im,tframe);// im为图片   tframe为时间 

  则是整个系统的核心所在,负责实时跟踪输入图片,具体内容将会在后面的章节中进行讲解.跟踪完所有的图片之后,系统将调用如下函数关闭所有线程.

SLAM.Shutdown();

  最后调用下面函数保存SLAM的相机跟踪轨迹(此处只是保存关键帧位姿而已,而不是包含全部帧的轨迹).

SLAM.SaveKeyFrameTrajectoryTUM("KeyFrameTrajectory.txt");

  至此,整个SLAM的基本框架和主函数入口已经讲解清楚了,具体的实现细节和内容且听下文讲解.


总结

  1. 目前SLAM应用方案及其应用点.
  2. ORB-SLAM2系统的总体框架以及该系统的主要贡献.

参考文献:

  1. 高翔–视觉SLAM十四讲
  2. ORB-SLAM a Versatile and Accurate Monocular SLAM System
  3. 知乎文章:https://zhuanlan.zhihu.com/p/62336523

PS:

  1. 如果您觉得我的博客对您有所帮助,欢迎关注我的博客。此外,欢迎转载我的文章,但请注明出处链接。
  2. 本博客仅代表个人观点,不一定完全正确,如有出错之处,也欢迎批评指正.

 
下一章节:一步步带你看懂orbslam2源码–orb特征点提取(二)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章