引言:經過前面的推送咱們已經對SLAM有了個大致的認識。(初識視覺SLAM)下面來看經典的視覺SLAM框架,瞭解一下視覺SLAM究竟由哪幾個模塊組成。
本文選自《視覺SLAM十四講:從理論到實踐》。前端
整個視覺SLAM流程包括如下步驟。後端
傳感器信息讀取。在視覺SLAM中主要爲相機圖像信息的讀取和預處理。若是是在機器人中,還可能有碼盤、慣性傳感器等信息的讀取和同步。微信
視覺里程計(Visual Odometry,VO)。視覺里程計的任務是估算相鄰圖像間相機的運動,以及局部地圖的樣子。VO又稱爲前端(Front End)。app
後端優化(Optimization)。後端接受不一樣時刻視覺里程計測量的相機位姿,以及迴環檢測的信息,對它們進行優化,獲得全局一致的軌跡和地圖。因爲接在VO以後,又稱爲後端(Back End)。框架
迴環檢測(Loop Closing)。迴環檢測判斷機器人是否到達過先前的位置。若是檢測到迴環,它會把信息提供給後端進行處理。dom
建圖(Mapping)。它根據估計的軌跡,創建與任務要求對應的地圖。機器學習
經典的視覺SLAM框架是過去十幾年的研究成果。這個框架自己及其所包含的算法已經基本定型,而且已經在許多視覺程序庫和機器人程序庫中提供。依靠這些算法,咱們可以構建一個視覺SLAM系統,使之在正常的工做環境裏實時定位與建圖。所以,咱們說,若是把工做環境限定在靜態、剛體,光照變化不明顯、沒有人爲干擾的場景,那麼,這個SLAM系統是至關成熟的了。ide
讀者可能尚未理解上面幾個模塊的概念,下面就來詳細介紹各個模塊具體的任務。這裏您只需對各模塊有一個直觀的、定性的理解便可。oop
視覺里程計關心的是相鄰圖像之間的相機運動,最簡單的狀況固然是兩張圖像之間的運動關係。例如,當看到下圖時,咱們會天然地反應出右圖應該是左圖向左旋轉必定角度的結果(在視頻狀況下感受會更加天然)。咱們不妨思考一下:本身是怎麼知道「向左旋轉」這件事情的呢?人類早已習慣於用眼睛探索世界,估計本身的位置,但又每每難以用理性的語言描述咱們的直覺。看到時,咱們會天然地認爲,這個場景中離咱們近的是吧檯,遠處是牆壁和黑板。當相機向左轉動時,吧檯離咱們近的部分出如今視野中,而右側遠處的櫃子則移出了視野。經過這些信息,咱們判斷相機應該是向左旋轉了。
可是,若是進一步問:可否肯定旋轉了多少度,平移了多少釐米?咱們就很難給出一個確切的答案了。由於咱們的直覺對這些具體的數字並不敏感。可是,在計算機中,又必須精確地測量這段運動信息。因此咱們要問:計算機是如何經過圖像肯定相機的運動的呢?
前面也提過,在計算機視覺領域,人類在直覺上看來十分天然的事情,在計算機視覺中卻很是困難。圖像在計算機裏只是一個數值矩陣。這個矩陣裏表達着什麼東西,計算機毫無概念(這也正是如今機器學習要解決的問題)。而在視覺SLAM中,咱們只能看到一個個像素,知道它們是某些空間點在相機的成像平面上投影的結果。因此,爲了定量地估計相機運動,必須先了解相機與空間點的幾何關係。
要講清這個幾何關係以及VO的實現方法,須要鋪墊一些背景知識。在這裏咱們先讓讀者對VO有個直觀的概念。如今只需知道,VO可以經過相鄰幀間的圖像估計相機運動,並恢復場景的空間結構。稱它爲「里程計」是由於它和實際的里程計同樣,只計算相鄰時刻的運動,而和再往前的過去的信息沒有關聯。在這一點上,VO就像一種只有短期記憶的物種。
如今,假定咱們已有了一個視覺里程計,估計了兩張圖像間的相機運動。那麼,只要把相鄰時刻的運動「串」起來,就構成了機器人的運動軌跡,從而解決了定位問題。另外一方面,咱們根據每一個時刻的相機位置,計算出各像素對應的空間點的位置,就獲得了地圖。這麼說來,有了VO,是否是就解決了SLAM問題呢?
視覺里程計確實是SLAM的關鍵,咱們也會花大量的篇幅來介紹它。然而,僅經過視覺里程計來估計軌跡,將不可避免地出現累積漂移(Accumulating Drift)。這是因爲視覺里程計(在最簡單的狀況下)只估計兩個圖像間的運動形成的。咱們知道,每次估計都帶有必定的偏差,而因爲里程計的工做方式,先前時刻的偏差將會傳遞到下一時刻,致使通過一段時間以後,估計的軌跡將再也不準確。比方說,機器人先向左轉,再向右轉。因爲偏差,咱們把第一個估計成了。那咱們就會尷尬地發現,向右轉以後機器人的估計位置並無回到原點。更糟糕的是,即便以後的估計再準確,與真實值相比,都會帶上這的偏差。
這也就是所謂的漂移(Drift)。它將致使咱們沒法創建一致的地圖。你會發現本來直的走廊變成了斜的,而本來的直角變成了歪的——這實在是一件很難使人忍受的事情!爲了解決漂移問題,咱們還須要兩種技術:後端優化(更多時候稱爲後端(Back End)。因爲主要使用的是優化方法,故稱爲後端優化。)和迴環檢測。迴環檢測負責把「機器人回到原始位置」的事情檢測出來,然後端優化則根據該信息,校訂整個軌跡的形狀。
籠統地說,後端優化主要指處理SLAM過程當中噪聲的問題。雖然咱們很但願全部的數據都是準確的,然而現實中,再精確的傳感器也帶有必定的噪聲。便宜的傳感器測量偏差較大,昂貴的可能會小一些,有的傳感器還會受磁場、溫度的影響。因此,除了解決「如何從圖像估計出相機運動」以外,咱們還要關心這個估計帶有多大的噪聲,這些噪聲是如何從上一時刻傳遞到下一時刻的,而咱們又對當前的估計有多大的自信。後端優化要考慮的問題,就是如何從這些帶有噪聲的數據中估計整個系統的狀態,以及這個狀態估計的不肯定性有多大——這稱爲最大後驗機率估計(Maximum-a-Posteriori,MAP)。這裏的狀態既包括機器人自身的軌跡,也包含地圖。
相對地,視覺里程計部分有時被稱爲「前端」。在SLAM框架中,前端給後端提供待優化的數據,以及這些數據的初始值。然後端負責總體的優化過程,它每每面對的只有數據,沒必要關心這些數據到底來自什麼傳感器。在視覺SLAM中,前端和計算機視覺研究領域更爲相關,好比圖像的特徵提取與匹配等,後端則主要是濾波與非線性優化算法。
從歷史意義上來講,如今咱們稱爲後端優化的部分,很長一段時間直接被稱爲「SLAM研究」。早期的SLAM問題是一個狀態估計問題——正是後端優化要解決的東西。在最先提出SLAM的一系列論文中,當時的人們稱它爲「空間狀態不肯定性的估計」(Spatial Uncertainty)。雖然有一些晦澀,但也確實反映出了SLAM問題的本質:對運動主體自身和周圍環境空間不肯定性的估計。爲了解決SLAM問題,咱們須要狀態估計理論,把定位和建圖的不肯定性表達出來,而後採用濾波器或非線性優化,估計狀態的均值和不肯定性(方差)。狀態估計與非線性優化的具體內容將在第6講、第10講和第11講介紹。讓咱們暫時跳過它的原理說明,繼續往下介紹。
迴環檢測,又稱閉環檢測(Loop Closure Detection),主要解決位置估計隨時間漂移的問題。怎麼解決呢?假設實際狀況下機器人通過一段時間的運動後回到了原點,可是因爲漂移,它的位置估計值卻沒有回到原點。怎麼辦呢?咱們想,若是有某種手段,讓機器人知道「回到了原點」這件事,或者把「原點」識別出來,咱們再把位置估計值「拉」過去,就能夠消除漂移了。這就是所謂的迴環檢測。
迴環檢測與「定位」和「建圖」兩者都有密切的關係。事實上,咱們認爲,地圖存在的主要意義是讓機器人知曉本身到過的地方。爲了實現迴環檢測,咱們須要讓機器人具備識別到過的場景的能力。它的實現手段有不少。例如像前面說的那樣,咱們能夠在機器人下方設置一個標誌物(如一張二維碼圖片)。它只要看到了這個標誌,就知道本身回到了原點。可是,該標誌物實質上是一種環境中的傳感器,對應用環境作了限制(萬一不能貼二維碼怎麼辦?)。咱們更但願機器人能使用攜帶的傳感器——也就是圖像自己,來完成這一任務。例如,能夠判斷圖像間的類似性來完成迴環檢測。這一點和人是類似的。當咱們看到兩張類似的圖片時,容易辨認它們來自同一個地方。若是迴環檢測成功,能夠顯著地減少累積偏差。因此,視覺迴環檢測實質上是一種計算圖像數據類似性的算法。因爲圖像的信息很是豐富,使得正確檢測迴環的難度下降了很多。
在檢測到迴環以後,咱們會把「A與B是同一個點」這樣的信息告訴後端優化算法。而後,後端根據這些新的信息,把軌跡和地圖調整到符合迴環檢測結果的樣子。這樣,若是咱們有充分並且正確的迴環檢測,就能夠消除累積偏差,獲得全局一致的軌跡和地圖。
建圖(Mapping)是指構建地圖的過程。地圖是對環境的描述,但這個描述並非固定的,須要視SLAM的應用而定。
對於家用掃地機器人來講,這種主要在低矮平面裏運動的機器人,只須要一個二維的地圖,標記哪裏能夠經過,哪裏存在障礙物,就夠它在必定範圍內導航了。而對於一個相機,它有6自由度的運動,咱們至少須要一張三維的地圖。有些時候,咱們想要一個漂亮的重建結果,不只是一組空間點,還須要帶紋理的三角面片。另外一些時候,咱們又不關心地圖的樣子,只須要知道「A點到B點可經過,而B點到C點不行」這樣的事情。甚至,有時不須要地圖,或者地圖能夠由其餘人提供,例如,行駛的車輛每每能夠獲得已繪製好的當地地圖。
對於地圖,咱們有太多的想法和需求。所以,相比於前面提到的視覺里程計、迴環檢測和後端優化,建圖並無一個固定的形式和算法。一組空間點的集合也能夠稱爲地圖,一個漂亮的3D模型亦是地圖,一個標記着城市、村莊、鐵路、河道的圖片仍是地圖。地圖的形式隨SLAM的應用場合而定。大致上講,能夠分爲度量地圖與拓撲地圖兩種。
度量地圖強調精確地表示地圖中物體的位置關係,一般用稀疏(Sparse)與稠密(Dense)對其分類。稀疏地圖進行了必定程度的抽象,並不須要表達全部的物體。例如,咱們選擇一部分具備表明意義的東西,稱之爲路標(Landmark),那麼一張稀疏地圖就是由路標組成的地圖,而不是路標的部分就能夠忽略掉。相對地,稠密地圖着重於建模全部看到的東西。對於定位來講,稀疏路標地圖就足夠了。而用於導航時,則每每須要稠密的地圖(不然撞上兩個路標之間的牆怎麼辦?)。稠密地圖一般按照某種分辨率,由許多個小塊組成。對於二維度量地圖是許多個小格子(Grid),而對於三維度量地圖則是許多小方塊(Voxel)。通常地,一個小塊含有佔據、空閒、未知三種狀態,以表達該格內是否有物體。當查詢某個空間位置時,地圖可以給出該位置是否能夠經過的信息。這樣的地圖能夠用於各類導航算法,如A*、D*等,爲機器人研究者所重視。可是咱們也看到,這種地圖須要存儲每個格點的狀態,會耗費大量的存儲空間,並且多數狀況下地圖的許多細節部分是無用的。另外一方面,大規模度量地圖有時會出現一致性問題。很小的一點轉向偏差,可能會致使兩間屋子的牆出現重疊,使地圖失效。
相比於度量地圖的精確性,拓撲地圖則更強調地圖元素之間的關係。拓撲地圖是一個圖(Graph),由節點和邊組成,只考慮節點間的連通性,例如A、B點是連通的,而不考慮如何從A點到達B點。它放鬆了地圖對精確位置的須要,去掉了地圖的細節問題,是一種更爲緊湊的表達方式。然而,拓撲地圖不擅長表達具備複雜結構的地圖。如何對地圖進行分割造成結點與邊,又如何使用拓撲地圖進行導航與路徑規劃,還是有待研究的問題。
本文選自《視覺SLAM十四講:從理論到實踐》,點此連接可在博文視點官網查看此書。
想及時得到更多精彩文章,可在微信中搜索「博文視點」或者掃描下方二維碼並關注。