orb_slam代碼解析(3)LocalMapping線程


距離寫上一片文章已經也過去一段時間了,對之前看過的程序竟是如此陌生,還好在此做注,現在開始看新的線程:LocalMapping

系統有一個map,這個線程就是用來管理這個地圖的,這個地圖在跟蹤線程中被初始化,在ORBSlam2的Tracking線程中,進行相機狀態初始化的時候,當使用對極約束時,求解了第一幀和第二幀之間的單應矩陣和基本矩陣,並通過三角測量得到兩幀匹配點的三維位置之后,使用了全局BA算法進行了一次細致的位姿優化。再是在locaomapping線程中,不斷得向地圖里插入關鍵幀,然后利用插入的關鍵幀及其相連關鍵幀及地圖點進行局部BA優化。

LocalMapping作用是將Tracking中送來的關鍵幀放在mlNewKeyFrame列表中;處理新關鍵幀,地圖點檢查剔除,生成新地圖點,Local BA,關鍵幀剔除。主要工作在於維護局部地圖,也就是SLAM中的Mapping。

LocalMapping線程主要的工作就是通過不斷的加入新KeyFrame和新地圖點,剔除冗余KeyFrame和冗余地圖點,來維護一個穩定的KeyFrame集合,從而可以進行后面的LoopClosing操作。

所以這個線程只是維護地圖,沒有進行全局優化。

我們知道。線程聲明之后就從Run函數開始出發

Function1:LocalMapping::Run()

只要系統沒有停止,那么就一直開始執行以下的任務:

  Function1.1:SetAcceptKeyFrames(false)

  告訴Tracking,LocalMapping正處於繁忙狀態, LocalMapping線程處理的關鍵幀都是Tracking線程發過的,在LocalMapping線程還沒有處理完關鍵幀之前Tracking線程最好不要發送太快。

判斷等待處理的關鍵幀列表不為空。

  Function1.2: ProcessNewKeyFrame()

  取出等待關鍵幀,該幀就是處理的當前幀。 計算該關鍵幀特征點的Bow映射關系。跟蹤局部地圖過程中新匹配上的MapPoints和當前關鍵幀綁定(在TrackLocalMap函數中將局部地圖中的MapPoints與當前幀進行了匹配, 但沒有對這些匹配上的MapPoints與當前幀進行關聯),即如果是非當前幀生成的MapPoints,那么就為當前幀在tracking過程跟蹤到的MapPoints更新屬性,包括為該MapPoint添加觀測,說明能夠為當前幀觀測到,獲得該點的平均觀測方向和觀測距離范圍, 加入關鍵幀后,更新3d點的最佳描述子,最后是更新關鍵幀間的連接關系,Covisibility圖和Essential圖(tree),將該關鍵幀插入到地圖中

由於單目不直接生成一些新的地圖點,所以就用不到剔除MapPoints。

  Function1.3: CreateNewMapPoints

  相機運動過程中和共視程度比較高的關鍵幀通過三角化恢復出一些MapPoints。

如果在等待處理的關鍵幀列表為空。

  Function1.4: SearchInNeighbors

  檢查並融合當前關鍵幀與相鄰幀(兩級相鄰)重復的MapPoints,在單目中,一級相鄰幀為其連接關系的前20幀,二級相鄰幀為各個一級相鄰幀相鄰程度最高的5幀。將當前幀的MapPoints分別與一級二級相鄰幀(的MapPoints)進  行融合,將一級二級相鄰幀的MapPoints分別與當前幀(的MapPoints)進行融合,融合就是指一個3D的地圖點轉換為關鍵幀坐標系下,然后反變換為像素坐標,在一定的半徑范圍內找出描述子距離跟3D的地圖點最近      的特征點id,並找到該特征點對應的MapPoint,然后比較兩個MapPoint的可被觀測的次數多,勝者替代對方,完成融合。最后更新當前幀MapPoints的描述子,深度,觀測主方向等屬性,更新當前幀的MapPoints后更新與      其它幀的連接關系。

  Function1.5: SLocalBundleAdjustment

  這是進行和當前幀相連的關鍵幀及MapPoint做局部BA優化,而不是整個地圖庫去做全局的優化。在這部分我一直誤解是所謂的后端全局地圖的優化,但現在的想法是他只不過是為了幫助更加精確得去維護一個地圖庫,即讓庫里的關鍵幀的位姿是優化后的。

  Function1.6: KeyFrameCulling   

  對當前幀與其共視的關鍵幀進行剔除,90%以上的MapPoint能被其他共視關鍵幀所觀測到,那么該幀就會被剔除。

  Function1.7: mpLoopCloser->InsertKeyFrame(mpCurrentKeyFrame)

  現在處理的當前幀是跟蹤線程送進來的,經過LocalMapping線程送到進行后面的mlploopKeyFrameQueue進行下一個線程的操作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM