ORBSLAM2中使用ORB描述子的方法


  经典的视觉SLAM系统大体分为两种:其一是基于特征点法的,其二是基于直接法的。那么本文主要就讲特征点法的SLAM。

  基于特征点法的视觉SLAM系统典型的有PTAM,ORBSLAM等。本文主要围绕ORBSLAM2的方案来阐述特征点法SLAM,因为ORBSLAM2可以说是特征点法SLAM的巅峰之作。ORBSLAM2采用三个主要线程:跟踪,局部建图和闭环以及一个额外线程:全局BA,该线程只有在闭环时才会触发。值得注意的是,ORBSLAM2中每个模块中都采用ORB描述子,而不像之前的其他系统那样跟踪和回环检测使用不同的特征点,这种做法一方面是节省提取时间,另一方面可以使得整个系统更加简洁。

  在跟踪阶段,ORBSLAM2对输入图像提取ORB描述子,与参考帧图像的ORB描述子进行特征匹配,具体的特征匹配方法下一讲中我们再详细讨论。如图1蓝色线所示,Rf表示参考帧(在ORBSLAM2中即是最后一个插入的关键帧Kf),Cf表示当前帧。p1表示参考帧Rf中的像素点,而p2表示当前帧Cf中与参考帧Rf匹配的ORB特征点位置。ORBSLAM2中在地图中查找p1的三维坐标P,如图1绿色线所示,查询完毕后利用外参T=[R,t]将P投影到当前帧Cf中,如图1红色线所示。如图1中黄色线所示,p2为P在当前帧Cf中的真实位置,而p2'为实际投影位置,二者之间存在误差,通过优化外参T=[R,t]来使得所有特征点之间的冲投影误差最小,实现相机的位置跟踪:

    

如公式(1)所示,即为当前帧和当前帧所有匹配特征点对的重投影误差,除了单纯的计算重投影误差外,注意到公式(1)中,采用了核函数,来防止外点对非线性优化的过度影响(非线性优化中最怕的就是外点,因为他会导致其他内点都去迁就他,结果优化效果与真实值的差距自然较大)。此外,公式(1)还利用了信息矩阵来对不同的特征点添加权值信息,最简单的信息就是取信息矩阵为单位阵,即对所有特征点都一视同仁。可以看见,这都是有一些优化的小技巧在的,纵观全文,你会发现ORBSLAM2中处处都是优化的细节,简直到了丧心病狂的地步 - -|。

  在局部优化和全局优化的时候,采用的也都是公式(1)的方法,只不过在闭环时为了节省计算时间,采用了pose-graph,即忽略所有点的信息,只对位姿进行优化。具体的内容后续博客我会尽量给大家讲清楚。

  ORB描述子用于回环检测之前,会先利用Bag of word将ORB描述子进行转换,变成视觉词汇。在回环检测时,只需要比较词汇之间的相似性,即可判断机器人是否回到之前经过的地方。当然,这里还有一些其他的验证,后续也会给大家慢慢讲。

  至此,ORBSLAM2中ORB描述子的使用算是给大家讲清楚了,接下来,就开始研究一下ORB描述子到底是怎么生成的以及为什么它会如此强大?

                      图 1


ORB描述子提取的方法

  如上所说的,视觉SLAM系统中目前主流的是基于直接法或者基于特征点法。但是目前鲁棒性最好的描述子是SIFT描述子,但是提取过程太耗费时间,非常不适用于SLAM这种需要实时运行的系统,而基于SIFT描述子改进的SURF描述子尽管提高了一个数量级的提取效率,但仍然无法满足SLAM系统的要求。而更快速的FAST关键点对光照非常敏感,BRIEF描述子可以很好地利用像素块的信息构成一个具有特异性的描述子,但其对于旋转不具备不变形。由于现存的大部分描述子要么因为鲁棒性不足,要么因为提取时间过长等缺陷,因此迫切需要一种在鲁棒性和提取时间这种的方案出现,而ORB描述子就是答案。

  ORB发掘了现有的提取效率最快的关键点FAST以及描述子BRIEF,并在其原有基础上进行改进,形成具备尺度不变形和旋转不变形的ORB描述子。

Fast关键点提取

  对输入图像中每个像素提取FAST关键点,即在当前提取像素点p的局部块中,比较块中的像素(1-16)与中心像素p的灰度差,如图2所示。

    

                        图 2

在ORB描述子的文章ORB: an efficient alternative to SIFT or SURF中,使用FAST9来提取FAST关键点,即在图2中的16邻域中,只要有9个像素点同时都比中心像素p小或者大,即认为其是关键点,但实际提取过程中这个像素差是可以添加阈值的。如公式(2)所示。

    

其中t即为阈值,必须满足像素差大于某一个值才能定义其为关键点。

  为了避免关键点扎堆的情况出现,比如桌子边缘这类地方,会出现整个边缘布满FAST关键点。尽管关键点某些时候越多越好,但是将较差的部分滤掉,保留较好那部分关键点,显然是更好的选择,因为这会使得在使用过程中,增加系统的鲁棒性。

  FAST中用极大值抑制来筛选出较好的关键点,统计关键点p1的邻域中的像素差总和分数s1,对比相邻关键点之间的差异,即s1和s2,在邻域内只保留分数最大的关键点。

  显然FAST关键点不具有尺度不变形,因此采用了空间金字塔为FAST构建尺度不变性,在每一个尺度下的图像中提取FAST关键点。具体在源码解析的时候会为大家详细解读。

  由于BRIEF描述子不具备旋转不变性,为了克服这个缺陷,ORB描述子通过计算FAST关键点局部块的矩来生成旋转方向(即利用块中所有像素y方向上的差值之和与x方向上的差值之和的比值,可以理解成tan(theta) = delta y / delta x):

    

BRIEF描述子生成

  BRIEF描述子主要是通过比较中心像素点p任意邻域内的256对像素之间的差值来生成二进制描述子的。如公式(6)所示,任意一对像素点p(x)和p(y),若p(x)<p(y),则描述子对应的位置为1,否则置为0。

    

  值得注意的是,很多人看到论文的时候会觉得BRIEF描述子并没有用到上面FAST生成的灰度质心角度啊。但是参考SIFT描述子,ORB描述子也采用了同样的方法,在计算描述子的时候,ORB描述子通过旋转匹配对的位置,再进行计算,因此就使得ORB描述子具备了旋转不变性。

  通过机器学习的方式随机选择多种组合的像素对,作者通过选择最好的一组256对像素点的组合作为ORB描述子的pattern。

  


总结

  本文首先介绍了

    ORB描述子在ORBSLAM2中的应用,包括跟踪阶段和回环检测时ORB如何使用的;

    ORB描述子的提取方法,包括FAST关键点的提取和BRIEF描述子的生成。  

  下一讲将会将ORBSLAM2中的ORB描述子提取源码分离出来,单独实现并进行讲解。

PS:

  如果您觉得我的博客对您有所帮助,欢迎关注我的博客。此外,欢迎转载我的文章,但请注明出处链接。

  对本文有任何问题可以在留言区进行评论,也可以在泡泡机器人论坛:http://paopaorobot.org/bbs/index.php?c=cate&fid=1中的SLAM技术交流模块发帖提问。

  

(一)ORB描述子提取的更多相关文章

  1. (二)ORB描述子提取源码思路与实现

    ORBSLAM2中ORB特征提取的特点 ORBSLAM2中通过对OpenCV中的ORB特征点提取类进行修改,对图像进行分块提取,而后划分节点,使得每个节点中保存的特征点性能是该节点所有特征点中最好的. ...

  2. 图像特征与描述子(直方图, 聚类, 边缘检测, 兴趣点/关键点, Harris角点, 斑点(Blob), SIFI, 纹理特征)

    1.直方图 用于计算图片特征,表达, 使得数据具有总结性, 颜色直方图对数据空间进行量化,好比10个bin 2. 聚类 类内对象的相关性高 类间对象的相关性差 常用算法:kmeans, EM算法, m ...

  3. 二进制描述子 BRIEF(ORB), BRISK, FREAK

    二进制描述子设计原则体现在三个部分: 采样pattern 方向orientation compensation 配对sampling pairs ORB基于BRIEF: BRISK是用于OKVIS的描 ...

  4. BRIEF 特征描述子

    Binary Robust Independent Elementary Features www.cnblogs.com/ronny 1. BRIEF的基本原理 我们已经知道SIFT特征采用了128 ...

  5. Brief描述子

    一.Brief算法 1.基本原理 BRIEF是2010年的一篇名为<BRIEF:Binary Robust Independent Elementary Features>的文章中提出,B ...

  6. PCL点云特征描述与提取(4)

    如何从一个深度图像(range image)中提取NARF特征 代码解析narf_feature_extraction.cpp #include <iostream> #include & ...

  7. PCL点云特征描述与提取(1)

    3D点云特征描述与提取是点云信息处理中最基础也是最关键的一部分,点云的识别.分割,重采样,配准曲面重建等处理大部分算法,都严重依赖特征描述与提取的结果.从尺度上来分,一般分为局部特征的描述和全局特征的 ...

  8. BRIEF特征点描述子

    简介 BRIEF是2010年的一篇名为<BRIEF:Binary Robust Independent Elementary Features>的文章中提出,BRIEF是对已检测到的特征点 ...

  9. Opencv Surf算子中keyPoints,描述子Mat矩阵,配对向量DMatch里都包含了哪些好玩的东东?

    Surf算法是一把牛刀,我们可以很轻易的从网上或各种Opencv教程里找到Surf的用例,把例程中的代码或贴或敲过来,满心期待的按下F5,当屏幕终于被满屏花花绿绿的小圆点或者N多道连接线条霸占时,内心 ...

随机推荐

  1. QinQ 简介

    QinQ 是一种二层隧道协议,通过将用户的私网报文封装上外层 VLAN Tag,使其携带两层 VLAN Tag 穿越公网,从而为用户提供了一种比较简单的二层VPN隧道技术.QinQ 的实现方式可分为两 ...

  2. Playfair 加密

    题目真的好长但是意思很简单 89.加密 (15分)C时间限制:3 毫秒 | C内存限制:3000 Kb题目内容:一种Playfair密码变种加密方法如下:首先选择一个密钥单词(称为pair)(字母不重 ...

  3. C# WinForm 技巧十: winfrom 全屏自适应屏幕分辨率

    Rectangle rect = new Rectangle(); rect = Screen.GetWorkingArea(this); this.Width = rect.Width;//屏幕宽 ...

  4. 4月25日课上练习 一维数组最大子数组(debug版)

    一维数组中求最大子数组的算法 package com.wangwang.mar; import java.util.Scanner; public class Sum { public static ...

  5. win10下安装ubuntu18.04

    在win10下安装Ubuntu18.04,双系统共存.Ubuntu 18.04 使用的是Gnome桌面. 查看系统的启动模式: Win+R打开运行,输入msinfo32,回车查看系统信息.在BIOS模 ...

  6. FreeMarker 入门

    目录 FreeMarker是什么 为什么要学习FreeMarker FreeMarker相关站点

  7. 使用linux backtrace打印出错函数堆栈信息

    一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序的分析),在程序出错时打印出函数的调用堆栈是非常有用的. 在glibc ...

  8. luogu P1723 高手过愚人节

    打算下周讲课就讲Manacher了 所以百度了一下相关题目,发现了一道千古好题 这道题没想到是一道模板题,模板中的模板 简要说一下思路,我们先复制一遍模板(甚至变量都不用改 然后唯一的区别就是要求的是 ...

  9. 最近公共祖先(LCT)

    来一发\(LCT\)求\(LCA\) \(LCT\)在时间上不占据优势,码量似乎还比树剖,倍增,\(Tarjan\)大一点 但是却是一道\(LCT\)的练手题 对于每一个询问,我们只需要把其中一个点( ...

  10. jQuery动态添加、删除按钮及input输入框

    输入框的加减实现: <html> <head> <meta charset="utf-8"> <title>动态创建按钮</t ...