视觉词典在SLAM中应用

前言

视觉词典技术是采用视觉Bag-of-word模型的技术。BOW模型最先是信息检索领域常用的文档表示方法,它假定对于一个文档,忽略它的单词顺序和语法、句法等要素,将其仅仅看作是若干个词汇的集合,文档中每个单词的出现都是独立的,不依赖于其它单词是否出现;2003年以来,BOW模型出现在视觉领域,如图像分类、图像检索等,其基本思想:首先提取图像集特征的集合,然后通过聚类的方法聚出若干类,将这些类作为字典,最后每个图像统计字典中words出现的频数作为输出向量,就可以用于后续的分类、检索等操作;然后发展为Vocabulary Tree,它是局部描述符量化和索引的一种高效数据结构,把通过聚类方法聚出的类保存在树结构中。

在SLAM机器人中,SLAM技术是机器人自主移动的基础。机器人的闭环检测问题是机器人SLAM在定位、导航时是否需要更新地图的重要依据,但是移动机器人在同步定位与地图创建时,由于视觉传感器自身的累积误差,无法正确的判断是否发生了闭环响应。现有闭环检测有两种:一是根据估计机器人的位置,看是否与某个位置临近;二是根据图像的外观,看是否与以前的关键帧相似,即视觉词典技术。

视觉词典创建技术是为了根据特定的场景创建视觉词典文件,应用于SLAM机器人。这样SLAM机器人能根据这个生成好的字典文件,进行闭环检测,以达到机器人实时,比较准确的移动。

Vocabulary tree模型

字典树主要是为了降低时间复杂度和创建索引。流程如下:

  1. 对训练图像进行特征提取
  2. 将提取的特征描述进行kmeans聚成K类
  3. 对于上一步的每一个子类,继续kmeans聚类
  4. 重复上步,直到聚类的层数到达L层

最后,聚类结果用树表示,其中叶子节点表示一个word。

ORB特征提取

ORB采用FAST算法找出特征点,用BRIEF算法来计算特征点的描述子。
Python实现:

1
2
3
4
5
import cv2

orb = cv2.ORB_create() #默认提取500个特征点
img = cv2.imread('pic.png', 0)
keypoint, descriptor = orb.detectAndCompute(img, None)

Keypoint:关键点集合
descriptor:描述特征集合

nfeatures:最多提取特征点的数量,默认500
scaleFactor:金字塔图像之间的尺度参数
nlevels:金字塔的层数
edgeThreshold:边缘阈值
firstLevel:第一层的索引值,默认0
WTA_K:BRIEF描述子点对的个数
scoreType:对特征点进行排序的算法
patchSize:计算BRIEF描述子的特征点领域大小

FAST

基本思想:拿一个点和周围的点比较,如果它和其中大部分的点都不一样就认为是特征点。
算法流程如下:

  1. 从图像中选取一个像素点P,首先将它的灰度值设为Ip。
  2. 设定一个阈值t,当两个点的灰度值之差的绝对值大于t时,认为这两个点不同。
  3. 比较像素点P和P周围的16个像素。
  4. 如果16个点中有连续n个点不同,那么它就是一个特征点,n一般设为12。
  5. 一个高效的测试,来快速排除非特征点的点。该测试只检查在位置1、9、5、13的像素,先检查1和9,看是否不同。如果是,再检查5和13。如果是一个特征点,那么4个像素点至少3个不同。
BRIEF

基本思想:在关键点P周围以一定模式选取N个点对,把N个点对的比较结果组合起来作为描述子。
算法流程如下:

  1. 以关键点P为圆心,以d为半径做圆O。
  2. 在圆O内选取N个点对,N为256。(opencv中orb是8维32列)
  3. 比较N个点对,如果大于,设为1,小于,设为0

理想的特征描述子应对光照不敏感,具备尺度一致性,旋转一致性。ORB在计算BRIEF描述子时建立的坐标系是以关键点为圆心,以关键点和取点区域的形心的连线为x轴建立2维坐标系。opencv中orb采用图像金字塔来改善尺度一致性问题。

Kmeans算法

算法流程如下:

  1. 创建k个点做为k个簇的起始质心,通常随机选择。
  2. 分别计算剩下的点到k个簇中心的距离,将这些点划分到距离最小的簇。
  3. 根据聚类结果,重新计算k个簇的中心,计算方法是算术平均值。
  4. 将点按照新的中心重新聚类。
  5. 重复3,4,直到聚类结果不再变化。

Python实现:

1
2
3
4
import cv2

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER,10,1.0)
compactness, labels, centers = cv2.kmeans(data, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)

compactness:每个点到相应聚类中心距离的和
labels:每个聚类中心下的标签数组
centers:聚类中心的数组

data:要聚类的数据,最好np.float32
k:聚成k簇
bestLabels:预设的分类标签,没有的话None
criteria:迭代停止的模式选择,是三个元素组成的元组(type, max_iter, epsilon),迭代精度满足epsilon, 或迭代次数超过max_iter停止。
attempts:重复试验kmeans算法次数,返回最好的一次结果
flags:初始化中心选择

代码实现

https://github.com/itswcg/DBow_Python

----------本文完,感谢您的阅读----------