转载请注明出处,谢谢
原创做者:MingruiYU
原创连接:http://www.javashuo.com/article/p-vfwwcuxe-cg.htmlhtml
本文要点:ios
最近准备开始作本科毕业设计,准备对 SLAM 系统中的回环检测模块下手。由于新冠疫情不知道何时才能返校,此次放假回家就带了个 matebook 14 回来,搬砖全靠这小电脑,它苦我也苦(流泪)。web
做为开源 SLAM 系统中的经典之一 —— ORB-SLAM2,天然是要拿来好好研究一番。以前阅读了 ORB-SLAM 和 ORB-SLAM2 论文,以后配置安装了 ORB-SLAM2 跑了个 example 看看样子(个人博文 ORB-SLAM2 初体验 —— 配置安装),这回准备开始磕代码。但越磕愈加现,这玩意也太复杂了吧。为了实现较好的鲁棒性,ORB-SLAM2 中加入了不少不少小 trick 来从细节上提高系统的性能。这些细节在论文里每每就是一句话带过,但在代码里就是一大堆环环相扣绕来绕去的东西。虽然你们都说 ORB-SLAM2 的代码是结构清晰,注释完整,易于理解,但本渣渣仍是看的把头发挠成了鸟窝状。app
因此,我决定经过写博文的方式,来更好地梳理 ORB-SLAM2 代码的框架和步骤,以加深本身的理解,也但愿个人梳理可以对你们有所帮助。框架
ORB-SLAM是15年Raul等人提出的一个单目SLAM系统,其在单目SLAM领域影响普遍。详情可见论文:[Monocular] Raúl Mur-Artal, J. M. M. Montiel and Juan D. Tardós. ORB-SLAM: A Versatile and Accurate Monocular SLAM System. IEEE Transactions on Robotics, vol. 31, no. 5, pp. 1147-1163, 2015. (2015 IEEE Transactions on Robotics Best Paper Award). PDF.svg
在单目ORB-SLAM的基础上,17年Raul等人又提出了ORB-SLAM2,增长了对于双目相机和RGB相机的支持。详情可见论文:[Stereo and RGB-D] Raúl Mur-Artal and Juan D. Tardós. ORB-SLAM2: an Open-Source SLAM System for Monocular, Stereo and RGB-D Cameras. IEEE Transactions on Robotics, vol. 33, no. 5, pp. 1255-1262, 2017. PDF函数
ORB-SLAM2 的论文中,对于单目部分并无作很大修改,也没有笔墨去重写单目实现的细节。而其虽然增长了双目和 RGB-D 相机的支持,但本质上仍是在单目系统的基础上加的,并非从根本上以双目或 RGB-D 输入为设计出发点。因此我的认为,学习 ORB-SLAM2 仍是要以单目为主,不能绕开单目去看双目或 RGB-D 的实现。另外,由于 ORB-SLAM2 论文中并无重写单目实现的细节,因此对于 ORB-SLAM2 的学习仍是要从第一篇 ORB-SLAM 的论文入手。如下内容均以 ORB-SLAM 单目部分为基础。oop
ORB-SLAM2 中的实体对象包括:性能
它们之间的关系是这样的:学习
下面我会从论文和代码(程序导图)两个角度出发,对 ORB-SLAM2 系统进行一个概览。
ORB-SLAM 论文中,有一张图很是经典且重要:
ORB-SLAM 系统同时运行三个线程:
其中 Covisibility Graph 指的是:其节点为全部 KF。一个 KF,若是它与另外一个 KF 观测到的相同的 MapPoints 的数量大于15个,则这两个 KFs 之间有边相连。从而组成了 Covisibility Graph。同时,Covisibility Graph 中的每条边有权重,权重即为两个 KFs 共同观测到的 MapPoints 数目。
其中 Essential Graph 指的是:系统会构造一个生成树。当一个新的 KF 插入时,将它与(与它观测到相同的 MapPoints 的数量最多的 KF)相连,从而获得一个生成树。Essential Graph = 该生成树 + Covisibility Graph 中权重大于100的边。
从上图能够看出,Covisibility Graph 中的边不少,生成树就是一条线,而 Essential Graph 介于二者之间。
上面论文里那张框架图归纳的很是好,可是这张图仍是太简略了,光看它也搞不懂每一个步骤之间的逻辑关系是怎样。而它们之间复杂的逻辑关系用大段文字更是很难描述清楚。在通读代码的时候,我常常读着读着就忘了前面读了什么,忘了如今读的部分是嵌套在哪里循环里,是属于哪一个子函数。因而我想了个办法 —— 用思惟导图来梳理代码的结构和逻辑。试验事后,我以为这个办法很好用。此处献上我梳理的很是很是大的 ORB-SLAM2 程序导图:
(若是下方显示不出来,就点 ORB-SLAM2 程序框图 连接查看吧)
这个导图梳理的挺详细的了,但愿它能对你们有帮助。(我用的 MindMaster 这款画思惟导图的软件,Windows Linux ios Andriod 都支持,同时能够将导图存储在我的云上多设备共享,另外也支持生成并分享导图连接)
我绘制的程序导图是以 mono_tum.cc 程序为入口,该程序是官方提供的 example,其对 TUM 数据集中的视频序列进行 SLAM。根据该程序,咱们能够清晰地看出该怎么调用整个 ORB-SLAM2 系统。
ORB-SLAM2 系统以 System.cc 为系统的入口,其负责建立各类对象,同时建立 Tracking,LocalMapping, LoopCLosing 三个线程并运行。其中,System::TrackMonocular()是启动 Tracking 线程的入口。Tracking 线程为主线程,而 LocalMapping 和 LoopClosing 线程是经过 new thread 建立的。
关于 Tracking,LocalMapping, LoopCLosing 三个线程的具体内容,我会在之后的博文中进行更为详细的介绍和梳理。