视觉SLAM:ORB视觉里程计的简单实现(四)

ORB视觉里程计的简单实现之四

更新内容

使用ORB-SLAM2中的均匀分布的ORB特征点提取算法,对原始的特征提取算法进行替换,使得提取的特征点均匀分布在场景中。这样做的好处在于:

  • 1、集中分布的特征点如果某一特征点出现错误的匹配,那么这一特征点周围可能还存在大量的特征点也同样是误匹配,这样的话产生的误差就可能比较大。
  • 2、均匀分布的特征点可以使得计算的空间三维点分布在场景中的各个区域,这样在使用PNP算法计算位姿时,一般不会产生错误的估计。(PNP算法如果使用平面的三维点去对应二维点,很容易计算出错误的位姿,这也就是均匀分布的好处)

均匀分布的ORB算法介绍

使用我在以前论文中的描述做简单的说明:

  • 原始的ORB特征提取算法直接对整个图像进行特征点提取,使得特征点集中分布在图像的某个区域,再通过视差估计深度时容易产生随机误差。因此,需要将图像进行分块,对每一块都提取一定的ORB特征点,以此来保存其均匀分布在图像中,减少随机误差的生成。首先搭建图像高斯金字塔,如图所示:
    视觉SLAM:ORB视觉里程计的简单实现(四)
    图中原始图像的大小为640*480,高斯金字塔的尺度为 ,层数 。通过使用高斯金字塔对图像进行尺度分层,对每一层都提取ORB特征点,获得具有尺度不变性的ORB特征点。

  • 然后,对原始图像与金字塔图像进行网格划分,假设原始图像被划分为64*48个网格,由于在高斯金字塔中上一层图像的尺寸比下一层图像的尺寸缩小1.2倍,因此网格的数量同样如此。然后,对每一层的图像都实现ORB特征点提取,假设需要获得的特征点总数为1000个,那么对于每一层需要提取的特征点数量为:
    a m = a 1 s m , a 1 = 1000 ∗ ( 1 − s ) / ( 1 − s n ) a_{m}=a_{1} s^{m}, a_{1}=1000 *(1-s) /\left(1-s^{n}\right) am​=a1​sm,a1​=1000∗(1−s)/(1−sn)
    其中:
    m = { 2 , 3 , … , n } m=\{2,3, \ldots, n\} m={2,3,…,n}
    根据等比数列前n项和有:
    S n = a 1 ( 1 − s n ) / ( 1 − s ) S_{n}=a_{1}\left(1-s^{n}\right) /(1-s) Sn​=a1​(1−sn)/(1−s)
    结合上式面几个式子可以得到,高斯金字塔所有层提取的特征点总数为1000个,与设定的值相等。

  • 对于具体的每层图像中的每个网格的特征点提取,由于每层图像提取的特征点数量是固定的,因此可以设定每个网格提取固定的特征点。设定每个网格的FAST角点的初始阈值为12,当某个网格提取不到角点时,减小该网格的FAST角点阈值继续提取,若阈值小于5之后还是没有角点则放弃对该网格的特征提取。为了保持特征点的旋转不变性,因此对于每一个角点特征,需要在其半径为3像素的圆形区域内计算其的质心位置,以此来获得该特征点的主方向。同时为了进行特征点的匹配,需要计算每一个角点特征的描述子,本文使用BRIEF[72]算法进行角点特征的描述子计算,以此来生成ORB特征点。

  • 此外以上获得的是在高斯金字塔上每一层图像的ORB特征点,对于不在原始层上的特征点,需要通过尺度信息将其映射到原始层,得到该特征点对应的实际像素坐标。同时为了提高ORB特征点使用的效率,如图所示,使用四叉树的方式对提取的ORB特征点进行保存,便于使用和匹配。
    视觉SLAM:ORB视觉里程计的简单实现(四)
    按照图中的图像划分,将各个部分中的特征点以此放入四叉树的根节点和叶子节点。若该区域没有其他的特征点,那么就结束划分,否则继续对可以划分的区域添加叶子节点,直到划分结束。

实验结果

  • 具体的实现代码已上传到github上,实验结果为:
    视觉SLAM:ORB视觉里程计的简单实现(四)
    视觉SLAM:ORB视觉里程计的简单实现(四)
  • 相比于原来的算法,现在的特征点均匀分布在空间的各个区域了。
  • 对于特征匹配,同样也可以采用更好的匹配算法进行优化,在优化位姿时也可以优化多帧图像位姿以及地图点位置。
  • 未完待续…
上一篇:【SLAM学习】环境搭建


下一篇:Semantic Visual SLAM in Populated Environments