ORB-SLAM(九)LocalMapping

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

1. 處理新關鍵幀ProcessNewKeyFrame()app

作了三件事:優化

  a. 計算當前關鍵幀Bow,便於後面三角化恢復新地圖點;spa

  b. 將TrackLocalMap中跟蹤局部地圖匹配上的地圖點綁定到當前關鍵幀(在Tracking線程中只是經過匹配進行局部地圖跟蹤,優化當前關鍵幀姿態),也就是在graph中加入當前關鍵幀做爲node,並更新edge。而CreateNewMapPoint()中則經過當前關鍵幀,在局部地圖中添加與新的地圖點線程

  c. 更新加入當前關鍵幀以後關鍵幀之間的鏈接關係,包括更新Covisibility圖和Essential圖(最小生成樹spanning tree,共視關係好的邊subset of edges from covisibility graph with high covisibility (θ=100), 閉環邊)。code

 

2. 對於ProcessNewKeyFrame和CreateNewMapPoints中最近添加的MapPoints進行檢查剔除:MapPointCulling()blog

候選待檢查地圖點存放在mlpRecentAddedMapPoints,知足兩個條件之一就被剔除:it

  1. 跟蹤(匹配上)到該地圖點的普通幀幀數(IncreaseFound)<應該觀測到該地圖點的普通幀數量(25%*IncreaseVisible):該地圖點雖在視野範圍內,但不多被普通幀檢測到。io

  2. 從添加該地圖點的關鍵幀算起的初始三個關鍵幀,第一幀不算,後面兩幀看到該地圖點的幀數,對於單目<=2,對於雙目和RGBD<=3;所以在地圖點剛創建的階段,要求比較嚴格,很容易被剔除;並且單目的要求更嚴格,須要三幀都看到。若從添加該地圖點的關鍵幀算起,一共有了大於三個關鍵幀,還存在列表中,則說明該地圖點是高質量的,從檢查列表中去掉。class

一旦通過了這樣比較嚴格的篩選,地圖點只有在觀測到它的關鍵幀<3時纔會被剔除,這主要發生在關鍵幀被剔除(90%以上匹配點能夠被其餘幀觀察到);或者局部捆集優化時,將地圖點歸爲外點從觀測中剔除了的狀況。所以地圖點中的外點是比較少的,因此整套ORB-SLAM中除了重定位和閉環不多去使用RANSAC。

ORB-SLAM中關鍵幀和地圖點的加入和刪除秉承的是送入嚴出的標準,所以在提升了定位建圖準確性的前提下又很好地限制了計算量,能夠用於large scale的場景。

3. 根據當前關鍵幀恢復出一些新的地圖點,不包括和當前關鍵幀匹配的局部地圖點(已經在ProcessNewKeyFrame中處理),注意理解與前面兩步的前後關係,先處理新關鍵幀與局部地圖點之間的關係,而後對局部地圖點進行檢查,最後再經過新關鍵幀恢復心的局部地圖點:CreateNewMapPoints()

--- 對Tracking中送來的每一幀關鍵幀執行上述過程,直到mlNewKeyFrame爲空。

3'. SearchInNeighbors()

更新並融合當前關鍵幀以及兩級相連(共視關鍵幀及其共視關鍵幀)的關鍵幀的地圖點。

4. LocalBundleAdjustment()

5. KeyFrameCulling

局部關鍵幀剔除

void LocalMapping::KeyFrameCulling();

候選的pKF是LocalMapping中當前處理的關鍵幀的共視關鍵幀,不包括第一幀關鍵幀與當前關鍵幀。遍歷pKF中的地圖點的觀測:

const map<KeyFrame*, size_t> observations = pMP->GetObservations();

如有很多於3幀被觀測到(須要知足觀測尺度不大於或近似於在pKF中的尺度),則記錄下。若pKF中90%以上的地圖點可以被其餘關鍵幀觀測到,也就是說,該關鍵幀的存在提供的地圖點觀測信息有限,則將其刪除!

相關文章
相關標籤/搜索