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

成员函数

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的数量
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,692评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,482评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,995评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,223评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,245评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,208评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,091评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,929评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,346评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,570评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,739评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,437评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,037评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,677评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,833评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,760评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,647评论 2 354

推荐阅读更多精彩内容