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ì)算描述子
- 獲取所有觀測
observations=mObservations;- 遍歷所有觀測,獲取對應(yīng)特征點(diǎn)描述子
- 計(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; } }- 計(jì)算每個(gè)描述子到其他描述子之間距離的中值
- 找到最小的中值 ,MapPoint描述子就是最小距離中值的描述子
void MapPoint::UpdateNormalAndDepth()
更新平均觀測方向以及觀測距離范圍int MapPoint::PredictScale(const float ¤tDist, 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;