news 2026/7/4 3:56:10

ORB-SLAM3 ComputeBoW

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ORB-SLAM3 ComputeBoW

词袋向量的计算原理,可以理解为一个“构建视觉词典”“用词典描述图像”的过程。

它的核心思想是:把图像中提取的“特征点”类比成文章中的“单词”,通过统计这些“单词”在图像中出现的频率,将一张复杂的图像转换成一个数值向量

这个计算过程主要分为两大步:离线构建词典在线计算向量

🏗️ 第一步:离线构建“视觉词典”

在系统运行前,需要先利用大量图片,通过聚类算法构建一棵“词汇树”(Vocabulary Tree),作为所有图像的通用词典。

  1. 提取特征:从大量不同的场景图片中提取ORB特征点及其描述子(Descriptors)。

  2. 构建词汇树(K-means聚类):将所有提取到的特征描述子,通过K-means++算法进行层层聚类。

    • 第一层:将所有特征点聚成k类,得到k个聚类中心,这些中心就是树第一层的节点。

    • 下一层:对第一层的每一个节点(类),再将其内部的特征点聚成k类,生成下一层的节点。

    • 重复:这个过程重复d层,最终得到一棵深度为d、每个节点有k个分支的k-d树。

  3. 定义“单词”:这棵词汇树的叶子节点(最底层的节点)就被定义为一个个的“视觉单词”(Visual Word)。整个词典总共可以表示k^d个不同的视觉单词。(d层,每一层上有K个节点,第d层上共k^d个节点,也就是k^d个单词)

例如,在ORB-SLAM3中,词典的参数为k=10d=6,因此可以表达多达10^6 = 1,000,000个不同的视觉单词。

📝 第二步:在线计算图像的“词袋向量”

当系统运行时,对于每一帧新图像(关键帧),都会进行以下操作来生成词袋向量:

  1. 提取特征:提取当前图像的ORB特征点和描述子。

  2. 寻找单词:对于当前图像中的每一个特征点描述子,从词汇树的根节点开始(遍历词典/词汇树的每一层),计算它与当前层所有k个节点的距离,选择距离最近的节点进入下一层,直到抵达一个叶子节点。这个叶子节点的索引,就是该特征点对应的视觉单词ID(Word ID)。(当前帧中m个特征点描述子,每个描述子可以查词典得到一个world ID,一个n个world ID ,多个特征点描述子可能查到同一个world ID)

  3. 统计词频(TF):遍历完当前帧所有特征点后,统计每个视觉单词ID在这张图像中出现的次数(Term Frequency, TF)。(n个world ID ,计算每一个world ID 的次数)

  4. 计算权重(TF-IDF):为每个单词的频数乘以一个权重。这个权重由TF-IDF方案决定。

    • TF (词频):即上一步统计的单词在当前图像中出现的频率。

    • IDF (逆文档频率):在离线构建词典时就已算好。它衡量(所有训练图片中的每一个)一个单词在所有训练图片中出现的频繁程度。如果一个单词在越多的图片中出现,说明它越普遍,区分度越低,其IDF值就越小。

    • 最终权重单词权重 = TF × IDF。(这个权重值就是TF-IDF

最终,一张图像会被表示为一个稀疏的向量(mBowVec),其中包含了这张图像里出现的所有单词ID及其对应的TF-IDF权重。(mBowVec 中保存的是 world ID 和 其对应的TF-IDF权重

⚡ 加速索引:正向与逆向索引

为了加速后续的匹配和检索,ORB-SLAM3还会构建两种索引:

  • 逆向索引(Inverse Index):以“单词”为 key,记录包含该单词的所有图像的列表。在闭环检测时,可以通过当前帧的单词,快速找到所有与之有共同单词的历史关键帧。(包含有某一个特征点的所有关键帧)

  • 正向索引(Direct Index):以“图像”为 key,记录该图像中,每个词汇树节点下有哪些特征点。在特征匹配时,可以只对两帧图像中属于同一节点的特征点进行匹配,大大缩小了搜索范围。(某一个关键帧中包含的所有特征点)

💎 总结

词袋向量的计算,本质上是将图像特征(ORB描述子)通过离线构建的词汇树(Vocabulary Tree)量化成离散的视觉单词(Visual Word),再统计这些单词的频率并用TF-IDF加权,最终形成一个可用于高效相似度计算的稀疏向量

补充:

mBowVec的维度在概念上等同于整个视觉词典的大小,但在实际存储时,它是一个仅包含非零元素的稀疏向量

具体可以从以下几个方面来理解:

📐 概念维度:等同于词典大小

视觉词典(Vocabulary)是通过离线训练得到的,它包含了数量庞大的“视觉单词”(Visual Word)。mBowVec在概念上是一个维度为N的向量,这个N就是词典中单词的总数。

在ORB-SLAM3中,这个N的典型值是1,000,000(即10^6)。这个数字来源于词典构建时的参数:一个深度为6层、每层有10个分支的词汇树(k=10, d=6),其叶子节点(即单词)总数就是10^6

🗺️ 实际存储:一个“稀疏”的映射表

虽然概念上维度高达百万,但一张图像只包含有限个特征点(例如几百个),因此它只会命中词典中极少数的单词。如果用一个长度为1,000,000的数组来存储,其中绝大部分元素都是0,会造成巨大的内存浪费。

因此,mBowVec的实际类型是DBoW2::BowVector,它被定义为一个std::map<WordId, WordValue>

  • WordId:是命中单词的ID(键)。

  • WordValue:是该单词对应的TF-IDF 权重值(值)。

这种设计意味着mBowVec实际大小(size()等于该图像中非零权重单词的数量,通常只有几百。它只存储有意义的“单词-权重”对,忽略所有零值,是一种非常高效的存储方式。

💎 总结

  • 概念上mBowVec的维度是词典的大小,通常为1,000,000

  • 实际上,它作为一个std::map,其元素个数等于图像中有效特征点对应的单词数量,通常为几百个

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/4 3:56:07

计算机Java毕设实战-商超智能折扣促销与结算管理系统的设计与实现 基于 SpringBoot 的商场促销活动与价格折扣系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/7/4 3:50:35

批量压缩图片还在用在线工具?这款648KB小软件,画质不变体积暴减

批量压缩、批量水印、自定义参数&#xff0c;PicSizer 可能是你用过的最轻量的图片压缩工具 前几天要在公司内网发一份产品介绍&#xff0c;里面有二十多张产品图片&#xff0c;每张都有800KB-1MB&#xff0c;整个文档传不上去。我第一反应是想用在线图片压缩网站&#xff0c;但…

作者头像 李华
网站建设 2026/7/4 3:50:33

C++语言基础1:作用域解析运算符“::”详细讲解

在 C 中&#xff0c;“::”被称为 作用域解析运算符&#xff08;Scope Resolution Operator&#xff09;。它是 C 语言中非常核心的一个操作符&#xff0c;用于明确指定某个标识符&#xff08;如变量、函数、类、命名空间等&#xff09;所属的作用域。一、基本语法与含义A::B表…

作者头像 李华