ORB-SLAM2代碼筆記(五):MapPoint

MapPoint

主要的成員變量
  • long unsigned int mnId; 地圖點(diǎn)的Global id

  • static long unsigned int nNextId;

  • const long int mnFirstKFid; 創(chuàng)建該MapPoint的關(guān)鍵幀ID
    如果是從幀中創(chuàng)建的話,會(huì)將普通幀的id存放于這里

  • const long int mnFirstFrame; 創(chuàng)建該MapPoint的幀ID(即每一關(guān)鍵幀有一個(gè)幀ID)

  • int nObs;被觀測到的次數(shù)


用于跟蹤的變量

  • float mTrackProjX; 當(dāng)前地圖點(diǎn)投影到某幀上后的坐標(biāo)

  • float mTrackProjY; 當(dāng)前地圖點(diǎn)投影到某幀上后的坐標(biāo)

  • float mTrackProjXR; 當(dāng)前地圖點(diǎn)投影到某幀上后的坐標(biāo)(右目)

  • int mnTrackScaleLevel; 所處的尺度, 由其他的類進(jìn)行操作

  • float mTrackViewCos; 被追蹤到時(shí),那幀相機(jī)看到當(dāng)前地圖點(diǎn)的視角

  • long unsigned int mnFuseCandidateForKF; 在局部建圖線程中使用,表示被用來進(jìn)行地圖點(diǎn)融合的關(guān)鍵幀(存儲(chǔ)的是這個(gè)關(guān)鍵幀的id)

  • long unsigned int mnLoopPointForKF;如果這個(gè)地圖點(diǎn)對應(yīng)的關(guān)鍵幀參與到了回環(huán)檢測的過程中,那么在回環(huán)檢測過程中已經(jīng)使用了這個(gè)關(guān)鍵幀修正只有的位姿來修正了這個(gè)地圖點(diǎn),那么這個(gè)標(biāo)志位置位

  • cv::Mat mPosGBA;全局BA優(yōu)化后(如果當(dāng)前地圖點(diǎn)參加了的話),這里記錄優(yōu)化后的位姿

  • long unsigned int mnBAGlobalForKF;如果當(dāng)前點(diǎn)的位姿參與到了全局BA優(yōu)化,那么這個(gè)變量記錄了那個(gè)引起全局BA的"當(dāng)前關(guān)鍵幀"的id

  • static std::mutex mGlobalMutex;全局BA中對當(dāng)前點(diǎn)進(jìn)行操作的時(shí)候使用的互斥量

  • cv::Mat mWorldPos;MapPoint在世界坐標(biāo)系下的坐標(biāo)

  • std::map<KeyFrame*,size_t> mObservations; 觀測到該MapPoint的KF和該MapPoint在KF中的索引

  • cv::Mat mNormalVector;該MapPoint平均觀測方向(目前不知道是做什么的)

  • cv::Mat mDescriptor;每個(gè)3D點(diǎn)也有一個(gè)descriptor如果MapPoint與很多幀圖像特征點(diǎn)對應(yīng)(由keyframe來構(gòu)造時(shí)),那么距離其它描述子的平均距離最小的描述子是最佳描述子;MapPoint只與一幀的圖像特征點(diǎn)對應(yīng)(由frame來構(gòu)造時(shí)),那么這個(gè)特征點(diǎn)的描述子就是該3D點(diǎn)的描述子 (泡泡機(jī)器人的公開課里面有提到),通過 ComputeDistinctiveDescriptors() 得到的最優(yōu)描述子

  • KeyFrame* mpRefKF;生成它的關(guān)鍵幀

  • Map* mpMap;所屬的地圖

  • std::mutex mMutexPos;對當(dāng)前地圖點(diǎn)位姿進(jìn)行操作的時(shí)候的互斥量

  • std::mutex mMutexFeatures;對當(dāng)前地圖點(diǎn)的特征信息進(jìn)行操作的時(shí)候的互斥量

  • 其他
    int mnVisible;
    int mnFound;
    bool mbBad;
    MapPoint* mpReplaced;
    float mfMinDistance;
    float mfMaxDistance;

成員函數(shù):
  • 構(gòu)造MapPoint分兩種:參考幀是關(guān)鍵幀或參考幀是普通幀
// 參考幀是關(guān)鍵幀,該地圖點(diǎn)將于許多幀關(guān)鍵幀對應(yīng),建立關(guān)鍵幀之間的共視關(guān)系
MapPoint::MapPoint(const cv::Mat &Pos, KeyFrame *pRefKF, Map* pMap)
// 參考幀是普通幀,該地圖點(diǎn)只與當(dāng)前普通幀的特征點(diǎn)對應(yīng)
MapPoint::MapPoint(const cv::Mat &Pos, Map* pMap, Frame* pFrame, const int &idxF)
  • void MapPoint::AddObservation(KeyFrame* pKF, size_t idx)添加觀測
    mObservations[pKF]=idx;添加觀測
    分成單目和雙目兩種清空添加觀測,單目時(shí)觀測次數(shù)加1,雙目時(shí)觀測次數(shù)加2.
  • void MapPoint::EraseObservation(KeyFrame* pKF) 刪除某個(gè)關(guān)鍵幀對當(dāng)前地圖點(diǎn)的觀測
    先減少觀測次數(shù),還是分成單目和雙目兩種,和添加的時(shí)候類似
    然后刪除:mObservations.erase(pKF);
    如果該keyFrame是參考幀,該Frame被刪除后重新指定關(guān)鍵字
            if(mpRefKF==pKF)
                mpRefKF=mObservations.begin()->first;

當(dāng)觀測到該點(diǎn)的相機(jī)數(shù)目少于2時(shí),丟棄該點(diǎn):SetBadFlag()

  • void MapPoint::SetBadFlag()告知可以觀測到該MapPoint的Frame,該MapPoint已被刪除
    把mObservations轉(zhuǎn)存到obs,然后mObservations.clear();
    遍歷obs告訴關(guān)鍵幀該MapPoint被刪了
  • void MapPoint::Replace(MapPoint* pMP)
    當(dāng)前地圖點(diǎn)(this),替換成pMp。主要使用在閉環(huán)時(shí),調(diào)整地圖點(diǎn)和關(guān)鍵幀,建立新的關(guān)系:
    設(shè)置當(dāng)前地圖點(diǎn)為壞點(diǎn)
mbBad=true;

關(guān)鍵幀將聯(lián)系的this替換成pMap:

pKF->ReplaceMapPointMatch(mit->second, pMP);// KeyFrame中mit->second索引對應(yīng)的地圖點(diǎn),用pMP替換掉原來的this
pMP->AddObservation(pKF,mit->second);// pMp地圖點(diǎn)添加觀測關(guān)鍵幀
  • void MapPoint::ComputeDistinctiveDescriptors()計(jì)算描述子

    1. 獲取所有觀測
    observations=mObservations;
    
    1. 遍歷所有觀測,獲取對應(yīng)特征點(diǎn)描述子
    2. 計(jì)算描述子兩兩之間的距離
    std::vector<std::vector<float> > Distances;
    Distances.resize(N, vector<float>(N, 0));
    for (size_t i = 0; i<N; i++)
    {
        //和自己的距離當(dāng)然是0
        Distances[i][i]=0;
        for(size_t j=i+1;j<N;j++)
        {
            int distij = ORBmatcher::DescriptorDistance(vDescriptors[i],vDescriptors[j]);
            Distances[i][j]=distij;
            Distances[j][i]=distij;
        }
    }
    
    1. 計(jì)算每個(gè)描述子到其他描述子之間距離的中值
    2. 找到最小的中值 ,MapPoint描述子就是最小距離中值的描述子
  • void MapPoint::UpdateNormalAndDepth()
    更新平均觀測方向以及觀測距離范圍

  • int MapPoint::PredictScale(const float &currentDist, KeyFrame* pKF)

在進(jìn)行投影匹配的時(shí)候會(huì)給定特征點(diǎn)的搜索范圍,考慮到處于不同尺度(也就是距離相機(jī)遠(yuǎn)近,位于圖像金字塔中不同圖層)的特征點(diǎn)受到相機(jī)旋轉(zhuǎn)的影響不同,
因此會(huì)希望距離相機(jī)近的點(diǎn)的搜索范圍更大一點(diǎn),距離相機(jī)更遠(yuǎn)的點(diǎn)的搜索范圍更小一點(diǎn),所以要在這里,根據(jù)點(diǎn)到關(guān)鍵幀/幀的距離來估計(jì)它在當(dāng)前的關(guān)鍵幀/幀中,
會(huì)大概處于哪個(gè)尺度

 float ratio;
    {
        unique_lock<mutex> lock(mMutexPos);
        ratio = mfMaxDistance/currentDist;
    }

    // 同時(shí)取log線性化
    int nScale = ceil(log(ratio)/pKF->mfLogScaleFactor);
    if(nScale<0)
        nScale = 0;
    else if(nScale>=pKF->mnScaleLevels)
        nScale = pKF->mnScaleLevels-1;

    return nScale;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容