DBoW2分析整理(理论部分)
1. 简介
DBoW2的github地址为:
https://github.com/dorian3d/DBoW2,
相关的论文文献为:《Bags of Binary Words for Fast Place Recognition in Image Sequences》
文章的主要内容是:字典(vocabulary tree)的建立和图像相似性的计算以及基于此进行的回环检测的策略。
主要步骤:
a. 对大量训练图像使用fast关键点+BRIEF描述子的方法提取特征(也可以选择其他特征如Kintinuous使用的是SURF特征,ORB特征则是结合了FAST特征和BRIEF描述子的特征)
b. 根据一定的策略(K-means++)将这些特征描述子聚类为“单词”,并使用树的形式组织,得到一个vocabulary tree。
c. 将利用vocabulary tree将图像转换为 {单词,权值} 的向量表示
d. 通过计算向量间距离的方式计算图像之间的相似性
2. 二值特征(binary feature)
ORB特征是一种结合了FAST特征和BRIEF描述的一种特征
FAST关键点:是一种角点,选择半径为3的Bresenham圆,选取之上的部分像素点,与初始像素点做灰度比较,找到灰度值相差较大的类角点(corner-like point)。
BRIEF描述子:以Fast关键点为原点。用一个二值向量来表示的,向量中的每一位都是patch中灰度值进行比较的结果,选择固定大小的patch,如长宽均为
S
b
S_{b}
Sb ,则有描述子
B
i
(
p
)
B^{i}(\mathrm{p})
Bi(p)
B
i
(
p
)
=
{
1
i
f
I
(
p
+
a
i
)
<
I
(
p
+
b
i
)
0
otherwise
∀
i
∈
[
1
,
L
b
]
B^{i}(p)=\left\{\begin{array}{l}{1 \quad i f I\left(p+a_{i}\right)<I\left(p+b_{i}\right)} \\ {0 \quad \text { otherwise }}\end{array}\right. \forall i \in\left[1, L_{b}\right]
Bi(p)={1ifI(p+ai)<I(p+bi)0 otherwise ∀i∈[1,Lb]
其中
B
i
(
p
)
B^{i}(\mathrm{p})
Bi(p):BRIEF描述子的第i位
I(·):高斯平滑处理之后的图像的像素的灰度。
a i , b i a_{i}, b_{i} ai,bi:在patch中随机选取的两个坐标,这两个坐标的选取是服从正态分布的,也表示第i个待测点距离patch中心的2-D偏移,范围为 [ − S b 2 … S b 2 ] × [ − S b 2 … S b 2 ] \left[\frac{-S_{b}}{2} \ldots \frac{S_{b}}{2}\right] \times\left[\frac{-S_{b}}{2} \dots \frac{S_{b}}{2}\right] [2−Sb…2Sb]×[2−Sb…2Sb]
L b L_{b} Lb:描述子长度(DBoW2取 L b L_{b} Lb为256, S b S_{b} Sb为48)
BRIEF描述子是一个长度为256的二进制串,使用BRIEF描述子最主要的优势是由于它的描述子是二值的,因此可以利用异或(xor)快速计算和比较。
3. 建立Vocabulary tree/图像数据的建立
image database由一个多级的词包(hierarchical bag of words)(实际上是一棵词树vocabulary tree)以及直接索引(direct index)和逆向索引(inverse index)构成。下面上图:
Remark1: 图中的树能够容纳 k d {k^d} kd个单词。组织成树的样子?一个原因在于它建立了节点之间的“父子”关系,父节点下面的子节点相似度更高。假如新来了一个节点,想要确定它和已知的节点中哪个最为相似,使用穷举法需要比较 k d {k^d} kd次;利用vocabulary tree,我们只需要从根节点开始逐层地和各个节点对比,选出相似度最高的那个节点下方的分支作为新的分支继续做对比,则只需比较k*d次。
Remark2: 正向索引,即中间层中每一节点下存储着该节点的索引值和对应的某一张图像的特征。 正向索引可以加速特征之间的匹配,因为在图像检索的过程中,通常也是先经过BoW或者其他检索算法检索出最相似的N张图像,然后再通过特征匹配(暴力匹配)的方式确定最相似的一张或几张图像。
使用正向索引时需要指定一个层数,即在与该层下的某个节点所包含的特征进行特征匹配,这同样也大大降低了特征匹配的规模,这种方法在ORB-SLAM中也用于特征匹配的加速,如跟踪时的关键帧模型等。
Remark3:反向索引即倒排文件系统,即每个叶子结点都有一个关联的文本文档,里面存储着当前节点的索引值和落在该节点下的图像索引值。反向索引的作用和倒排文档是一致的,加速图像的匹配过程,当query图像来时,只要和对应节点下图像计算相似性即可,这就大大缩小了待匹配图像的规模。
bag-of-words使用 视觉词表(visual vocabulary)将图像转化为一个稀疏的数值向量 ,visual vocabulary可以离线生成,将训练集图像(training)的描述空间(descriptor space)离散成W个视觉词汇(visual words)。
建立这个vocabulary tree可以分为三步:
a. 从训练图像中离线提取descriptor
b. 对提取到的descriptors进行聚类,聚类方法是从根节点开始使用k-mean++生成种子,得到了vocabulary tree的第一层,共k个节点
c. 接下来的每一层都进行与第一步相同的操作,聚类L层,最终得到W个叶节点。
Remark: 节点关联的直接索引,word关联的倒排索引
补充:1、K-means算法
step1. 在样本集中指定k个初始化中心a1,a2,…,ak
step2. 对于每个样本Xi,使用某种距离定义计算其与各个初始化中心的距离,并且选择距离最小的作为其归属子集
step3. 对于k个子集,计算其样本平均值作为该子集新的中心ak
step4. 重复step2-3,直至满足终止条件(迭代次数/中心变化大小等)
补充:2、K-means++算法
Kmeans++算法是基于Kmeans改进而来,主要改进点在于中心点的初始化上,不像原始版本算法的随机生成,它通过一些策略使得k个初始中心点彼此间距离尽量地远,以期获得这些中心点具有更好的代表性,有利于后面的分类操作的效果。其步骤如下所示:
step1. 从n个样本中随机选取一个点作为第一个中心点;
step2. 计算样本中每个点和距离它最近的中心点之间的距离Di,根据策略选择新的中心点
step3. 重复step2直至得到k个中心点
4. 利用Vocabulary tree计算图像相似度
4.1 TF-IDF
每一个word都会根据其在训练集中的关联性得到一个权重值。但是那些出现频率非常高的words,显然它们的辨识度很低,因此会相应降低它们的权重。加权方法使用的是TF-IDF(term frequency - inverse document frequency)。
建立好vocabulary tree后,两幅图像如何利用它来计算相似度呢?
a. 首先将图像转换为单词的表示形式,基本操作为:提取得到图像的特征,然后对每个特征计算得到它的单词归属。这样图像就变成了一个类似于
(
w
1
,
w
2
,
…
,
w
n
)
\left({w}_{1}, {w}_{2}, \dots, {w}_{n}\right)
(w1,w2,…,wn)的序列,其中
w
n
{w}_{n}
wn为单词的索引。
b. 不同的单词重要程度不一样,DBoW2中使用TF-IDF
Remark:TF-IDF,这是一种标准的计算权重的方法,它的计算方法为:
t = (word在当前图像出现的次数/当前图像的总词数)*log(整个数据集中的图像数/数据集中出现该word的图像数) 。
字典树在建立过程中,每个叶子也就是每个 word 记录了该 word 在所有的训练图像中出现的频率,出现的频率越高,表示这个 word 的区分度越小,频率的计算公式如下:
i
d
f
(
i
)
=
log
N
n
i
i d f(i)=\log \frac{N}{n_{i}}
idf(i)=logniN
4.2 在线更新字典树
当在字典树中需要插入一幅新图像
I
t
I_t
It,在图像中提取的特征描述子按照 Hamming 距离从字典树的根部节点开始逐级向下到达叶子节点,可以计算每个叶子节点也就是每个 word 在图像
I
t
I_t
It 中的出现频率
t
f
(
i
,
I
t
)
=
n
i
I
t
n
I
t
t f\left(i, I_{t}\right)=\frac{n_{i I_{t}}}{n_{I_{t}}}
tf(i,It)=nItniIt
n
i
I
t
n_{i I_{t}}
niIt表示word在图像中出现的次数
n
I
t
n_{I_{t}}
nIt表示图像中描述子的总数
在树构建的过程中每个叶子节点存储了 inverse index,存储了到达叶子节点的图像
I
t
I_t
It 的id和word在图像
I
t
I_t
It 描述vector中第i维的值
v
t
i
=
t
f
(
i
,
I
t
)
×
i
d
f
(
i
)
v_{t}^{i}=t f\left(i, I_{t}\right) \times i d f(i)
vti=tf(i,It)×idf(i)
对于一幅图像所有的描述子,做上述操作,可以得到每个 word 的值,将这些值构成图像的描述向量
V
t
V_t
Vt
4.3 计算图像的相似度
增加了权值后,一幅图像A利用字典转换后得到的序列为
(序列由一个个的
t
f
−
i
d
f
tf-idf
tf−idf 组成):
V
t
=
{
(
w
1
,
weight
)
,
(
w
2
,
weight
)
,
…
,
(
w
n
,
weight
n
)
}
V_{t}=\left\{\left(\mathrm{w}_{1}, \text { weight }\right),\left(\mathrm{w}_{2}, \text { weight }\right), \ldots,\left(\mathrm{w}_{n}, \text {weight}_{n}\right)\right\}
Vt={(w1, weight ),(w2, weight ),…,(wn,weightn)}
我们把它看做向量
V
a
V_a
Va ,则图像B可转换得到向量
V
b
V_b
Vb ,计算图像间相似性问题转换为计算两个向量之间差异的问题。类似于定义范数,计算差异的标准和方式有很多,DBoW2中使用了如下的计算形式:
s
(
v
1
,
v
2
)
=
1
−
1
2
∣
v
1
∣
v
1
∣
−
v
2
∣
v
1
∣
∣
s\left(v_{1}, v_{2}\right)=1-\frac{1}{2}\left|\frac{v_{1}}{\left|v_{1}\right|}-\frac{v_{2}}{\left|v_{1}\right|}\right|
s(v1,v2)=1−21∣∣∣∣∣v1∣v1−∣v1∣v2∣∣∣∣
其中,图像越相似得分越高。 字典树除了存储了 inverse index,还存储了 direct index 如上图所示,direct index 方便两幅图像特征搜索,建立特征之间的对应,计算两帧之间的位姿转换。
5 闭环检测算法/数据库查询
Database的访问
在计算相似度时,相似度的大小和字典树、图像等有一定关系,这里采用归一化的方式,消除这两种因素的影响,归一化相似度计算公式如下:
η
(
v
t
,
v
t
j
)
=
S
(
v
t
,
v
t
j
)
S
(
v
t
,
v
t
−
Δ
t
)
\eta\left(v_{t}, v_{t_{j}}\right)=\frac{S\left(v_{t}, v_{t_{j}}\right)}{S\left(v_{t}, v_{t-\Delta t}\right)}
η(vt,vtj)=S(vt,vt−Δt)S(vt,vtj)
其中
V
t
−
Δ
t
\mathcal{V}_{t-\Delta t}
Vt−Δt 表示上一帧图像,上式含义是上一帧图像和当前帧图像是最为相似度的,用和上一帧图像计算的相似度来归一化和字典树中图像计算的相似度。
当
s
(
v
t
,
v
t
−
Δ
t
)
s\left(v_{t}, v_{t-\Delta t}\right)
s(vt,vt−Δt) 较小时(机器人做旋转时),会把总体的得分拉的很高,论文里面剔除这种因素,选取阈值 α,当前帧和上一帧图像相似度小于 α 时不做回环检测。
6 参考:
https://blog.csdn.net/lwx309025167/article/details/80524020
http://www.itdaan.com/blog/2018/06/01/c42442f71edc3142aa18ddac4e01406.html
http://www.itdaan.com/blog/2018/06/04/e6c937a9d9383189a26ebc686a8a05c1.html
http://www.cnblogs.com/mafuqiang/p/7161293.html
https://blog.csdn.net/fuxingyin/article/details/51489160
paper:
Bags of Binary Words for Fast Place Recognition in Image Sequences