1.回环检测

回环检测的关键,就是如何有效的检测出相机经过同一个地方这件事。它关系到我们估计的轨迹和地图在长时间下的正确性。

由于回环检测提供了当前数据与所有历史数据的关联,在跟踪算法丢失后,我们还可以利用重定位。有些时候,我们把仅有前端和局部后端的系统称为VO,把带有回环检测和全局后端的系统称为SLAM。

回环检测的方法:基于里程计的几何关系和基于外观。
基于几何关系是说,当我们发现当前相机运动到了之前的某个位置时,检测它们有没有回环关系。但是由于误差积累的存在,我们往往没办法正确发现“运动到了之前的某个位置附近”这个事实。
基于外观的(主流做法),它和前端、后端的估计都无关,仅根据俩副图像的相似性确定回环检测关系,这种做法摆脱了积累误差,使回环检测模块成为SLAM一个相对独立的模块。

在基于外观回环检测算法中,核心问题是如何计算图像间的相似性。比如对于图像A和图像B,我们要计算它们之间的相似性评分:s(A,B)。如果单单用俩副图像相减然后取范数 s(A,B)=||A−B|| s ( A , B ) = | | A − B | | s(A,B)=||A-B||。但是由于一副图像在不同角度或者不同光线下其结果会相差很多,所以不使用这个函数。

程序判断与实际总有误差,以下是我们的分类结果:

其中假阳性又称为感知偏差,假阴性称为感知变异。为方便,则真阳性(True Positive)简称TP,假阳性称为(False Positive)简称FP,以此类推。当然,所有的结果我们都希望FP和FN尽可能要低。对于某特定算法,我们可以统计它在某个数据集上的TP、FP、FP、FN的出现次数,并统计俩个统计量:准确率Presicion=TP/(TP+FP)和召回率Recall=TP/(TP+FN)。
从上述公式可以得到,准确率描述的是,算法提取的所有回环中确实是真实回环的概率。而召回率是说在所有真实回环中被正确检测出来的概率。一般而言,我们更倾向于提高算法的准确性,稍微牺牲下召回率。如果出现假阳性,那么就会在后端的Pose graph添加错误的边,导致误差不准。

2.词袋模型

1.确定概念,例如一副图像上有人、狗等,那么“人”“狗” 等概念就是Bag-of-Words中的“单词”,许多单词放在一起,组成了“字典”。
2.确定一副图像中出现了哪些在字典中定义的概念——用单词出现的情况(直方图)描述整副图像,转换成向量。
3.比较上一步中的描述的相似程度。

举个例子,若“人”“狗”都在字典里(这里的字典是已经知道的),不防设为 w1,w2 w 1 , w 2 w_{1}, w_{2},假设A图像中有人没狗,则可以描述成: A=1∗w1+0∗w2 A = 1 ∗ w 1 + 0 ∗ w 2 A=1*w_{1}+0*w_{2},由于字典是固定的,那么只需要一个向量就可以描述整副图像了,例如 A=[1,0]T A = [ 1 , 0 ] T A=\begin{bmatrix} 1,0 \end{bmatrix}^{T}

通过这个词袋模型,我们可以得到俩张图片在这个词袋里面的向量 a,b∈Rw a , b ∈ R w a,b\in R^{w},那么可以计算 s(a,b)=1−1W||a−b||1 s ( a , b ) = 1 − 1 W | | a − b | | 1 s(a,b)=1-\frac{1}{W}||a-b||_{1},如果俩个向量相等,那么我们得到1,完全相反(即a为0的地方b为1)则得到0。

3.字典

假设我们对所有的图片进行特征点的提取,比如有N个。我们现在可以寻找一个有个单词的字典,每个单词可以看作相邻特征点的集合,可以用K-means均值来做:

1.随机选取k个中心点: c1,⋯cn c 1 , ⋯ c n c_{1},\cdots c_{n}。
2.对每一个样本,计算它与每个中心点之间的距离,取最小的作为它的归类。
3.重新计算每个类的中心点。
4.如果每个中心点变化很小,那么退出,算法收敛;否则返回第二步。

K-means存在小问题,就是:需要指定聚类数量,随机选取中心点等。

为了解决这个问题,我们使用一种K叉树来表达字典。假定我们构建一个深度为d、每次分叉为k的树,那么做法如下:

1.在根节点上,用K-means把所有样本聚成k类(有时候为保证聚类均匀性会使用k-means++),这样得到了第一层。
2.对于第一层的每个节点,把属于该节点的样本再聚类k类,得到下一层。
3.以此类推,最后得到叶子层。叶子层即所谓的Words。

一方面,这样一个k分支,深度为d的树,可以容纳 kd k d k^{d} 个单词。另一方面,在查找某个特征对应的单词时,只需要将它与每个中间节点的聚类中心比较(一共d次),即可找到最后的单词。

紧接着我们创建字典,直接上代码:(高博用的是opencv3,我用的是opencv2,略有不同)

#include "DBoW3/DBoW3.h" //使用了BOW这个库
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <iostream>
#include <vector>
#include <string>using namespace cv;
using namespace std;int main( int argc, char** argv )
{// read the imagecout<<"reading images... "<<endl;vector<Mat> images;for ( int i=0; i<10; i++ )//这里选取了10张图片{string path = "/home/hansry/Slam_Book/src/Feature_traning/data/"+to_string(i+1)+".png";images.push_back( imread(path) );}// detect ORB featurescout<<"detecting ORB features ... "<<endl;Ptr< Feature2D > detector = ORB::create("FAST");//由于这里用的是opencv2,所以略有不同vector<Mat> descriptors; for ( Mat& image:images ){vector<KeyPoint> keypoints;Mat descriptor;ORB orb;orb( image, Mat(), keypoints, descriptor );descriptors.push_back( descriptor );}// create vocabularycout<<"creating vocabulary ... "<<endl;DBoW3::Vocabulary vocab;vocab.create( descriptors );cout<<"vocabulary info: "<<vocab<<endl;vocab.save( "vocabulary.yml.gz" );cout<<"done"<<endl;return 0;
}

Cmakelist如下:

cmake_minimum_required(VERSION 2.8.3)
project(Feature_traning)set(CMAKE_CXX_FLAGS "-std=c++11 -O3")
find_package(OpenCV  REQUIRED )
set( DBoW3_INCLUDE_DIRS "/usr/local/include" )
set( DBoW3_LIBS "/usr/local/lib/libDBoW3.so" )
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES test
#  CATKIN_DEPENDS opencv roscpp
#  DEPENDS system_lib
)include_directories(include)
include_directories(${catkin_INCLUDE_DIRS}${OpenCV_INCLUDE_DIRS}
)
add_executable(Feature_traning src/Feature_traning.cpp)target_link_libraries(Feature_traning${catkin_LIBRARIES}${OpenCV_LIBRARIES}${DBoW3_LIBS}
)

结果如下图所示:

我们这里使用的是默认构造函数,所以默认分支数量为10,深度L为5,单词数量为4983,没有达到最大容量。weighting是权重,scoring是评分。

4.相似度计算

在上一part中,我们创建了字典,那么有了字典以后,给定任意特征点 fi f i f_{i},只要在字典树中逐层查找,最后都能找到与之对应的单词 wj w j w_{j},如果字典足够大,我们可以说这俩个来自同一类物体。

假设一副图像提取N个特征,找到这N个特征对应的单词之后,就相当于有了该图像在单词列表中的分布,相当于“这幅图里有一个人和一辆汽车”等。但是有的时候,我们会希望对单词的区分性或重要性加以评估,会给单词加权重。

这里,我们提供一种方法叫TF-IDE,TF的思想是:某单词在一副图像中经常出现,它的区分度就越高。另一方面,IDE的思想是,某单词在字典中出现的频率越低,则分类图像时的区分度越高。

对于IDF部分,假设所有特征数量为n,某个叶子节点的 wi w i w_{i}所含的数量特征为 ni n i n_{i},那么该单词的IDF为:

IDFi=lognni I D F i = l o g n n i IDF_{i}=log\frac{n}{n_{i}}

TF是指某个特征在单副图像中出现的频率。假设图像A中单词 wi w i w_{i}出现了 ni n i n_{i} 次,而一共出现的单词次数是n,那么TF为:
TFi=nin T F i = n i n TF_{i}=\frac{n_{i}}{n}

于是 wi w i w_{i}的权重等于TF乘IDF之积,即 ηi=TFi×IDFi η i = T F i × I D F i \eta_{i}=TF_{i}\times IDF_{i}

考虑权重以后,对于某副图像,我们就可以得到许多个单词,得到BOW:

(A是一幅图像) A={(w1,η1),(w2,η2),⋯,(wn,ηn)}=ΔvA A = { ( w 1 , η 1 ) , ( w 2 , η 2 ) , ⋯ , ( w n , η n ) } = Δ v A A=\begin{Bmatrix} (w_{1},\eta _{1}),(w_{2},\eta _{2}),\cdots ,(w_{n},\eta _{n}) \end{Bmatrix}\overset{\Delta }{= }v_{A}(是一个向量,非零部分表示含有哪些单词)

如何计算俩副图像相似度,这里使用了 L1 L 1 L_{1}范数形式:

s(vA−vB)=2∑Ni=1|vAi|+|vBi|−|vAi−vBi| s ( v A − v B ) = 2 ∑ i = 1 N | v A i | + | v B i | − | v A i − v B i | s(v_{A}-v_{B})=2\sum_{i=1}^{N}|v_{Ai}|+|v_{Bi}|-|v_{Ai}-v_{Bi}|

SLAM学习——回环检测相关推荐

  1. 最全综述 | SLAM中回环检测方法 收藏

    在视觉SLAM问题中,位姿的估计往往是一个递推的过程,即由上一帧位姿解算当前帧位姿,因此其中的误差便这样一帧一帧的传递下去,也就是我们所说的累积误差.一个消除误差有效的办法是进行回环检测.回环检测判断 ...

  2. 3D激光SLAM的回环检测方法

    一.Scan-to-Scan 1.格地图或者说是概率占据栅格地图初步 在Matlab中创建一个1000*1000大小的二维数组,如果数组中每个元素取值为0到255的整数(灰度图),再把这个数组用Mat ...

  3. 开源!用于3D激光雷达SLAM回环检测的实时词袋模型BoW3D

    点击进入->3D视觉工坊学习交流群 0. 笔者个人体会 回环检测对于SLAM系统的全局一致性有着至关重要的影响.现有的视觉SLAM回环检测大多是基于词袋模型,也就是2012年推出的BoW2库和2 ...

  4. 视觉SLAM十四讲学习笔记——ch11回环检测

    文章目录 11.1 理论部分 11.2 实践部分 11.2.1 创建字典 11.2.2 利用已经创建的vocabulary.yml.gz字典,得到图片与图片之间相似性的评分 11.2.3 利用规模更大 ...

  5. 详解 | SLAM回环检测问题

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文经知乎作者fishmarch授权转载,二次转载请联系作者 原文 ...

  6. ​综述 | SLAM回环检测方法

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者丨任旭倩 来源丨计算机视觉life 在视觉SLAM问题中,位姿的估计往往是一个递推的过程,即由上一 ...

  7. 视觉SLAM回环检测、词袋模型和视觉位置识别--论文记录和实验简析

    一.传统方法部分(词袋模型,bag of words,BoW) 1. 预先在环境中采集足够多的图像或者所有位置的图像(成千上万张图片)之后构建视觉词汇表 参考论文:2012年的TRO顶刊 Gálvez ...

  8. 视觉slam十四讲 pdf_视觉SLAM十四讲|第12讲 回环检测

    1. 什么是回环检测 前面有说过累积误差的问题,前一时刻的误差会积累到后面,导致画不成圈圈,如图12-1所示,而画圈圈(全局一致性)很重要,所以需要有一个步骤来纠正当前的计算偏差. 回环检测通过判断相 ...

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

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

最新文章

  1. Fib(兔子问题)python实现多种方法
  2. 最新Transformer模型大盘点,NLP学习必备,Google AI研究员出品丨资源
  3. 关于html5的使用简单总结
  4. JavaScript快速上手入门
  5. SAP GUI security setting on local file access
  6. codeforce Gym 100500F Door Lock (二分)
  7. java学习(177):获取应用程序的路径
  8. python士兵突击_想自学Python进入该行业成为一名自己一直以来就很羡慕和钦佩的程序员,过来人的你有什么想分享的吗?...
  9. Java类的加载过程,类加载器,双亲委派原则
  10. 观察者模式(浅谈监听器工作原理)
  11. linux系统 安装mysql,在linux系统中安装MySQL
  12. jvm gc监控分析常用命令
  13. windows笔记-【内核对象线程同步】概述
  14. HTML,CSS基础十大重点问题
  15. 密码学原理与实践_浅谈SSH2工作原理
  16. C语言自己写代码实现的strcmp函数
  17. goeasy小demo
  18. 002--YAML工具
  19. js复制一个数组(浅复制、深复制)
  20. [翻译] 在 Overleaf 中使用参考文献

热门文章

  1. 软件测试书清华大学出版社,清华大学出版社-图书详情-《软件测试技术与实践》...
  2. 查看git当前tag_Git - git tag - 查看当前分支 tag 版本说明
  3. 超级实习生名企实习经历经得起背调吗?是正规实习吗?
  4. JavaScript预习
  5. squirrel 脚本_Squirrel便携式Shell和脚本语言
  6. 使用Squirrel创建基于Electron开发的Windows 应用安装包
  7. How to Play HLS Live Stream using ExoPlayer
  8. 协方差矩阵和相关系数矩阵(R语言)
  9. Maven及插件安装
  10. 【赛报速递】“赛博朋克,无不可测!” 2020上海国际创客大赛EdgeX专题赛赛报之赛博联物篇