這篇文章即是Felix Endres等人12年完成的RGB-D SLAM V2,是最早的為kinect風格傳感器設計的SLAM系統之一
沒看到有相關的論文解析
在Github上可找到開源代碼,工程配置與運行參考http://www.cnblogs.com/voyagee/p/6898278.html
系統流程
系統分為前后端。前端就是視覺里程記。從每一幀的RGB圖像提取特征,計算描述符,RANSAC+ICP計算兩幀之間的motion estimation,
並提出了一個EMM(Environment Measurement Model)模型來判斷estimate motion是否可接受。后端回環檢測,基於g2o優化庫的位姿圖(pose graph)優化,
得到優化后的軌跡,用於建立地 圖。建圖采用八叉樹地圖octomap的方式。
特征提取
在源碼中可選擇 SIFT \ SURF \ORB 特征,其中SIFT要在GPU上運行,ORB和SURF都在CPU上用Opencv實現
不同特征比較:
( 其中,ATE為Absolute Trajectory Error,軌跡的誤差,就是系統估計的軌跡和真實軌跡(GroundTruth)之間的歐式距離,RMSE就是均方根)
可以看出,有GPU時SIFT綜合表現最好。 綜合實時性、硬件成本和准確率來看,ORB較好。
運動估計
三對特征快速計算RANSAC的初始值,在每一輪迭代中,最小二乘correspondences之間的馬氏距離 。
馬氏距離與歐式距離的差別:http://www.cnblogs.com/likai198981/p/3167928.html,簡單說就是計算距離時考慮到了各項異性,多乘了一個協方差矩陣
EMM:Environment Measurement Model
一個傳統的判斷motion estimate是否可接受的方法就是看inlier的比例,小於設定閾值就reject motion estimate。
然而,motion blur(運動模糊),缺少紋理信息的環境都很容易出現inlier較少的情況。
並且有一些點,在一幀中可以看到,另一幀可能就被其他點擋住了。 作者提出使用這個EMM來更魯棒的判斷是否reject estimate
先看一個假設:實施transformation之后,空間上對應的深度測量值應該來自於同一個表面位置之下:
after applying transformation estimate,spatially corresponding depth measurement stem from the same underlying surface location.
論文中作者證明了觀測yi和yj(不同與下圖的yi,yj)之間的差滿足高斯分布,方差為表示噪音的協方差矩陣(計算方法由論文 Accuracy and Resolution of Kinect Depth Data給出)
這樣,就可以用概率學里的p值檢驗來判斷是否reject estimate,然而,發現p值檢驗 有點神經衰弱 ,對於微小的誤差太過敏感,
因此使用另一種方法
將相機A觀測到的點投影到相機B,在observed points中找出inlier,outlier,occluded:
上圖中yi和yj應該是同一個點,算作inlier。yk不再A的視場內,所以被忽視,不看作“observed points”。
投影之后的yq在相機B 的市場中被yk擋住,看不到,因此算作occluded。
至於yp,落在了yq和相機A光心的連線上,算作outlier(注意,yp與yk不同,yp在相機A的視場內,但是相機A在這里觀測到的是yq的深度)
因此,在上圖中,inlier有倆,outlier一個,occluded一個
而在代碼中(misc.cpp 913行之后有兩個函數,其中一個是用於p值檢驗方法的),作者是這么計算inlier,outlier,occluded,並判斷是否reject的
observedPoints=inliers + outliers + occluded
I=inlier數量,O=outlier數量,C=occluded數量,如果I/(I+O+C)<25%,直接reject
否則,對I/(I+O)設一個閾值,小於閾值就reject
回環檢測
現在的回環檢測大多數是基於Bag-of-Words,深度學習興起后也有用deep learning 的,或者用語義信息
此文回環是基於 最小生成樹 ,隨機森林的隨機回環
使用描述符之間的距離(直接相減),生成一棵深度圖像(limited depth)的最小生成樹,去掉n個時間上最近的(避免重復)
再隨機從樹上選k幀(偏向於更早的幀)來找閉環
圖優化
只優化位姿圖,不優化三維點。
使用g2o圖優化庫。g2o的使用http://www.cnblogs.com/gaoxiang12/p/3776107.html
沒有被EMM拒絕的motion,將兩幀相機位姿作為優化頂點,motion作為約束,加入優化邊
檢測到的回環,也加入優化頂點和邊
g2o優化邊的誤差函數:
這里的xi,xj為優化變量(頂點位姿的estimate),Zij是約束,也就是xi和xj之間的變換。e()是how well xi and xj satisfy the constraint ,
中間的Ω是約束(優化邊)的信息矩陣(協方差矩陣的逆), 表示對邊的精度的估計。在代碼中,是這么計算的:
odom_edge.informationMatrix = Eigen::Matrix<double,6,6>::Identity() / time_delta_sec;//e-9;
單位矩陣除以兩幀之間的時間間隔
看到這里,依然沒有明白這個誤差究竟咋算的~
查看g2o::SE3edge.cpp, 這個e其實是這么算的:
_inverseMeasurement * from->estimate().inverse() * to->estimate()
解釋一下這個誤差函數:
我們認為 幀2( from)的位姿態 Tj 是幀1(to)的位姿 Ti 經過 Tij 得到的 ,也就是
Ti * Tij = Tj
也就是
Tij = Ti -1 * Tj
即一個位姿的逆乘另一個位姿可以表示兩個位姿之間的變化,那么,我們想表達邊的measurement與Tij之間的差距,也可以這么玩兒
delta : Δ = measurement-1 * Ti-1 * Tj ,
這就得到g2o代碼里的式子了, 后面的toVectorMQT是啥我也不清楚。。應該就是矩陣轉化為向量
注意,Ti其實完整寫法是Twi, w代表世界坐標系
這里看不懂的可以參考高翔大大《視覺SLAM十四講》11.1.2
這個樣子的回環檢測,難免會出現錯誤的回環,這種回環約束加入到圖優化中去,勢必會把地圖拉的扭曲
所以,在圖優化第一次收斂之后,作者就把錯誤回環對應的優化邊 從圖中刪除。
怎么判斷回環是錯誤的呢? ----- 給上面說的誤差函數設一個閾值(又又又又是閾值。。) ,誤差大於這個閾值的就是錯誤的
octoMap:
http://www.cnblogs.com/gaoxiang12/p/5041142.html
把一個立方體平均分成八個小立方體,小立方體又可以再分,子子孫孫無窮盡也
每個小立方體對應八叉樹的一個節點,因此成為八叉樹地圖
每個小立方體存儲 被占據的概率的logist回歸,被觀測到占據次數越多,概率越大,而如果沒有一次觀測到被占據,則不用展開該節點
OctoMap的優點: 利於導航 ; 易於更新 ;存儲方式比較省空間
歡迎交流,歡迎補充,歡迎糾錯