ORB-SLAM2學習5 Tracking.h
一、直接上圖,清楚明了。(來自論文)
我們註意到TRACKING線程,很清楚明白的告訴了我們是如何跟蹤的,第一,提取ORB特征;第二,進行地圖初始化(如果沒初始化的話)。第三,初始位置估計(這裏用3種模型,代碼在這裏經過了很多判斷來選擇這三種模型的其中一種)得到是一個很粗略的初始位姿;第四,跟蹤局部地圖:為了優化上一步得到的初始位姿態。第五,決定是不是插入關鍵幀。
二、解釋跟蹤裏面使用的三種模型,這三種模型都是用來得到當前幀的位姿T的,我們根據需要選擇一種。
1.TrackWithMotionModel()
這個就是論文裏面提到的恒速運動模型(const velocity motion),意識相當於是:我們根據上一幀的跟蹤結果得到一個運動的速度,我們能夠像我們知道的恒速運動那樣用類似”速度乘以時間“這一公式來估算當前幀的位姿。
2.TrackReferenceKeyFrame()
這個很好理解,就是根據兩幀之間的約束關系來求解位估算位姿。
3. Relocalization()
當我們跟丟了的時候(我用RGBD相機測試代碼的時候只要稍微運動快一點就會跟丟.....),我們用所謂的“重定位”來找回當前幀的位姿,重定位其實跟找閉環相似,都是在database裏面找到與當前幀最相似的那一幀。
三種模型的函數如下:
bool Tracking::TrackWithMotionModel()
三種跟蹤模型的一種:就是根據估計的速度來“預測當前幀的位姿”。
bool TrackReferenceKeyFrame();
三個跟蹤模型中的一種。會改變當前幀的位姿。
bool Tracking::Relocalization()
三 個跟蹤模型的一種。用於跟丟的時候,我們重新定位。知道當前幀的位姿。具體步驟:第一在關鍵幀的database裏面尋找候選的關鍵幀們。第二:將第一步 得到的候選關鍵幀們一個個的與當前幀進行BoW匹配,如果匹配的關鍵點數很少我們就拋棄這個候選的關鍵幀,否則我們就可以構造這個關鍵幀的pno求解器 了。第三步:使用pnp算法算出候選的關鍵幀們與當前幀的位姿。然後進行優化,如果優化的結果不夠好,我們就繼續找,直到找到合適的關鍵幀為止 (nGood>50)。
三、mbOnlyTracking 的解釋
做SLAM我們知道,我們要優化我們估計的位姿,和空間三維點的位置。ORB使用並行線程的策略,在跟蹤的時候也有在建圖。我們可以想象我們要優化的地圖點的時候,地圖點會不斷地收斂到一個範圍,這時候我們就可以認為地圖點穩定了,沒有必要繼續優化了,我們只需要估計優化位姿,這就是mbOnlyTracking。當然反之就是既要建圖又要估計位姿的情況。
四、其他各個函數學習。
Tracking(System* pSys, ORBVocabulary* pVoc, FrameDrawer* pFrameDrawer, MapDrawer* pMapDrawer, Map* pMap,
KeyFrameDatabase* pKFDB, const string &strSettingPath, const int sensor);
構造函數,傳入各種參數,比如相機內參,畸變系數,金字塔層樹,特征點個數......
// Preprocess the input and call Track(). Extract features and performs stereo matching.
cv::Mat GrabImageStereo(const cv::Mat &imRectLeft,const cv::Mat &imRectRight, const double ×tamp);
cv::Mat GrabImageRGBD(const cv::Mat &imRGB,const cv::Mat &imD, const double ×tamp);
cv::Mat GrabImageMonocular(const cv::Mat &im, const double ×tamp);
這幾個函數功能一樣,用於不同的傳感器。這個函數才是真正的跟蹤函數。需要註意的是,當前幀在構造的時候,其所有的特征點、描述子都已經被計算出來了。跟蹤完了的結果就是返回估計的當前幀位姿。
void Track();
這個函數是,我們用於跟蹤的最主要的函數,其具體解釋看上面的第一部分。
// Map initialization for stereo and RGB-D void StereoInitialization();
雙目的初始化。當前幀變成關鍵幀放到地圖裏面,得到關鍵點的3D坐標,並且將當前幀的關鍵點全部變成了地圖點。
// Map initialization for monocular void MonocularInitialization();
這裏首先設置參考幀,new Initializer(mCurrentFrame,1.0,200); 之後還有苛刻的要求來決定是不是要初始化。然後才使用函數Initialize(mCurrentFrame, mvIniMatches, Rcw, tcw, mvIniP3D, vbTriangulated)真正的初始化。但這個函數的得到只是Rcw, tcw, mvIniP3D, vbTriangulated 後面兩個是3D點坐標,和關鍵點是不是三角化了。 最後調用的函數CreateInitialMapMonocular();創建初始化的地圖的。
void Tracking::CreateInitialMapMonocular()
這個函數創建了初始化的單目地圖,主要是就是創建了兩個關鍵幀,並將這個兩個關鍵幀匹配好的點作為地圖點。然後進行一次全局的BA優化下。
bool NeedNewKeyFrame(); void CreateNewKeyFrame();
//將地圖點的點投影到當前幀進行更多的匹配。 void Tracking::SearchLocalPoints()
這裏代碼參考論文,論文提到關鍵幀在這裏可以盡快的插入,因為在局部建圖會去除多余的關鍵幀。盡快插入關鍵幀的好處就是增加魯棒性,特別是在相機旋轉的時候。
創建新的關鍵幀,就是把當前幀當做關幀,創造地圖點,其他受牽連變量改變下就行了。
//就是將局部關鍵幀們裏面的合適的局部關鍵點放到mvpLocalMapPoints容器裏面,做為局部地圖點
void Tracking::UpdateLocalPoints()
void Tracking::UpdateLocalKeyFrames()
跟新局部關鍵幀,改變的是mvpLocalKeyFrames.將4中類型的關鍵幀放到mvpLocalKeyFrames裏面,第一種:與當前幀有共視點的關鍵幀們kf1;第二種:與mvpLocalKeyFrames裏面的關鍵幀有很多公視關系的關鍵幀們;第三種:mvpLocalKeyFrames裏面每個關鍵幀的孩子們(最小生成樹);第四種:mvpLocalKeyFrames裏面每個關鍵幀的父親(最小生成樹)。
ORB-SLAM2學習5 Tracking.h