ORB_SLAM2代码阅读(3)——LocalMapping线程
ORB_SLAM2代碼閱讀(3)——LocalMapping線程
- 1.說明
 - 2.簡介
 - 3.處理關鍵幀
 - 4. 地圖點剔除
 - 5. 創建新的地圖點
 - 6.相鄰搜索
 - 6.剔除冗余關鍵幀
 
1.說明
本文介紹ORB_SLAM2中的LocalMapping線程。相對而言,LoaclMapping線程要比tracking線程簡練整潔一些。整體思路比較清晰,沒有那么多情況需要討論。該部分內容中有很多細節部分還沒有弄清楚,暫時先將整體思路捋順,更多細節內容以后再補充。
2.簡介
在學習ORB_SLAM2系統的過程中,我們需要緊緊抓住兩樣東西:幀(關鍵幀)和地圖點,只要把握好這兩樣東西,就很容易理清整個系統的脈絡。而在LoaclMapping線程中,大部分都是對地圖點進行處理,只有少部分內容是處理關鍵幀。
先來看一下LoaclMapping線程的主要思路:
- 檢測在隊列中是否存在新的關鍵幀,如果存在進行局部地圖構建。
 - 處理關鍵幀。在該過程中,計算關鍵幀特征點的BoW映射,將關鍵幀插入地圖。
 - 剔除冗余地圖點。該部分內容遍歷當前關鍵幀的所有地圖點,對于不滿足條件的地圖點將其剔除。
 - 添加新的地圖點。相機運動過程中與相鄰關鍵幀可以通過三角化恢復出一些MapPoints。
 - 如果當前關鍵幀是關鍵幀隊列中的最后一幀,則進行局部BA,然后剔除冗余關鍵幀。
 - 將關鍵幀加入到回環檢測線程。
 
具體流程如下圖:
 
 接下來,從 處理關鍵幀、地圖點剔除、創建新的地圖點、局部搜索和剔除多余關鍵幀這5部分分別展開介紹。
3.處理關鍵幀
處理關鍵幀這部分內容相當于局部建圖線程中的第一步,該步驟主要的操作是:
- 從緩沖隊列中取出一幀關鍵幀 。
 - 計算該關鍵幀特征點的Bow向量。
 - tracking線程中局部地圖跟蹤過程中新匹配上的MapPoints和當前關鍵幀綁定。
 - 更新關鍵幀間的連接關系。
 - 將該關鍵幀插入到地圖中。
 
在處理關鍵幀過程中,有一個問題需要搞清楚(我自己開始理解的不清楚,導致這個問題想了很久)。這個問題是:在獲取當前關鍵幀的地圖點之后,為什么還要判斷地圖點是否在當前關鍵幀中?
要弄清這個問題還要從tracking線程中的局部地圖跟蹤過程說起。局部地圖跟蹤過程中首先將能夠觀測到當前幀地圖點的關鍵幀及這些關鍵幀的共視關鍵幀和父子關鍵幀作為局部地圖跟蹤過程中的關鍵幀,然后將這些關鍵幀的所有地圖點作為局部地圖跟蹤過程中的地圖點。有了關鍵幀和地圖點之后,需要將這些地圖點與當前幀的地圖點進行投影匹配,然后進行當前幀的位姿優化。這是局部地圖跟蹤的大致過程。由于局部地圖(此處的局部地圖是tracking線程中的局部地圖)中的地圖點與當前幀的地圖點進行了投影匹配。所有可以認為當前幀的匹配地圖點分為兩部分:當前幀自己生成的地圖點,非當前幀(局部地圖中其他關鍵幀)生成的地圖點。而非當前幀生成的地圖點未與當前幀進行關聯,所以在局部建圖線程的關鍵幀處理部分需要為這些非當前幀(局部地圖中其他關鍵幀)生成的地圖點更新屬性。
4. 地圖點剔除
地圖點剔除過程是指剔除局部地圖中的某些不合乎要求的地圖點。具體來說,要剔除的不合乎要求的地圖點是 處理關鍵幀過程中的 當前幀自己生成的地圖點中的一部分。
剔除原則是:
- 已經是壞點的MapPoints直接從檢查鏈表中刪除
 - 跟蹤到該地圖點的Frame數與預計可觀測到該地圖點的Frame數的比例小于25%,則剔除
 - 從該點建立開始,到現在已經過了不小于2個關鍵幀但是觀測到該點的關鍵幀數卻不超過cnThObs幀,則剔除
 - 從建立該點開始,已經過了3個關鍵幀而沒有被剔除,則僅從隊列中刪除,放棄繼續對該MapPoint的檢測而不將其設為bad點。
 
那么問題又來了。既然該部分處理的是 當前幀自己生成的地圖點,為什么會考慮這些地圖點的跟蹤情況呢?
原因是:當前幀自己生成的地圖點雖然沒有在tracking線程的局部地圖跟蹤過程中進行匹配和跟蹤,但是這些地圖點在tracking線程中的位姿估計部分進行了匹配跟蹤。換句話說:當前幀自己生成的地圖點和非當前幀(局部地圖中其他關鍵幀)生成的地圖點在tracking線程中都進行了匹配跟蹤,只是匹配跟蹤的方式和時間不同。
5. 創建新的地圖點
目前為止,我們知道當前幀地圖點分為兩部分:當前幀自己生成的地圖點 和 非當前幀(局部地圖中其他關鍵幀)生成的地圖點。而創建新的地圖點則是根據當前關鍵幀的共視關鍵幀和當前幀之間的姿態關系,利用三角化的方式恢復出一些地圖點。所以經過創建新的地圖點之后,當前幀的地圖點分為三部分:當前幀自己生成的地圖點 、 非當前幀(局部地圖中其他關鍵幀)生成的地圖點和當前幀與共視幀通過三角化計算出的地圖點。
該部分內容的大致思路為:
- 在當前關鍵幀的共視關鍵幀中找到共視程度最高的nn幀相鄰幀vpNeighKFs
 - 遍歷相鄰關鍵幀vpNeighKFs
 - 判斷相機運動的基線是不是足夠長
 - 根據兩個關鍵幀的位姿計算它們之間的基本矩陣。
 - 通過極線約束限制匹配時的搜索范圍,進行特征點匹配
 - 對每對匹配通過三角化生成3D點。
 
具體流程:
 
 這部分的代碼,注釋的較為詳細,以后再上傳。
6.相鄰搜索
如果當前關鍵幀是待處理關鍵幀隊列中的最后一幀。則經過創建新的地圖點之后要進行相鄰搜索。相鄰搜索的主要目的是檢查并融合當前關鍵幀與相鄰幀(兩級相鄰)重復的MapPoints。在經過上面幾步的處理之后,地圖點必然存在冗余,所以需要在此處進行冗余去除。
相鄰搜索的主要思路為:
- 獲得當前關鍵幀在covisibility圖中權重排名前nn的鄰接關鍵幀,找到當前幀一級相鄰與二級相鄰關鍵幀并將其存入
vpTargetKFs中。
這里提到的一級相鄰關鍵幀指:與當前關鍵幀共視程度最高的nn個相鄰關鍵幀,二級相鄰關鍵幀指:與一級相鄰關鍵幀共視程度最高的5個相鄰關鍵幀。 - 將當前幀的MapPoints分別與一級二級相鄰幀(的MapPoints)進行融合。
投影當前幀的MapPoints到相鄰關鍵幀pKFi中,并判斷是否有重復的MapPoints。如果MapPoint能匹配關鍵幀的特征點,并且該點有對應的MapPoint,那么將兩個MapPoint合并(選擇觀測數多的);如果MapPoint能匹配關鍵幀的特征點,并且該點沒有對應的MapPoint,那么為該點添加MapPoint。 - 將一級二級相鄰幀的所有有效的MapPoints分別與當前幀(的MapPoints)進行融合。
 - 更新當前幀MapPoints的描述子,深度,觀測主方向等屬性。
 - 更新covisibility圖。
 
具體步驟如圖:
 
6.剔除冗余關鍵幀
如果已經處理完隊列中的最后的一個關鍵幀,并且閉環檢測沒有請求停止LocalMapping。則進行局部BA,然后剔除冗余關鍵幀。在此處先不說局部BA(后面單獨說),只介紹一下剔除冗余關鍵幀操作。
剔除冗余關鍵幀的操作比較簡單。其主要思想是:過去當前關鍵幀的所有共視關鍵幀。如果這些共視關鍵幀中的某一幀的地圖點有90%能被至少3個關鍵幀觀測到,則認為該幀是冗余的,需要將其設置為bad。
做完這些操作后,便可以將當前幀加入到閉環檢測隊列中進行閉環檢測。
局部建圖的過程就介紹到這里,相對來說內容比較少。
總結
以上是生活随笔為你收集整理的ORB_SLAM2代码阅读(3)——LocalMapping线程的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 修复处女多少钱啊?
 - 下一篇: 女性可以避免习惯性流产吗