vins 回环检测detectLoop用于寻找当前关键帧在地图关键帧的最佳匹配(寻找TopK的过程), 其过程主要依靠DBow2来实现.
- typedef DBoW2::TemplatedVocabulary<DBoW2::FBrief::TDescriptor, DBoW2::FBrief> BriefVocabulary; 预训练的字典,用于生成词带向量.
- typedef DBoW2::TemplatedDatabase<DBoW2::FBrief::TDescriptor, DBoW2::FBrief> BriefDatabase; 地图关键帧数据库,用于比对词带向量相似性,确定是否找到topK
预先构建字典TemplatedVocabulary
VINS回环检测使用的是FAST特征点检测,并利用BRIEF描述子存储特征, 在数据集中提取到描述子后使用DBoW2层次聚类(Hierarchical K-means)训练字典brief_k10L6.bin
-
从大量图像中提取 ORB 特征描述子
-
将 ORB 描述子进行多级(L=6)聚类,每一级将描述子划分为若干簇(k=10)。这样可以逐步构建出一个树结构的词典,每个叶子节点代表一个视觉单词。聚类完成后,每个簇的质心(聚类中心)就成为一个视觉单词.
-
生成视觉词典,k10L6含有10万个单词(叶子节点)
构建数据库TemplatedDatabase
在 VINS 中,数据库在内存中存储关键帧的词带向量std::vector<BowVector> m_dBowfile 和字典TemplatedVocabulary<TDescriptor, F> *m_voc
-
描述子通过字典生成词带向量BowVector(单词分布直方图,单词有权重)建立数据库
- 建图时: 通过字典查找描述子对应的单词, 当有一张新图像时,提取它的描述子,并将每个描述子映射到视觉词典中的最近的视觉单词(聚类中心)。统计每个视觉单词的出现次数,生成一个单词频次直方图作为图像的特征向量。
- 建图时: 通过 db.add(keyframe->brief_descriptors)建立起数据库db
- 二次读取地图时建立数据库: pose_graph会存关键点keypoints.txt和描述子briefdes.dat,一帧一个文件,这些描述子读取到内存后转为词带向量再次建立数据库, 其实可以优化直接保存词带向量的字典.
-
根据词带向量在数据库中寻找TopK帧
- 新的关键帧进来,同上面的1过程.
- 通过db.query(keyframe->brief_descriptors, ret, 4, frame_index - 50);寻找score最高的top4帧.通过ret返回, 另外前50帧不找topK,vins默认使用计算L1距离计算相似性.