成员函数
SearchByProjection(Frame &F, const vector<MapPoint*> &vpMapPoints, const float th)
- 作用:SearchByProjection函数利用将相机坐标系下的Location MapPoints投影到图像坐标系,,在其投影点附近根据描述子距离选取匹配,由此增加当前帧的MapPoints
- Frame &F当前帧
- const vector<MapPoint*> &vpMapPoints是 Local MapPoints
- th 搜索半径的因子
- 返回:成功匹配的数量
- 主要逻辑:通过地图点投影到当前帧,利用一个搜索窗口搜索兴趣点,如果没找到兴趣点则跳过这个地图点,遍历所有找到的兴趣点,利用描述子计算距离,寻找描述子距离最小和次小的特征点
// 通过投影点(投影到当前帧,见isInFrustum())以及搜索窗口和预测的尺度进行搜索, 找出附近的兴趣点
const vector<size_t> vIndices =
F.GetFeaturesInArea(pMP->mTrackProjX,pMP->mTrackProjY,r*F.mvScaleFactors[nPredictedLevel],nPredictedLevel-1,nPredictedLevel);
if(vIndices.empty())//没找到兴趣点
continue;
const cv::Mat MPdescriptor = pMP->GetDescriptor();//求描述子
int bestDist=256;
int bestLevel= -1;
int bestDist2=256;
int bestLevel2 = -1;
int bestIdx =-1 ;
// Get best and second matches with near keypoints
for(vector<size_t>::const_iterator vit=vIndices.begin(), vend=vIndices.end(); vit!=vend; vit++)
{
const size_t idx = *vit;
// 如果Frame中的该兴趣点已经有对应的MapPoint了,则退出该次循环
if(F.mvpMapPoints[idx])
if(F.mvpMapPoints[idx]->Observations()>0)
continue;
if(F.mvuRight[idx]>0)
{
const float er = fabs(pMP->mTrackProjXR-F.mvuRight[idx]);
if(er>r*F.mvScaleFactors[nPredictedLevel])
continue;
}
const cv::Mat &d = F.mDescriptors.row(idx);
const int dist = DescriptorDistance(MPdescriptor,d);//求取描述子距离
// 根据描述子寻找描述子距离最小和次小的特征点
if(dist<bestDist)
{
bestDist2=bestDist;
bestDist=dist;
bestLevel2 = bestLevel;
bestLevel = F.mvKeysUn[idx].octave;
bestIdx=idx;
}
else if(dist<bestDist2)//求次小距离
{
bestLevel2 = F.mvKeysUn[idx].octave;
bestDist2=dist;
}
}
int ORBmatcher::SearchByBoW(KeyFrame* pKF,Frame &F, vector<MapPoint*> &vpMapPointMatches)
- 作用:通过词袋(bow)对关键帧(pKF)和当前帧(F)中的特征点进行快速匹配,不属于同一节点(node)的特征点直接跳过匹配,对属于同一节点(node0的特征点通过描述子距离进行匹配,根据匹配,用关键帧(pKF)中特征点对应的MapPoint更新F中特征点对应的MapPoints,通过距离阈值、比例阈值和角度投票进行剔除误匹配
- pKF:关键帧
- F:当前帧
- vpMapPointMatches 当前帧中MapPoints对应的匹配,NULL表示未匹配
- 返回值成功匹配数量
SearchByProjection(KeyFrame* pKF, cv::Mat Scw, const vector<MapPoint> &vpPoints, vector<MapPoint> &vpMatched, int th)
- 作用:根据Sim3变换,将每个vpPoints投影到pKF上,并根据尺度确定一个搜索区域,根据该MapPoint的描述子与该区域内的特征点进行匹配,如果匹配误差小于TH_LOW即匹配成功,更新vpMatched
- Scw:sim3矩阵 即变换矩阵
- vpPoints:MapPoint
- vpMatched:MapPoint匹配点
SearchByBoW(KeyFrame *pKF1, KeyFrame *pKF2, vector<MapPoint *> &vpMatches12)
- 作用:通过词包,对关键帧的特征点进行跟踪,该函数用于闭环检测时两个关键帧间的特征点匹配,通过bow对pKF和F中的特征点进行快速匹配(不属于同一node的特征点直接跳过匹配),对属于同一node的特征点通过描述子距离进行匹配,根据匹配,更新vpMatches12
- pKF1 关键帧1
- pKF2 关键帧2
- vpMatches12 pKF2中与pKF1匹配的MapPoint,null表示没有匹配
SearchForTriangulation(KeyFrame *pKF1, KeyFrame *pKF2, cv::Mat F12,vector<pair<size_t, size_t> > &vMatchedPairs, const bool bOnlyStereo)
- 作用:利用基本矩阵F12,在两个关键帧之间未匹配的特征点中产生新的3d点
- pKF1 关键帧1
- pKF2关键帧2
- F12 基础矩阵
- vMatchedPairs 存储匹配特征点对,特征点用其在关键帧中的索引表示
- bOnlyStereo 在双目和rgbd情况下,要求特征点在右图存在匹配
SearchBySim3(KeyFrame *pKF1, KeyFrame pKF2, vector<MapPoint> &vpMatches12,const float &s12, const cv::Mat &R12, const cv::Mat &t12, const float th)
- 作用 通过Sim3变换,确定pKF1的特征点在pKF2中的大致区域,同理,确定pKF2的特征点在pKF1中的大致区域,在该区域内通过描述子进行匹配捕获pKF1和pKF2之前漏匹配的特征点,更新vpMatches12(之前使用SearchByBoW进行特征点匹配时会有漏匹配)
- s12尺度
- R12 1到2的旋转矩阵
- t12 1到2的平移
- 基本思路:1.通过Sim变换,确定pKF1的特征点在pKF2中的大致区域,在该区域内通过描述子进行匹配捕获pKF1和pKF2之前漏匹配的特征点,更新vpMatches12(之前使用SearchByBoW进行特征点匹配时会有漏匹配)
2.通过Sim变换,确定pKF2的特征点在pKF1中的大致区域,在该区域内通过描述子进行匹配捕获pKF1和pKF2之前漏匹配的特征点,更新vpMatches12
SearchByProjection(Frame &CurrentFrame, const Frame &LastFrame, const float th, const bool bMono)
- 作用:上一帧中包含了MapPoints,对这些MapPoints进行tracking,由此增加当前帧的MapPoints,
- LastFrame 上一帧
- th 阈值
- bMono是否为单目
- 返回值 成功匹配的数量
- 基本思路:1. 将上一帧的MapPoints投影到当前帧(根据速度模型可以估计当前帧的Tcw)2. 在投影点附近根据描述子距离选取匹配,以及最终的方向投票机制进行剔除
Fuse(KeyFrame *pKF, const vector<MapPoint *> &vpMapPoints, const float th)
- 作用:将MapPoints投影到关键帧pKF中,并判断是否有重复的MapPoints,1.如果MapPoint能匹配关键帧的特征点,并且该点有对应的MapPoint,那么将两个MapPoint合并(选择观测数多的),2.如果MapPoint能匹配关键帧的特征点,并且该点没有对应的MapPoint,那么为该点添加MapPoint
- vpMapPoints 当前关键帧的MapPoints
Fuse(KeyFrame *pKF, cv::Mat Scw, const vector<MapPoint *> &vpPoints, float th, vector<MapPoint *> &vpReplacePoint)
- 作用 投影MapPoints到KeyFrame中,并判断是否有重复的MapPoints
- pKF 相邻关键帧
- Scw Scw为世界坐标系到pKF机体坐标系的Sim3变换,用于将世界坐标系下的vpPoints变换到机体坐标系
- vpPoints 当前关键帧的MapPoints
- vpReplacePoint 记录下来需要被替换掉的pMPinKF
- 返回值 重复MapPoints的数量