一步步帶你看懂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特徵點提取(二)

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