美文网首页
ORB-SLAM2代码阅读笔记(九):ORBmatcher

ORB-SLAM2代码阅读笔记(九):ORBmatcher

作者: liampayne_66d0 | 来源:发表于2019-08-16 11:17 被阅读0次

    成员函数

    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的数量

    相关文章

      网友评论

          本文标题:ORB-SLAM2代码阅读笔记(九):ORBmatcher

          本文链接:https://www.haomeiwen.com/subject/hwdfsctx.html