嗨,各位讀者朋友們好久不見。在開始之前,再碎碎念幾句。
筆者從2019年開始接觸DSO,主要是得益於趙開勇博士的指導,將我領入DSO的大門。隨后,在學習的過程中,也遇到非常多的挫折,雖然現在還有很多問題沒徹底搞清楚,但是有幸的是,泡泡機器人SLAM的朋友們為我提供了非常多的幫助,其中包括但不限於勇哥(趙開勇)、威爺(曲星威)、晨博(邱笑晨)、金戈戈(塗金戈)、龔益群、吳佳田等大佬的指導和幫助。
雖然目前對於DSO認識還比較淺薄,但是也算是多少有些收獲,因此想從現在開始把DSO整個體系再梳理一遍,更加系統地把各個模塊的知識再學習學習,同時整理成筆記(博客),算是給自己定個小目標吧。畢竟,再不寫博客的話,可能東西就快忘光了...
筆者想着跟往期的ORB-SLAM2一樣,完成每一篇博客之后,再同步把對應的源碼摳出來模塊化,使其能夠單獨運行。不得不說,肢解一個SLAM系統,將其模塊化,可真算是筆者特別喜歡的事情了... 雖然有可能會像往期的ORB-SLAM2一樣,只實現一部分,但是筆者盡力而為吧。
接下來就是列一下表,將后續的博客內容都安排一下,筆者會主要圍繞着這個大綱來寫,至於啥時候能更完,這個事就隨緣了。不過開弓沒有回頭箭,筆者就努力努力吧。
筆者能力有限,有寫錯的或者不足的地方,也煩請各位同行指正、交流。
圖1. DSO全家桶博客標題列表
DSO流程概述
好的,那么我們就開始今天這一講的內容了,先對DSO[1]的整體流程做一個概述。
圖2. DSO重建效果(參考DSO[1])
DSO全稱Direct Sparse Odometry,是慕尼黑工業大學計算機視覺實驗室[2]的雅各布博士在2016年發表的工作。在DSO之前,雅各布博士的另一個直接法巨作是LSD-SLAM[3]及其雙目版本LSD-SLAM2[4]。非常幸運的是,高翔博士在知乎上的文章DSO詳解[5]對DSO做了非常詳細的分析,因此我們可以非常系統的了解DSO系統的整體框架。
為了更加流暢地對整個系統流程進行介紹,筆者參考了塗金戈的博客DSO代碼框架。
一. 前端
前端的主要任務是對傳感器的輸入進行預處理,隨后進行數據關聯,並構建目標函數,通過優化目標函數估計初始的相機位姿變換。
1. 初始化
初始化階段需要兩幀圖像:
第一幀是作為基准幀,即DSO視第一幀所在的相機坐標系為世界坐標系。對圖像構建圖像金字塔,逐層對圖像提取梯度較大的點,並在層間設置關聯關系,同時為每個點初始化一個深度值,通常為1。
第二幀基於第一幀的點,構建光度誤差函數,通過Gauss-Newton法優化得到初始相對位姿。隨后將第一幀設置為關鍵幀,將第一幀中提取的梯度點激活,將其加入滑動窗口的優化中。在DSO中,點分為兩種類型,一種是激活點、一種是未成熟點。通常在圖像中剛剛提取的或者深度未收斂的點稱為未成熟點,具有非常大的深度范圍。通過深度濾波器在幀間不斷地濾波,使得點的深度不斷收斂,最終得到的點會被激活,加入滑動窗口中,這種點被稱為激活點。
DSO中的點在剛剛提取時,都是設置為深度范圍非常大的未成熟點。而在前端跟蹤階段,新幀都是不會先提取點的,只有在確定為關鍵幀時,經過窗口優化后,才會對當前幀提取點,並將滑動窗口所有激活點投影到該幀中構建深度圖,作為后續幀的參考幀。而第二幀就是這種情況,在初始化后,進入滑動窗口優化,在這個階段會判斷初始化是否成功,若殘差太大,則判定初始化失敗,需要重新設置第一幀,重復上述過程。
2. 跟蹤
從第三幀開始,進入正式的跟蹤流程。需要明確的一點是,直接法不同於特征點法,特征點法可以通過特征提取以及特征匹配進行幀間數據關聯,並采用多視圖幾何的方式構建幀間約束關系,比如采用RANSAC PNP或者對極幾何等方式估算初始位姿變換。而直接法沒有這種數據關聯方式,它必須通過幀間運動將參考幀中的點反投影到當前幀中構建光度誤差函數,從而優化幀間相對位姿。那么問題來了,又要用相對位姿來做反投影、又要反過來用這個投影的結果構建的誤差函數優化這個相對位姿,那么這個初始的位姿怎么來呢?直接法中采用的方式是運動模型,通過考慮1倍的、2倍的、0.5倍的、0倍的速度假設,構建多個運動模型,而基數是基於前幾幀間的相對位姿變換。
在得到了運動模型之后,便是逐個對運動模型進行驗證。即采用運動模型,將參考幀中的點反投影到當前幀中構建光度誤差函數,利用Gauss-Newton法優化目標函數,若結果收斂,則跳出模型驗證,直接給出相對位姿初值。否則,重復上述過程。
二. 后端
后端的內容主要包括深度濾波、未成熟點激活、窗口優化。
1. 深度濾波
如前所述,所有未成熟點的深度范圍值都是非常大,在DSO中初始化為[0, +∞]。通過在幀間進行極線搜索,找到匹配的點后,采用Gauss-Newton進一步優化,值得注意的是,每次深度濾波器濾波后得到的結果仍然是一個深度范圍,而不是單一一個深度值。深度濾波在關鍵幀和非關鍵幀中都會用到。后續的博文中我們會詳細介紹。
2. 未成熟點激活
通過多次深度濾波,有些關鍵幀的未成熟點的深度范圍已經收斂,通過多種條件判定后,將未成熟點激活,加入滑動窗口中進行聯合優化。
3. 窗口優化
通過將滑動窗口中的所有關鍵幀位姿和激活點全部聯合起來優化一個總的光度誤差函數,相比於兩幀之間的約束,滑動窗口中提供的約束條件更多,可以優化前端估計的相對位姿初值。后續我們會詳細介紹。
三. 邊緣化
在滑動窗口的優化中,隨着新的關鍵幀和點的加入,滑動窗口的大小會不斷增大,最終失去它靈活高效的功能。為了保持固定大小的窗口(DSO默認值是7個關鍵幀和2000個激活點),DSO采用邊緣化策略將舊幀和舊點剔除。如圖3左圖所示,優化問題中的海塞矩陣具有良好的稀疏性,這種稀疏性可以使得SLAM問題的求解更加高效。但是,有些錯誤的操作通常會導致海塞矩陣的稀疏結構被破壞。參考所長(賀一家)的博文:SLAM中的marginalization 和 Schur complement,由於同一個點,可以被不同的關鍵幀觀測到,會產生約束關系。若我們貿然地將某個狀態給邊緣化了,會得到圖3右圖所示的結果,即稀疏性被完全破壞了。而在DSO中,對於被多個關鍵幀觀測到的點,若已經到了需要邊緣化的階段,通常會選擇直接舍棄。並且,DSO采用先邊緣化點,再邊緣化關鍵幀的目的也是為了保證海塞矩陣的稀疏性。
圖3. 海塞矩陣的稀疏性(參考DSO[1])
四. 參考文獻
[1] Engel J, Koltun V, Cremers D. Direct sparse odometry[J]. IEEE transactions on pattern analysis and machine intelligence, 2017, 40(3): 611-625.
[2] 慕尼黑工業大學計算機視覺實驗室
[3] Engel J, Schöps T, Cremers D. LSD-SLAM: Large-scale direct monocular SLAM[C]//European conference on computer vision. Springer, Cham, 2014: 834-849.
[4] Engel J, Stückler J, Cremers D. Large-scale direct SLAM with stereo cameras[C]//2015 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS). IEEE, 2015: 1935-1942.
[5] DSO詳解
[6] DSO代碼框架
[7] Mur-Artal R, Tardós J D. Orb-slam2: An open-source slam system for monocular, stereo, and rgb-d cameras[J]. IEEE Transactions on Robotics, 2017, 33(5): 1255-1262.
[8] 深度濾波器
[9] SLAM中的marginalization 和 Schur complement
最后打個廣告,歡迎關注泡泡機器人SLAM微信公眾號,更歡迎加入泡泡大家庭。