1. 程式人生 > >ORB-SLAM2學習5 Tracking.h

ORB-SLAM2學習5 Tracking.h

線程 ini 生成 建圖 提取 with 只需要 b-s oci

一、直接上圖,清楚明了。(來自論文)

技術分享

  我們註意到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 &timestamp);
    cv::Mat GrabImageRGBD(const cv::Mat &imRGB,const cv::Mat &imD, const double &timestamp);
    cv::Mat GrabImageMonocular(const cv::Mat &im, const double &timestamp);

這幾個函數功能一樣,用於不同的傳感器。這個函數才是真正的跟蹤函數。需要註意的是,當前幀在構造的時候,其所有的特征點、描述子都已經被計算出來了。跟蹤完了的結果就是返回估計的當前幀位姿

   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