ORB-SLAM的RGBD為什麼要分Mono和Stereo?
在優化的時候判斷pFrame-&>mvuRight[i]的正負
1)如果&<0
是Monocular observation
obs &
2)如果&>0
const float kp_ur = pFrame-&>mvuRight[i];
obs &
觀測還要加上一個虛擬的右側相機的點?
還有,如果&>0,觀測一個mappoint,每觀測到一次,直接+2
因為RGB-D不存在左右兩個相機,所以我不清楚為什麼有這種操作?希望大神們幫我解答一下~~~
1. 觀測還要加上一個虛擬的右側相機的點?
原因是為了與 Mono 和 Stereo 模式保持一致。RGBD 雖然是具有深度信息,但是深度圖和 RGB 圖不是完全匹配,四周還是有無深度的影像區域,中間也存在空洞。無深度信息的特徵點是一條射線,與 Mono 一同處理;有深度信息的特徵點與 Stereo 一同處理。
Mono 的 error 是重投影誤差 2 維的,Stereo 的 error 是 3 維的,前 2 維與 Mono 相同,第 3 維是右片上 u 的重投影誤差(相當於深度的誤差)。以下是細節:
生成 RGBD Frame 的過程中調用了函數 Frame::ComputeStereoFromRGBD。如果有深度就設置mvuRight
和mvDepth
的對應值,下面這一行就是設置了虛擬右影像上的 u 坐標值:
mvuRight[i] = kpU.pt.x-mbf/d;
對應公式:
其中 是 方向上的焦距(即 ), 是左影像上的深度, 是左右影像基線的長度。
生成 Frame 之後就是調用 Tracking::Track() 函數。初始化 Tracking::StereoInitialization() 只會使用那些有深度的 Stereo 點。初始化完成之後,不論是 Tracking::TrackWithMotionModel() 與上一普通幀匹配,還是 Tracking::TrackReferenceKeyFrame() 與上一關鍵幀匹配,亦或是 Tracking::Relocalization() 與窗口中所有的關鍵幀匹配。
得到了關鍵點對應的有深度的 MapPoint,隨後調用函數 Optimizer::PoseOptimization() 進行一個類似 PnP 的優化。對於 Mono 情況使用的 Edge 是 g2o::EdgeSE3ProjectXYZOnlyPose,對於 Stereo 情況使用的 Edge 是 g2o::EdgeStereoSE3ProjectXYZOnlyPose。分別看這兩個 Edge 的 computeError() 函數,EdgeSE3ProjectXYZOnlyPose::_error
是Vector2d
,EdgeStereoSE3ProjectXYZOnlyPose::_error
是Vector3d
。函數EdgeSE3ProjectXYZ::cam_project()
和EdgeStereoSE3ProjectXYZ::cam_project()
的代碼如下:
Vector2d EdgeSE3ProjectXYZ::cam_project(const Vector3d trans_xyz) const{
Vector2d proj = project2d(trans_xyz);
Vector2d res;
res[0] = proj[0]*fx + cx;
res[1] = proj[1]*fy + cy;
return res;
}
Vector3d EdgeStereoSE3ProjectXYZ::cam_project(const Vector3d trans_xyz, const float bf) const{
const float invz = 1.0f/trans_xyz[2];
Vector3d res;
res[0] = trans_xyz[0]*invz*fx + cx;
res[1] = trans_xyz[1]*invz*fy + cy;
res[2] = res[0] - bf*invz;
return res;
}
res[0], res[1]
是 ,res[2]
是 。
2. 還有,如果&>0,觀測一個mappoint,每觀測到一次,直接+2
ORB_SLAM2 細節不熟,沒有搜到+2
。請明示。這個點能夠在左右兩張影像上觀測到?
我估計你這是有誤解,我沒太看過orb的rgbd怎麼搞的,但是我估計它那裡存儲的是深度圖,你看下右圖賦值給的是什麼
推薦閱讀: