学习到这里为止,SLAM14讲的主要知识就不多了。这章的内容书里只是做了一个简述,因此读起来也没有什么难度。但是初学者不仔细看就很容易犯糊涂。
1.给后端的Pose Graph提供更多有效的数据(即走到同一个位置附近了),否则后端优化可能把前端的误差累积起来,出现漂移问题。
2.跟踪算法如果跟丢了,利用回环检测进行重定位。
1.朴素思路:(1)暴力匹配,任意两幅图像做一遍特征匹配,并根据数量确定两幅相关联的图像。问题:时间复杂度太大,不实用。(2)随机抽取历史数据进行回环检测。问题:抽到回环几率下降。检测率不高。
2.不盲目的预测:
(1)基于里程计的几何关系:发现相机到达之前的某个位置附近,进行回环检测。存在问题:由于累积误差存在,往往没办法正确发现“运动到了某个位置附近”。
(2)基于外观的方式:主流方式。(本文讲的也是这个方式)
准确率:算法检测到“是回环”的结果里,有多少个真的是回环。(针对结果)
召回率:有多少个真的回环,被算法检测到“是回环”了。(针对真实样本)
记忆:阳性Postive,阴性Negative,是算法的结果。真True,假False,是真正的结果。由首字母结合。
slam中对准确率要求更高,因为如果实际不是回环,算法却判断为回环(即假阳性)会在后端Pose Graph中添加根本错误的边,严重影响算法结果。而召回率低一些关系不大,因为大不了没检测到回环,后端的优化有点漂移和累积误差而已。
1.强调的是词的有无,而不是顺序。
2.可以记录词出现的次数,也可以记录词是否出现(这样的向量是二值向量)
3.两个向量的相似性,可以由如下方式定义(定义方式不唯一):
词袋(BoW)表现了字典里的词是否出现或是出现的情况。有词带的前提是,先得有字典。
字典的生成方式:聚类
可以用的方式:K-means聚类。
字典的数据结构:k叉树(叶子层是单词,中间节点的作用是方便查找)
如何判断两幅图像的相似性?
TF:某单词在一个图像中经常出现,它的区分度就高
IDF:某单词在字典中出现的频率越低,则分类图像时区分度越高
(关于这块我之前有个不明白:字典中的单词不都是唯一的吗?怎么会说“某单词在字典中出现的频率越低”呢?)
这块理解很重要,之前我的理解出现了一些偏差,犯了糊涂。后来才明白。在此特别感谢我的师兄李坤指出我的低级错误。
并不是一个特征点就是一个叶子节点,而是作为最下面的一个类别(还可以再细分,很多个特征点同属这个单词),也就是说聚成了k类。
单幅图像A中单词wi出现了ni次,一共出现的单词数为n次,(即图像里有n个单词,其中某个单词出现的次数是ni次,换句话说就是有ni个特征点同属这个单词)
TF为:
整体的字典中,共有n个特征点,其中单词wi里面含有的特征点有ni个,IDF为
注意IDF是离线算出来的,也就是说所有的图像都已经有了,提取特征点聚类了。而TF是在线算出来的,来一张算一张。
这样单词的权重就可以通过TF和IDF乘积计算出来。
这块扩展一下:
每个单词(也就是一小部分特征点的集合)指向这么一个数据结构:一个是图像号,一个是权重。这也就是词袋中的“逆序指针/索引”。
在字典建立好以后,每次有新的图像来了,比如A图检测到1号单词,那么就把1号叶子节点指针指向的列表中多加一个Image A,表示A中曾经出现过这个单词。然后把1单词在A图中对应的权重(该单词类别内所含有特征点数目/该图像中所有的特征点)记录下来。
除了“逆序指针”以外,还有个“顺序索引”:
顺序索引存储了图像特征和它们关联的节点:
左图是2011会议论文所采用的存储结构,以word为单位,右图是2012在TRO期刊上使用的存储结构,以node为单元。
图里的f1,65表示,第一张图像的第65个特征点是node3的子节点(node3可以指定为倒数第二层,也可以指定为倒数第三层……几层都行,这个按需来)的第三个节点。这样的目的是快速匹配而不是暴力匹配。之后当前关键帧的这个叶节点可以和上一个关键帧在这个node3下的其他兄弟叶节点进行匹配。
【扩展结束】
每一副图像,都由向量表示,即一堆(wi,ni)组成。wi是检测到的单词,ni是上面算出的TF和IDF的乘积(所以每个单词在不同图像中对应的TF是不一样的,而单词自身的IDF是一样的)
分值的绝对值大小不一定帮助大。按上面的分值来说,高分说明相似,低分说明不相似。(有的环境本身外观相似,有的环境各个地方都不同,这样前者向量的差异很小,分值高但并不一定代表回环,后者向量的差异很大,分值低却可能代表回环)
处理方法:取先验相似度(关键帧图像与上一时刻关键帧图像的相似性),做归一化处理:
从这个角度可以制定一个策略:当前帧与之前某关键帧的相似度超过当前帧与上一个关键帧的三倍,就可能存在回环。
问题:关键帧是啥?
用于回环检测的帧。可以取的稀疏一些,彼此不同但涵盖整个环境。在后端优化中,主要优化的也是关键帧
对此我的理解:假如把运动轨迹抽象成一个10厘米的尺子,把整数厘米的刻度当成关键帧,然后回环检测就是和这些关键帧作为对比,跟哪个最像就说明走到哪个附近了。
1.用于回环检测的帧取的稀疏一些,彼此之间不太相同,又能涵盖整个环境。
2.把"相近"的回环聚成一类,使算法不要反复地检测同一类的回环。
1.时间上的一致性检测:一段时间内一直检测的回环才当做是回环(n,n+1,n+2……帧都和关键帧像,才当做是回环)
2.空间上的一致性检测:把回环上的两帧进行特征匹配,估计相机运动。把运动放到Pose Graph中,检查与之前估计是否有很大出入。
学了这章以后我的理解是,回环检测并不是用来百分百确定我走到了哪个位姿上,而是通过回环检测判断我是否走到了之前走过的位置附近,也就是说两张图像可以是不完全相似的。回环检测到的目的,是为了给后端优化一个参考,或者是跟丢以后,重新把之前的位姿续上。
而广义上的“重定位”,应该是指我给出一张图像,虽然我没有完全精准的走到那个位置,但是我可以根据这个图像算出它所在的位置。这应该就是回环检测和重定位的区别。回环检测也可以拿来做重定位,就是上面说的跟丢了,把位姿续上,但这并不代表回环检测就等同于重定位,而是说做回环检测的目的,是为了要重定位。
和机器学习的关系是,1.聚类方式能否有更先进的?2.能否不用SURF,ORB等人工设计的特征点,而是用机器学习学习到的图像特征?显然,这点是可以和机器学习结合的突破口之一。
这块补充一些参考资料:
1.浅谈回环检测中的词袋模型(bag of words)
2.ORB-SLAM2:基于可识别特征的自主导航与地图构建(这篇内容中包含著名的《Bags of Binary Words for Fast Place Recognition in Image Sequences 》的翻译,可以作为参考)
3.浅谈SLAM的回环检测技术
4.【泡泡机器人原创专栏】DBoW3 视觉词袋模型、视觉字典和图像数据库分析
5.词袋模型一些理解