轉載請註明出處,謝謝
原創做者: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 三個線程的具體內容,我會在之後的博文中進行更爲詳細的介紹和梳理。