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

总结:回环部分对候选帧的检测其实可以理解为静态检测和动态检测;静态检测也就是对于图片相似度的检测,通过候选帧及其共视帧的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 falseif(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 zeroif(!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的时候就可以把它放入最终的候选帧mvpEnoughConsistentCandidatesif(nCurrentConsistency>=mnCovisibilityConsistencyTh && !bEnoughConsistent){mvpEnoughConsistentCandidates.push_back(pCandidateKF);bEnoughConsistent=true; //this avoid to insert the same candidate more than once}}  

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

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

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

  1. 使用UWP人脸检测API在WPF中进行人脸检测

    目录 介绍 先决条件 背景 人脸检测 标记人脸 查看模型 视图 结论 Download repository 介绍 通用Windows平台的Windows.Media.FaceAnalysis名称空间 ...

  2. SC-A-LOAM:在A-LOAM中加入回环检测

    Thanks to LOAM, A-LOAM, and LIO-SAM code authors. The major codes in this repository are borrowed fr ...

  3. 【SLAM】VINS-MONO解析——回环检测和重定位

    9. 回环检测与重定位 本部分内容涉及到的代码大部分在pose_graph文件夹下,少部分在vins_estimator里. 原创内容,转载请先与我联系并注明出处,谢谢! 系列内容请点击:[SLAM] ...

  4. 视觉SLAM⑪----回环检测

    目录 11.0 本章目标 11.1 概述 11.1.1 回环检测的意义 11.1.2 回环检测的方法 11.1.3 准确率和召回率 11.2 词袋模型 11.3 字典 11.3.1 字典的结构 11. ...

  5. 一文详解回环检测与重定位

    标题:VINS-Mono代码解读-回环检测与重定位 pose graph loop closing 作者:Manii 来源:https://blog.csdn.net/qq_41839222/cate ...

  6. GT Transceiver的回环模式

    GT Transceiver的回环模式 回环模式是transceiver数据通路的专门配置,其中数据流被折返到源头.通常情况下,传输一个特定的数据流,然后进行比较以检查错误.下图说明了一个具有四种不同 ...

  7. 回环设备(loop-back devices)

    回环设备( 'loopback device')允许用户以一个普通磁盘文件虚拟一个块设备.设想一个磁盘设备,对它的所有读写操作都将被重定向到读写一个名为 disk-image 的普通文件而非操作实际磁 ...

  8. what is 本地回环

    Linux的本地回环接口是一种虚拟网络接口,通常表示为"lo",用于将数据包从同一主机的一个网络应用程序传输到另一个网络应用程序.当数据被发送到本地回环接口时,操作系统将数据包传递 ...

  9. OpenCV中图像轮廓检测

    OpenCV中图像轮廓检测 通过之前的Canny方法可以得到图像的边界,但是我们无法得到边界的数学信息.所以就有了今天的图像轮廓检测. 在OpenCV中图像轮廓检测的API: findContours ...

最新文章

  1. C语言实现链式栈(LinkStack)
  2. 分布式系列文章——Paxos算法原理与推导
  3. Qt (5.10.0)for android
  4. Android中的APinner2
  5. 拼凑 牛客练习赛70
  6. 多态情况下,怎么用基类指针去访问基类的虚函数?
  7. AD如何清理过期电脑
  8. Android新增usb Audio(mic)设备
  9. 程序设计语言的特性——心理特性、工程特性、技术特性
  10. VMware 15.6版本下载安装
  11. vscode插件查找并导出到新电脑
  12. ITellYou结合软碟通安装Win10系统指南
  13. 前端流媒体:MSE入门
  14. 2017年域名从Godaddy转移到Namesilo过程全记录
  15. DTU网关连接MQTT服务器、MQTT.fx工具测试
  16. 高通Q888内核源码分析--概述篇
  17. 与你相关|《个人信息保护法》发布后我们能做什么?
  18. 如何将证件照缩小到20k像素不变?怎么把照片压缩到20k?
  19. AppleScript(7) : 睡眠
  20. 网页密码查看器+原代码+windows密码查看

热门文章

  1. bzoj 2326: [HNOI2011]数学作业(矩阵快速幂)
  2. 二分法实战教学快速入门(折半查找法)
  3. python机器学习案例系列教程——模型评估总结
  4. 五分钟快速过完Verilog HDL基本概念(5)数据类型
  5. react typescript 父组件调用子组件
  6. super 关键字的使用及说明
  7. 浅谈sql之连接查询
  8. C++11右值引用和std::move语句实例解析
  9. Perforce-Server迁移
  10. 检查用户是否有访问权限