本文最后更新于:2026年7月9日 上午

回环检测是 SLAM 区别于纯里程计的关键——只有识别出"我以前来过这里",才能消除累积漂移、得到全局一致的地图。词袋(Bag-of-Words, BoW)是它事实上的标配前端。这篇梳理 BoW 的算法原理、核心推导与几个常见误区。

图像检索问题

SLAM 跑久了会有累积漂移:每帧位姿估计都有微小误差,误差一路累加,几千帧后能偏出几米。消除漂移的办法就是回环检测——发现"当前帧和很久以前某一帧拍的是同一个地方",于是能把两端之间的轨迹误差摊平。没有回环,SLAM 就只是个"会漂移的里程计"。

回环检测的本质,其实是一个图像检索问题:给定当前帧,在所有历史关键帧里找出"最像的"那一帧。最朴素的办法是当前帧和每一帧都做特征匹配,但这是 $O(N^2)$ 的,几千关键帧就扛不住。

词袋模型干的就是这件事:把每张图压缩成一个可以快速比对的"视觉词直方图",让秒级在数千帧里找相似帧成为可能。ORB-SLAM、VINS 等系统的回环前端都用它。

图像相似度

词袋要加速的是"判定两张图是否同一场景"这个原子问题,先把它讲清。

给定图 A(N 个特征)和图 B(M 个特征),判定它们是不是同一场景,分三步:

  • 描述子匹配:对 A 的每个特征,在 B 里找描述子最近的特征。但仅靠"最近"远远不够——重复纹理、弱纹理会让大量 patch 长得很像,错配一堆。
  • Lowe 比率测试:对最近邻 $nn_1$ 和次近邻 $nn_2$,算 $\text{ratio}=\text{dist}(a,nn_1)/\text{dist}(a,nn_2)$,超过阈值(0.7~0.8)就丢。直觉是:如果一个特征在 B 里有两个候选"一样像",说明它没判别性(比如一面墙上相同的窗户),这种匹配不可靠。
  • 几何一致性检验(RANSAC):这是判定的本质。两张同一静态场景的图,所有正确匹配必须服从同一个几何变换——一般 3D 场景是对极约束 $\mathbf{x}_B^\top F\,\mathbf{x}_A=0$(基础矩阵 F),错误匹配则是随机散落、不服从任何单一变换的。RANSAC 反复采样最小点集估 F,数"满足约束的内点数",内点够多就判同场景。

这里有个反直觉但极其关键的点:判定同场景的标准是"存在一个能解释大量匹配的统一几何模型",而不是匹配的绝对数量。一面满是相同窗户的墙,描述子能匹配上千个,但它们不服从单一几何(窗户互相错配),RANSAC 内点反而少,不会误判。这一条是整个回环检测最根本的判据,后面会反复用到。

这套"匹配 + 比率 + RANSAC"对一对图就要 $O(N\cdot M)$,对当前帧 vs 全部历史帧跑就是 $O(N^2)$。词袋的角色,就是把每张图压成直方图、秒级筛出少数候选帧,只对候选跑这套原子算法。 它是"可扩展性"那一层;几何一致性才是"是否同场景"的本质。

词袋

词袋借鉴文本检索:一篇文档 = 词的无序集合,只统计词频、忽略语法顺序。同理,一张图像 = "视觉单词"的无序集合。

  • 视觉词 = 特征描述子空间里聚类后的一个聚类中心;
  • 图像 → 提特征 → 每个描述子映射到最近的视觉词 → 统计词频 → 得到 BoW 向量(词直方图);
  • 两张图的相似度 = 两个 BoW 向量的距离。

"无序"是关键:BoW 不关心特征在图里的位置,只关心"出现了哪些词、各出现几次"。这一丢,让两张视角不同但场景一样的图能匹配上。

什么是“词”

这里有个常见混淆:词典是 kmeans 聚类出来的,那所谓"一个词",到底是一个簇里那十来个训练特征,还是当前帧里的某个特征

答案是都不是。必须分清三个角色:

  • 训练描述子:离线训练集里的特征,每个词大约十来个,kmeans 算完聚类中心后就被丢弃了——它们是熬出中心用的食材。
  • 视觉词 = 聚类中心:训练描述子聚出来的那个原型描述子,存进词典,全程复用,共百万个,固定不变。
  • 当前帧特征:在线时当前图提的特征,它会被分配到(贴标签给)最近的那个词,但它本身不是词。

所以词是聚类中心本身、一个原型描述子,和任何具体图像无关、离线存盘。同一个词,在不同图像里对应的可能是物理上完全不同的 patch——只要它们"长得像这个原型",就贴同一个词标签。理解这一点,后面的视角不变性(同一物体不同角度贴同词)和感知偏差(不同物体贴同词造成假阳)就都顺了:它们其实是同一枚硬币的两面,根源都是 BoW 丢掉了空间信息。

视觉词典

离线训练时,用大量描述子做 K-means 聚类,K 个聚类中心就是 K 个视觉词。这一步可以写成明确的优化问题:给定描述子池,找 K 个中心和每个点的归属,使所有点到其所属中心的距离平方和最小:

$$ J=\sum_{j=1}^{n}\big\|x_j-c_{r_j}\big\|^2\;\longrightarrow\;\min_{\{c_k\},\{r_j\}} $$

(其中 $r_j\in\{1,\dots,K\}$ 是点 j 被分配到的簇编号,$c_{r_j}$ 是它的归属中心;记 $S_k=\{j:r_j=k\}$ 为分到簇 k 的样本下标集。)

K-means(Lloyd 算法)解这个问题用的是坐标下降,交替固定一组优化另一组:

  • 固定中心,优化归属:每个点归到最近的中心。这一步显然不增 $J$。
  • 固定归属,优化中心:中心取该簇所有点的均值。为什么是均值?对 $J$ 里只与 $c_k$ 有关的项求导置零:
$$ \frac{\partial}{\partial c_k}\sum_{j:\,r_j=k}\|x_j-c_k\|^2=-2\sum_{j:\,r_j=k}(x_j-c_k)\stackrel{!}{=}0\;\Longrightarrow\;c_k=\frac{1}{|S_k|}\sum_{j\in S_k}x_j $$

所以均值是固定归属下的最优中心(最小二乘的闭式解)。两步都单调不增 $J$,而 $J\ge0$ 有下界,所以必收敛。但要清楚:这是解非凸问题的坐标下降,只收敛到局部最优,对初始化敏感——这也是后面词典泛化问题的根源之一。

K 怎么定

一个常见误区是把 K 当成经验值来调,实际上 BoW 的 K 不是用统计方法估出来的,它是个工程参数:它由分支因子 $k$ 和深度 $d$ 决定,总词数 $K=k^d$。

通用机器学习里定 K 的手肘法、轮廓系数、Gap statistic 那些,前提是"K 是数据真实有几个簇";而 BoW 把 K 当量化粒度(把巨大的描述子空间切成多少个格子),要靠下游 precision-recall 曲线评判。所以主流 BoW 不用那些方法。

那 K 的大小怎么权衡?它的两头坏方向是相反的:

  • K 太小(词少、量化粗):不同物体落到同一个词 → 判别力低 → 假阳多;而且每个词出现在很多图里,IDF 被压低,雪上加霜。
  • K 太大(词多、量化细):相似的 patch 落到不同词 → 漏检多、视角不变性下降;词典文件大、加载慢、每个词训练样本还不足。

有个直觉锚点:典型 ORB 训练集大约千万级描述子,配百万词,平均每词十来个样本,既不空也不挤。这背后其实有个软统计下限——聚类中心是 $n$ 个样本的均值,逐维抖动约 $\sigma/\sqrt{n}$;$n$ 大于 5~10 时抖动远小于词间距,中心才稳。所以"每词十来个样本"不是拍脑袋,而是卡在"中心估计刚够稳"的统计下限附近。但要注意:真实每词样本数是长尾分布(少数常见纹理词上千样本,大量稀有词只有 0~2 个),"十来个"只是被头部拉高的均值;最终拍板 K 的还是 benchmark 上的 PR 曲线。

分层词典树

百万个词平铺,查一个描述子要和百万个中心比距离,太慢。DBoW2 采用 Nister & Stewenius 2006 的递归 K-means 造一棵树:根节点是全部描述子,做 K-means 分成 $k$ 簇;每个子节点再各自 K-means 分 $k$ 簇;递归 $d$ 层到叶子,叶子就是视觉词,共 $K=k^d$ 个。典型 $k=10,d=6$ 就是百万词。

查询时从根出发,每层只在 $k$ 个兄弟里选最近的一个往下走,走 $d$ 层到叶子。每层 $k$ 次距离计算,总共 $d\cdot k$ 次。对百万词来说,暴力是 $10^6$ 次,树只要 60 次,加速上万倍。

这个加速是有代价的:树是贪心搜索,每层选定一个分支就不回溯,所以找到的不一定是全局最近的叶子,只是"沿贪心路径最近的叶"。这是用精度换速度。实测发现,深度 3(千词)时贪心有 43.7% 的情况选的不是全局最近叶——但错的时候,贪心叶只比最优远 1.15 倍,几乎总落在"最近几个"里。它是个近似最近邻,不是精确的。对 BoW 这够用,原因后面讲。

TF-IDF

不是所有词同等重要。每张图都有的词(天空、地面纹理)判别性低;罕见独特的词判别性高。BoW 用 TF-IDF 体现这一点。

TF 是词频,衡量"这个词对本图多重要":

$$ \mathrm{TF}_i=\frac{\text{词 }i\text{ 在当前图的出现次数 }\eta_i}{\text{当前图总词数 }N} $$

IDF 是逆文档频率,衡量"这个词整体上多判别",这里有个漂亮的推导。设训练集共 $D$ 张图,其中 $n_i$ 张含词 $i$,词 $i$ 出现在一张图里的频率估计为 $p_i=n_i/D$。信息论里,概率为 $p$ 的事件的自信息(surprise)定义为 $-\log p$,越罕见信息量越大。把"词 $i$ 出现在一张图里"当事件,它的自信息就是:

$$ -\log p_i=-\log\frac{n_i}{D}=\log\frac{D}{n_i}=\mathrm{IDF}_i $$

所以 IDF 就是词的自信息。到处都有的词 $p_i\to1$,自信息趋于 0,权重几乎为 0;罕见词自信息大,权重高。这就是"为什么是 log"——它精确度量了"这个词能带来多少判别信息(比特)"。BoW 分量就是两者相乘:

$$ \tilde v_i=\mathrm{TF}_i\cdot\mathrm{IDF}_i=\frac{\eta_i}{N}\cdot\log\frac{D}{n_i} $$

这里可以接另一个视角:词频分布是长尾的,IDF 正是它的标准校正。所谓长尾,就是"少数项极常见、大量项各罕见、且尾部集体重要"的分布形态,自然语言词频服从的 Zipf 律就是经典长尾。BoW 里至少三处长尾:每词样本数长尾(常见纹理词上千、稀有词近乎为零)、词频 TF 长尾、描述子密度长尾。如果不加 IDF,头部词(天空)就因频次高而主导相似度,凡是有天空的图都判相似,假阳爆炸;IDF 自动压低头部、抬高尾部。所以"IDF=自信息"换个角度看,就是"IDF 是为抵消长尾频次分布而生的重加权"。以一个四词小例子手算,有 IDF 时同/异场景的相似度间隔是 0.59,去掉 IDF 只剩 0.10,基本分不开——IDF 把判别间隔拉开了将近六倍。

相似度评分

两帧的 BoW 向量 $v_a,v_b$ 做 L1 归一化(分量之和为 1)。DBoW2 的相似度评分是:

$$ s(a,b)=1-\tfrac{1}{2}\|v_a-v_b\|_1 $$

这式子看着像随手拼的,实际上它严格等价于直方图交集。推导很短但对每一维利用恒等式 $|a-b|=a+b-2\min(a,b)$(自己验证:若 $a\ge b$,左边 $a-b$,右边 $a+b-2b=a-b$):

$$ \|v_a-v_b\|_1=\sum_i\big(v_{a,i}+v_{b,i}-2\min(v_{a,i},v_{b,i})\big)=2-2\sum_i\min(v_{a,i},v_{b,i}) $$

最后一步用了 L1 归一化 $\sum_i v_{a,i}=\sum_i v_{b,i}=1$。代回评分:

$$ s(a,b)=1-\tfrac12\|v_a-v_b\|_1=\sum_i\min(v_{a,i},v_{b,i}) $$

右边正是经典的直方图交集——两个直方图的重叠面积。这不是巧合:L1 归一化加 L1 距离的组合,数学上必然导出交集形式。取值天然落在 [0,1]:两向量相同得 1,没有共同词得 0。

检索复杂度

表面看复杂度很高:如果真拿当前帧和每个历史帧都算一遍交集,是 $O(M\cdot K)$($M$ 帧数、$K$ 词数),长跑几万帧就扛不住。

实际上倒排索引让它不必逐个比。倒排索引的结构是:每个词挂一个链表,记录"哪些图含这个词、权重多少"。查询时,当前帧只查自己的非零词(几百个),对每个非零词遍历它的倒排表,把 $\min(v_{q,i},v_{d,i})$ 累加到对应历史帧的得分上。只有和当前帧共享至少一个词的帧才会被碰到,共享 0 个词的帧(绝大多数不在同一位置的帧)根本不进循环——它们交集本来就是 0,没必要比。

复杂度从 $O(M\cdot K)$ 降到 $O(\sum_{i\in W_q}|\text{post}(i)|)$,这就是毫秒级检索的来源。而且 TF-IDF 在这里还有个隐藏加速:判别性强(IDF 大、权重高)的词恰好是稀有词,含它的帧少、倒排表短、查得快——“最重要的词恰好查得最快”。

量化误差

贪心树既然会选错(前面测过 43.7% 选的不是全局最近叶),这种量化误差会不会破坏 BoW 判定同场景的能力?要讲清这个,得先把"误差"拆成两条正交的轴,否则很容易混。

第一条轴:打分时距离被丢弃(硬分配)。 BoW 是硬分配word = argmin distance,这个 argmin 只留下词 id,把距离数值扔了。一个特征无论落得刚好、略偏还是离谱,只要落进同一个词,对 BoW 向量的贡献一模一样——都只是给那个词 +1。所以"错 1.1 倍"和"错 8 倍"的特征,在打分里完全等价;误差大小不进打分。

第二条轴:匹配能否成立,取决于"同 cell 碰撞",与误差大小无关。 这才是关键,也是最容易想偏的地方。同一个真实 patch P,在图 A、图 B 各产生一个描述子 $x_A,x_B$,因视角噪声它们很接近但不等。这个 patch 贡献相似度的条件是一个碰撞门:$x_A,x_B$ 被量化进**同一个 cell(同一个词)**才贡献 +1,分到不同词就贡献 0。

这里必须分清两套不同的"误差":“贪心误差”(greedy 叶 vs flat-NN 叶)衡量的是"树作为最近邻搜索工具准不准",44% 指的就是它;“碰撞一致性”($x_A,x_B$ 是否落进同一 cell)才是决定匹配成不成立的。这两条轴正交。$x_A,x_B$ 落进同一 cell 的条件是:在树的每一层它们都选了同一个子节点,也就是没有任何一层的边界把它们劈开。对很接近的两个点,这几乎总成立(除非恰好有边界从中间穿过)。所以贪心树能让 BoW 工作,靠的是对相近输入给出一致划分(局部一致性),而不是"贪心找到的叶离 flat-NN 近"——flat-NN 量化器一样有边界、一样会把跨边界的相近点劈开;贪心树就算每层都"错",只要对 $x_A,x_B$ 错得一致(走同一条下行路径),照样碰撞、照样贡献。

换句话说,一个 patch 贡献相似度只有三种情形:(a) 两个描述子都进了"正常"的 cell;(b) 两个描述子都进了同一个"非正常"的 cell(都"错到同一个词");© 两个描述子进了不同的 cell(跨了边界)。(a)(b) 都贡献,© 才丢失。那个词是不是 flat-NN 会选的,根本不影响是否贡献——所以前面那个"44% 贪心误差"对匹配其实是个红鲱鱼。

那区分同/异场景的信号从哪来?来自碰撞数量的差:同一场景共享几百个真实 patch,大多数 patch 的 $x_A,x_B$ 都落进同一 cell,直方图高度重叠,交集高;不同场景没有共享 patch,只有共有的背景词(天空)碰撞,交集低。信号来自同 cell 碰撞的数量差,而不是误差大小

可以用一个实验验证"碰撞门"这件事本身:给词典中心逐步加噪声(破坏量化器与数据的对齐),固定一对同场景图和一张异场景图,看相似度交集怎么变。结果是

中心噪声(误差大小) 同场景交集 异场景交集 判定间隔(信号)
0(正常词典) 0.638 0.184 0.454
1.0 0.660 0.336 0.324
2.0 0.798 0.656 0.142
5.0 0.970 0.838 0.132

噪声一大,量化器退化成接近随机分桶,所有图的直方图都往均匀分布靠拢,同/异场景的交集双双膨胀、往一块凑,判定间隔从 0.45 塌到 0.13,分不开了。这反向印证:BoW 能工作靠的是量化器把相近 patch 一致地分到同一 cell、把不同 patch 分开;一旦这种数据对齐被破坏,判定信号就没了。

那如果真想让误差大小进打分呢?有个变体叫软分配(soft assignment,Philbin 2007):一个特征的票不全投给最近词,而是按距离用高斯核分散投给最近的 k 个词。自信的特征(接近)票集中,模棱两可的特征(离谱)票摊开。这样误差大小才真正进打分,精度更高,但每特征要查 k 个词、更慢。DBoW2 默认用硬分配,速度优先。

还有一点要补:BoW 把距离扔了,但几何验证在后面把它捡回来。回环的最终确认阶段用原始描述子的真实 Hamming 距离做特征匹配(不是 BoW 词),自信的算内点、模棱两可的被比率测试或 RANSAC 剔除。所以"同/异场景"的最终定性,是建立在带距离信息的精确匹配上的,BoW 只是那个"丢距离、图快"的粗筛前端。理清这条,整个 BoW 的定位就清楚了。

部署流程

这里有个常见疑问:字典是数据训练出来的,判同源又要用字典,可设备运行时还在不断采集新数据,这不是鸡生蛋吗?

其实没有循环依赖,关键在于词典有两种角色,运行时绝不混:

  • 码本(codebook,冻结):视觉词的定义(聚类中心加 IDF),离线训练一次、出厂带上,运行时加载后全程不变。设备的新数据不进这里。
  • 数据库 / 倒排索引(growing):存"哪些历史关键帧含哪些词",运行时由设备自己采集的关键帧持续填充

设备的新数据喂的是数据库,不是码本。码本(蛋)在开跑前就冻结好了,数据库(鸡的活)在线增长。回环检测是"当前帧 vs 本次运行中更早采集的历史帧",用的是出厂前训好、全程不变的固定词表。ORB-SLAM 里这俩分得很清楚:ORBVocabulary 是冻结码本,KeyFrameDatabase 是在线倒排索引。开跑那一刻数据库是空的、没东西可比、没回环,这很正常——回环只在"去过又回来"之后才有意义,先老老实实积累关键帧就行。

冷启动与词典泛化

顺带说清"冷启动"这个概念,因为它和上面相关。冷启动就是系统刚开跑、还没积累数据的时期,“巧妇难为无米之炊”。SLAM 里其实有两个层面的冷启动别混:

  • 数据库冷启动:一次 run 刚开始,倒排索引空,没历史帧可比。这个自然解决,跑一会儿就有历史帧了。
  • 词典冷启动:场景专属词典(在该场景数据上训出来的,更贴合)需要该场景的数据来训,可刚部署时还没有 → 开跑初期词典贴合度差、性能瘸。这就是"场景专属词典更贴合但冷启动差"的准确含义。

所以工程上有三种选择:用通用词典(ORB-SLAM 默认,开箱即用但贴合度一般)、用场景专属词典(部署前先勘测采集数据训好,贴合但费事)、或在线增量词典(边跑边加词,兼顾开跑和场景适应)。ORB-SLAM 选了第一种,牺牲一点贴合度换开箱即用。

通用词典在陌生场景判别力会掉(kmeans 收敛到训练集的局部最优,词不贴合新场景),这是 BoW 的固有短板,也是后来学习型方法(NetVLAD 等)进场的切入点。

工程实现

把几个反复出现的名词收束一下。

ORB(Oriented FAST and Rotated BRIEF)= 一个检测器加一个描述子。FAST 找关键点在哪,ORB 给它补了方向(强度质心朝向)和尺度(图像金字塔),所以旋转尺度不变;rBRIEF 在 patch 里比 256 对像素亮度、每对"左小于右则该位为 1",输出 256 位 0/1 串作为描述子。进 BoW 的是描述子那 256 bit,不是检测器的几何信息。256 bit 等于 32 字节(一位就是一位 0/1,八位打包成一字节),不是 256 字节,这俩容易混。

比两个 ORB 描述子用 Hamming 距离:两条等长二进制串"对应位不同的位置数",计算就是 XOR 后数 1(popcount),是整型单周期硬件指令,比 SIFT 的浮点欧氏距离快十倍左右。还有个漂亮事实:二值向量下欧氏距离的平方就等于 Hamming 距离,两者单调等价,但 Hamming 更省。

DBoW2 用的是二值描述子,所以建词典树时不能像浮点那样取算术均值——它取的是逐比特多数表决(每个比特位上簇内 1 多取 1、0 多取 0)。这不是随便选的:Hamming 距离逐比特可加,最小化总 Hamming 距离等价于每个比特独立求最优,而对单个比特,最小化绝对偏差和的解是中位数,二值的中位数就是多数表决。这条"二值 → Hamming → 逐比特多数表决"是 DBoW2 能用 ORB 实时建树查询的底层原因。

DBoW2 是把上面整套(分层树 + TF-IDF + 倒排索引 + 时序一致性)工程化的 C++ 库,是 BoW 从理论变成能跑代码的那一层。ORB-SLAM3 是当前视觉/视觉惯性 SLAM 的标杆系统,把 DBoW2 当回环检测和重定位(迷路找回家)的模块装了进去。两者都出自西班牙萨拉戈萨大学 Tardós 组,所以集成得很顺。

DBoW2 的缺陷

DBoW2 这套"手工 ORB + 硬量化 + 无序 bag + 离线词典"的组合很实用,但也有几条结构性短板。其中几条前面散见过,这里集中梳理,并补上几个还没讲的角度:

  • 描述子层:手工 ORB 的天花板。 256 位二进制携带的信息量低于 SIFT 的 128 浮点,更远低于学习描述子。它对大视角(一般 30°–40° 以上)和显著光照变化鲁棒性差——这是回环召回掉的根本原因之一,而瓶颈其实在 ORB,不在 BoW 本身。
  • 量化层:硬分配丢距离、贪心树近似。 就是前面量化误差那节讲的:argmin 把距离扔了(误差大小不进打分),分层 K-means 的贪心下行是近似最近叶(实测深度 3 时约 44% 不选全局最近叶)。
  • 表示层:无序 bag → 感知偏差。 BoW 丢掉所有空间布局换视角不变性,代价就是感知偏差——不同地方只要词分布像就被判同。这是它自己解决不了的,只能靠几何验证兜底。
  • 词典层:离线固定、泛化差、冷启动。 前面冷启动那节讲过:离线大数据训的词典换到没见过的场景判别力会掉,场景专属词典又冷启动差。
  • 语义层:词无"意义"之分。 BoW 把所有 patch 一视同仁(只靠 IDF 加权),分不清"稳定路标"和"天空/动态物体/重复纹理"。动态物(人、车)和季节变化会污染 BoW 向量,而它没法主动忽略。
  • 时序层:本质是单帧检索。 DBoW2 的核心是单帧 BoW 检索,时序一致性只是个后置过滤。但真回环在轨迹上是连续序列的匹配,单帧的判别力天然不够。
  • 工程层:内存与长期运行。 百万词词典约 100MB,长期 SLAM 的倒排索引和关键帧数持续膨胀,旧观测还会随环境变化失效(lifelong SLAM 的痛点)。

这些缺陷不是 DBoW2 实现得不好,而是"手工 BoW"这套范式的固有代价。它们也正是后续工作要逐层修的地方:软分配 / VLAD 修量化,NetVLAD 把聚合做成端到端学习,DINOv2 / AnyLoc 这类基础模型修描述子和视角鲁棒性——但 DBoW2 靠"快、无 GPU、可解释、可在线增量"在工业 SLAM 里仍难替代。

小结

把零散的点串成一条线:SLAM 回环检测本质是图像检索,词袋把每张图压成"视觉词直方图"。离线用分层 K-means 建百万级词典(查询复杂度从 $O(K)$ 降到 $O(d\cdot k)$),在线把图像特征量化成词、用 TF-IDF 加权(IDF 即词的自信息、也是长尾校正)、L1 归一化得 BoW 向量,相似度 $1-\tfrac12\|v_a-v_b\|_1$ 恰好等于直方图交集,靠倒排索引做到毫秒级检索。

但词袋只是粗筛前端:它丢掉空间信息换来速度和视角不变性,代价是感知偏差这种假阳,必须靠几何验证(RANSAC 位姿一致性)加时序一致性来精筛确认——这是"BoW 不可单独完成回环"的核心。而量化误差不进单个匹配的打分(硬分配丢距离),它决定的是碰撞数量、也就是判定信号够不够拉开同/异场景;逐特征的精确距离,最终由几何验证用真实描述子补回来。

理解 BoW,关键是抓住那条贯穿始终的权衡:用丢信息换效率,用聚合统计弥补个体精度的损失,用管线后段的精确匹配给前段的模糊兜底

参考资料

  • D. Gálvez-López and J. D. Tardós, “Bags of Binary Words for Fast Place Recognition in Image Sequences,” IEEE Transactions on Robotics, 2012.(DBoW2)
  • D. Nister and H. Stewenius, “Scalable Recognition with a Vocabulary Tree,” CVPR 2006.
  • E. Rublee et al., “ORB: An efficient alternative to SIFT or SURF,” ICCV 2011.
  • J. Philbin et al., “Object retrieval with large vocabularies and fast spatial matching,” CVPR 2007.(软分配、近似 K-means)
  • C. Campos, R. Elvira, J. J. G. Rodríguez, J. M. M. Montiel, J. D. Tardós, “ORB-SLAM3: An Accurate Open-Source Library for Visual, Visual–Inertial, and Multimap SLAM,” IEEE Transactions on Robotics, 2021.
  • 高翔,《视觉SLAM十四讲:从理论到实践》。


文章链接:
https://www.zywvvd.com/notes/study/SLAM/bag-of-words/bag-of-words/


“觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭”

微信二维码

微信支付

支付宝二维码

支付宝支付

词袋模型 BoW 与 SLAM 回环检测
https://www.zywvvd.com/notes/study/SLAM/bag-of-words/bag-of-words/
作者
Yiwei Zhang
发布于
2026年7月3日
许可协议