【回环检测】如何理解loopClosing中的连续性检测

在连续性检测中会用到几个变量如下,可以先理解一下这几个变量之间的关系如图:

 

总结:回环部分对候选帧的检测其实可以理解为静态检测和动态检测;静态检测也就是对于图片相似度的检测,通过候选帧及其共视帧的commonwords 和score进行选择,保存下来的帧都具有静态一致性;空间上的连续性检测主要是动态检测,用于筛选那些落单的相似帧,通俗来讲就是这一候选、帧与当前帧相似,但是走两步之后就不一定相似了(传说中的没病走两步),怎么实现走两步的效果检测呢?那就是看簇与簇之间有没有共同帧了;

PS:簇 = 候选帧 + 候选帧的共视帧;

在来看一下回环中连续性检测部分的代码:

其实可以将代码简化来看:
1. 首先第一步,就是从database中去检测有足够相似度的候选帧,其实这里的检测就已经不仅仅是单帧的检测,对当前帧和其共视帧一起计算得分,满足条件的才能称之为candidate;

// Query the database imposing the minimum score
vector<KeyFrame*> vpCandidateKFs = mpKeyFrameDB->
                             DetectLoopCandidates(mpCurrentKF, minScore);

2. 接下来第二步的判断其实还是很重要,即如果没有检测到candidate的话就需要将mvConsistentGroups清除,这点说明,其实mvConsistentGroups从一开始就是空的;

    // If there are no loop candidates, just add new keyframe and return false
    if(vpCandidateKFs.empty())
    {
        mpKeyFrameDB->add(mpCurrentKF);
        mvConsistentGroups.clear();
        mpCurrentKF->SetErase();
        return false;
    }

3. 那既然从一开始是空的,那我们不妨就先从它为空时来理解代码,接下来是对符合条件的candidate进行筛选了,如果mvConsistentGroups为空,那么代码将会变成下面这个样子:

//初始化阶段其实这些所有的变量size都是0;
    mvpEnoughConsistentCandidates.clear();
    vector<ConsistentGroup> vCurrentConsistentGroups;
    vector<bool> vbConsistentGroup(mvConsistentGroups.size(),false);
    for(size_t i=0, iend=vpCandidateKFs.size(); i<iend; i++)
    {
        KeyFrame* pCandidateKF = vpCandidateKFs[i];
        //获取每个候选帧的关联簇,其实就是共视帧和其本身
        set<KeyFrame*> spCandidateGroup = pCandidateKF->GetConnectedKeyFrames();
        spCandidateGroup.insert(pCandidateKF);
        bool bEnoughConsistent = false;
        bool bConsistentForSomeGroup = false;
        for(size_t iG=0, iendG=mvConsistentGroups.size(); iG<iendG; iG++)
        {
            //因为mvConsistentGroups的size为0,所以这里面根本不会执行,也就说明当前簇其实与别人没有关联
        }

        // If the group is not consistent with any previous group insert with consistency counter set to zero
        if(!bConsistentForSomeGroup)
        {//在这里将这个候选帧对应的一簇帧  的 连续度 设置为 0,并且保存为ConsistentGroup 的形式;
            ConsistentGroup cg = make_pair(spCandidateGroup,0);
            vCurrentConsistentGroups.push_back(cg); //这时,vCurrentConsistentGroups,我们称他为簇村儿,因为它里面保存的都是一簇一簇的“东西”,簇村儿终于有内容了
        }
    }

 4. 既然vCurrentConsistentGroups中已经有了刚刚添加进去的第一个关键帧簇,那么接下来我们看一下循环里的内容:

          //首先获取到刚刚放入的那一簇,我们叫他老一簇
           set<KeyFrame*> sPreviousGroup = mvConsistentGroups[iG].first;
         //接下来for循环中的spCandidateGroup 代表新的一簇
            bool bConsistent = false;
            //这个for循环主要做的就是检查老一簇中与新一簇有没有共同话题,也就是共同帧
            for(set<KeyFrame*>::iterator sit=spCandidateGroup.begin(), send=spCandidateGroup.end(); sit!=send;sit++)
            {
                if(sPreviousGroup.count(*sit))
                {
                    bConsistent=true;
                    bConsistentForSomeGroup=true; //有的话,说明新一簇的表现是很好的,比较连贯
                    break;
                }
            }

5. 至此,对新一簇的连贯性检测实际已经完成了,其实就是看老一簇与新一簇有没有共同的帧,有共同帧才能说明这两个关键帧距离大概比较近,否则就是孤立的一个候选人;但是仅仅验证完连贯性还不行,还需要将新的簇也保存进入 簇村儿 中:

                if(bConsistent)
                {
                    int nPreviousConsistency = mvConsistentGroups[iG].second;
                    int nCurrentConsistency = nPreviousConsistency + 1;
                    if(!vbConsistentGroup[iG])
                    //这个参数可以理解为连续性作证的一次性,就是同样一簇帧,只能在连续性作证时给一簇作证,不能重复使用,
                    //比如第一次放进去的老一簇,如果与新一簇有联系,那么就算是给新一簇作过证了,接下来有了新新一簇,即使与老一簇有共同帧,其实也不算数了,新新一簇只能与
    新一簇进行比较
                    {
                        ConsistentGroup cg = make_pair(spCandidateGroup,nCurrentConsistency);
                        vCurrentConsistentGroups.push_back(cg);
                        vbConsistentGroup[iG]=true; //this avoid to include the same group more than once
                    }
                    //当连续性大于3的时候就可以把它放入最终的候选帧mvpEnoughConsistentCandidates
                    if(nCurrentConsistency>=mnCovisibilityConsistencyTh && !bEnoughConsistent)
                    {
                        mvpEnoughConsistentCandidates.push_back(pCandidateKF);
                        bEnoughConsistent=true; //this avoid to insert the same candidate more than once
                    }
                }  

 最后一个初步的关系图如下:

(这里稍微注意一下,Group的Consistency会进行累加,表示截止到当前Group,已经有n个Group是连在一起的)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值