原文链接:VSLAM系列原创09讲 | 如何在线生成BoW词袋向量?原理+代码详解
本文系ORB-SLAM2原理+代码实战系列原创文章,对应的视频课程见:
大家好,今天我们继续更新ORB-SLAM2/3系列的原创文章,以小白和师兄对话的形式阐述背景原理+代码解析,喜欢的点个赞分享,支持的人越多,更新越有动力!如有错误欢迎留言指正!
代码注释地址:
https://github.com/electech6/ORB_SLAM2_detailed_comments
VSLAM系列原创01讲 | 深入理解ORB关键点提取:原理+代码
VSLAM系列原创02讲 | ORB描述子如何实现旋转不变性?原理+代码
VSLAM系列原创03讲 | 为什么需要ORB特征点均匀化?
VSLAM系列原创04讲 | 四叉树实现ORB特征点均匀化分布:原理+代码
VSLAM系列原创05讲 | 单目初始化中如何进行特征匹配?原理+代码
VSLAM系列原创07讲 | 词袋有什么用?ORB特征点构建BoW是否靠谱?
VSLAM系列原创08讲 | 如何离线训练BoW字典?终于搞懂了!
接上回继续。。。
在线生成词袋向量
师兄:以上是离线生成训练字典的过程。在ORB-SLAM2中,对于新来的一帧图像,我们会利用上面的离线字典给当前图像在线生成词袋向量。具体流程是这样的:
-
第1步:对新来的一帧图像先提取ORB特征点,特征点描述子和离线字典中的一致。
-
第2步:对于每个特征点的描述子,从离线创建好的字典树中自上而下开始寻找自己的位置,从根节点开始,用该描述子和每个节点的描述子计算汉明距离,选择汉明距离最小的节点作为自己所在的节点,一直遍历到叶子。最终把叶子的单词ID和权重等属性赋予这个特征点。见上图。紫色的线表示 一个特征点从根节点到叶子的搜索过程。在树状结构中,这个过程是非常快的。
小白:图中的level up是什么意思?
师兄:可以简单的将level up理解为搜索范围。每个描述子转化为单词后会包含一个属性叫做单词的节点ID(图中的word’s node id),这个节点ID距离叶子的层级就是level up。以后特征匹配的时候,只在该单词的节点ID内部搜索即可。如果这个level up设置比较大,单词的节点ID会比较靠近根节点,那么搜索范围就会扩大,极端的就是在整个字典树里搜索,那肯定相当慢;但是如果这个level up设置的比较小,单词的节点ID会比较靠近叶子,那么很可能搜不到匹配的特征点。还是拿前面国家机构的例子来类比,比如我想在整个国家寻找一个人(单词),这个单词的节点ID就相当于我的搜索范围,是在某个省级范围还是村级范围搜索。如果是省级范围,那搜索效率就很低,如果是在村级范围,搜索是很快,但是如果要找的人是在隔壁村,那就无法搜索到。因此level up要设置为一个合适的值,在ORB-SLAM2里level up=3。
确定一个特征描述子的单词ID、权重、单词所属的节点(距离叶子深度为level up深度的节点)ID ,对应的实现代码见:
/**
* @brief 确定一个特征描述子的单词ID和权重,单词所属的节点(距离叶子为level up深度的节点)ID
* @param[in] feature 特征描述子
* @param[in & out] word_id 单词ID
* @param[in & out] weight 单词权重
* @param[in & out] nid 单词所属的节点(距离叶子为level up深度的节点)ID
* @param[in] levelsup 单词距离叶子的深度
*/
template<class TDescriptor, class F>
void Tem