ORB-SLAM: A Versatile and Accurate Monocular SLAM System 笔记(二)
4. 自动地图初始化
地图初始化的目标是两个帧之间相对位姿来三角化一系列的点云(riangulate an initial set of map points),这个操作是独立与场景且不需要人为的干预的。文章提出平行的计算两个几何模型:对平面场景的 homography 和对非平面的 fundamental matrix 。然后根据实际情况选择一个模型做初始化,算法的步骤如下:
Find initial correspondences: 从当前帧 \(F_c\) 中提取 ORB 特征并且在相邻帧 \(F_r\) 寻找匹配 \(\bf x_c \leftrightarrow \bf x_r\),如果没有找到足够的匹配,就重置参考帧。
Parallel computation of the two models: 同时计算 homography \(\bf H_{cr}\) 和 fundamental matrix \(\bf F_{cr}\) :
\[{\bf x}_c = {\bf H}_{cr} \, {\bf x}_r, \quad {\bf x}_c^T \, {\bf F}_{cr} \, {\bf x}_r = 0
\]计算模型使用的特征点和迭代数是提前固定的,每次迭代都给模型打分:
\[\begin{eqnarray}
S_M &=& \sum _i \big (\rho _M \big (d_{cr}^2({\bf x}_c^i,{\bf x}_r^i,M)\big) \nonumber +\; \rho _M (d_{rc}^2\big ({\bf x}_c^i,{\bf x}_r^i,M)\big) \big) \nonumber \\
\rho _{M} (d^2) &=& \left\lbrace \begin{array}{ll}\Gamma - d^2, & \textrm {if} \quad d^2 < T_M \\
0, & \textrm {if} \quad d^2 \ge T_M \end{array}\right.
\end{eqnarray}
\]\(d_{cr}^2,d_{rc}^2\) 是一个帧到另一个帧的传递误差,\(T_M\) 是拒绝门限值,\(\Gamma\) 等于 \(T_H\) 这样所有的模型在得分均匀。 最后选取score最高的一组。如果没有模型被找到,那么就重新回到步骤一(we restart the process again from step 1)。
Model selection: 如果场景是近似于平面的,就可以用 homography 模型,否则选用 fundamental matrix 模型。在平面的情况下视差较低,使用 homography 重建的误差较低。文章设计了一个式子:
\[R_H=\frac{S_H}{S_H+S_F}
\]当 \(R_H>0.45\) 的时候选择 homography 模型。
Motion and structure from motion recovery: 一旦选好了模型,我们就可以获得运动状态。在 homography 中,从方法 23 中提取8种运动假设,这个方法通过测试来选择有效的方案。如果测试失败就会返回 1 中重新做计算,
\[{\bf E}_{rc} = {\bf K}^{T} \, {\bf F}_{rc} \, {\bf K}
\]Bundle adjustment: 使用 full BA 来初始化地图。
5. Tracking
这一节详细介绍线程通过相机执行每一帧的步骤。
A. ORB 提取
为了确保角点分布均匀,将一张图片分成多个 cell ,每个 cell 提取至少五个角点。如果找不到足够的角点,通过调整检测器阈值来重新提取。如果某些 cell 不包含角点,每个 cell 的角点也要进行调整。方向和ORB描述符会做进一步的计算。
B. 从前面的帧初始化位姿
如果最后一帧的 tracking 成功,就是用匀速运动模型来预测位姿并找出上一帧中匹配的点。如果匹配不够,那么使用更加宽泛的距离去寻找对应的点进行相应的优化位姿。
C. 全局重定位的初始姿态估计
如果 tracking 失败,就把当前帧转为 bag of words 然后到数据库中做匹配。我们计算与每个关键帧中与地图点相关联的ORB 特征,使用 PnP 算法来确定相机位姿,如果有足够的 inlier ,就可以对丢失的帧做出位姿估计。
D. Track Local Map
一旦对相机位姿和特征匹配有了估计,就可以将地图投影到帧中来寻找更多的关联点。定义与当前帧有交集的集合\(\mathcal {K}_1\) 和 \(\mathcal {K}_2\) ,形成一个 covisibility graph 。在 \(\mathcal {K}_1\) 中与当前帧有最多的匹配点的帧叫做 \(\mathcal {K}_{ref}\) 。\(\mathcal {K}_1\) 和 \(\mathcal {K}_2\) 中每个可见的点云将会如下操作:
- 把 x 映射到当前帧,如果超出边界就丢弃;
- 计算当前视角 \(\bf v\) 和点云中平均视角 \(\bf n\),如果 \(\mathbf {v} \cdot \mathbf {n}<\textrm {cos}(60^{\circ})\) 就丢弃当前视角;
- 计算点云到相机中心的距离,超出the scale invariance region 就丢弃;
- 计算帧的 scale,比例 \(d/d_{\min}\) ;
- 对比点云中描述符 \(\bf D\) 和当前帧还没有匹配的ORB特征,在scale,和靠近x的云点作最优匹配。
相机位姿最后通过当前帧中获得所有的点云进行优化。
E. 新的关键帧选取
要尽可能快的插入关键帧,这样可以在相机移动时 tracking 过程更加稳健。插入新的关键帧遵循:
- 上一次全局定位已经过去 20 帧;
- 局部地图构建已经暂停,或者是距离上次插入关键帧超过20帧;
- 当前帧 track 出来 50个特征点;
- 当前帧跟踪少于参考关键帧特征点的90%。
6. Local Mapping
A. 关键帧插入
首先更新 covisibility graph ,插入节点 \(K_i\) ,更新关键帧间具有相同点云产生的edge。我们还要更新生成树上Ki和其他关键帧的链接。然后,计算表示关键帧的词袋,用于数据关联来三角化新的云点。
B. 点云的去冗余
点云必须通过三帧的严格测试,确保它们是可被 track 和没有错误的 triangulate。一个点必须满足两个条件:
- Track 必须在超过25%预测可见的帧中找到该点;
- 特征点必须被至少三个关键帧察觉到。
C. 新点云的创建
在 covisibility graph 中的关联关键帧 $\mathcal {K}_c $ 三角化 ORB 可以创建点云,ORB特征对三角化后,将要获得新的云点,这时要检查两个相机视图的景深,视差,重映射误差,和尺度一致性等。
D. 局部BA
局部优化当前处理的关键帧 \(K_i\) 、所有在 covisibility graph $\mathcal {K}_c $ 上关联的帧和之前所有帧中的特征点。离群点会在优化的中间和最后阶段被丢弃。
E. 局部关键帧剔除
为了使得重构更加简洁,局部映射会尝试探测冗余关键帧然后删除它们。这会大有帮助,因为BA 的复杂度随着关键帧的增加而增长。一个关键帧如果90%的特征点已经在至少三帧出现过,也会被剔除。
7. 闭环检测
闭环检测处理的是最近处理的关键帧,判断它是否与之前的关键帧存在闭环。
A. 闭环候选检测
首先,计算 \(K_i\) 和它在 covisibility graph 邻近的关键帧的 bag of words vector 的相似度,保留最小得分 \(s_{\min}\) 。然后查询数据库,丢弃所有得分小于 \(s_{\min}\) 的关键帧,然后丢弃所有和 \(K_i\) 直接关联的关键帧。接着从剩下的帧中选取候选项,候选项必须是连续的三帧以上的才能作为候选项。
B. 计算相似转换
在单目 SLAM 中,可能有 7 个自由度发生漂移:三个平移分量,三个旋转分量和 scale 因子。因此要计算 \(K_i\) 和回环帧 \(K_l\) 的相似度来计算环中的累计误差。
首先计算当前关键帧和环候选关键帧中特征点的 ORB 对应关系,对应每个候选环,有 3D to 3D 的对应关系。对每个候选回环执行RANSAC迭代,,balabala
C. 闭环融合
第一步融合重复的点,在covisibility graph插入与 loop closure 有关的新的 edges。当前关键帧的位姿 \(\mathbf {T}_{iw}\) 通过相似变化 \(\mathbf {S}_{il}\) 修正,这个修正也会应用于所有的相邻帧 \(K_i\) ,来执行 concatenating 变换,这样环中所有的边都可以对齐。
回环关键帧所有的特征点和它的邻居映射到 \(K_i\) 中,通过映射在较小的区域内搜索它的近邻和匹配。所有匹配和未离群的点都被融合起来,融合过程中所有的关键帧将会更新它们的边缘,这些视图内容相关的图像创建的边缘用于回环控制。
D. Essential Graph 优化
为了进行有效的闭环,我们在 Essential Graph 执行了一个优化,这样可以将回环的误差分散到图像中,优化程序通过相似变换校正尺度偏移。优化过后每一个特征点都根据关键帧的校正进行变换。
ORB-SLAM: A Versatile and Accurate Monocular SLAM System 笔记(二)的更多相关文章
- ORB-SLAM: A Versatile and Accurate Monocular SLAM System 笔记(一)
ORB-SLAM: A Versatile and Accurate Monocular SLAM System Abstract 这篇文章提出了 ORB-SLAM,一个基于特征的单目SLAM系统,这 ...
- SLAM: Inverse Depth Parametrization for Monocular SALM
首语: 此文实现客观的评测了使线性化的反转深度的效果.整篇只在表明反转可以线性化,解决距离增加带来的增长问题,有多少优势--%! 我的天呢!我竟然完整得翻译了一遍. 使用标记点地图构建SLAM的方法, ...
- 《SLAM for Dummies》中文版《SLAM初学者教程》
SLAM for Dummies SLAM初学者教程A Tutorial Approach to Simultaneous Localization and Mapping 一本关于实时定位及绘图 ...
- Semantic Monocular SLAM for Highly Dynamic Environments面向高动态环境的语义单目SLAM
一.摘要 当前单目SLAM系统能够实时稳定地在静态环境中运行,但是由于缺乏明显的动态异常处理能力,在动态场景变化与运动中往往会失败.作者为解决高度动态环境中的问题,提出一种语义单目SLAM架构,结合基 ...
- 转:SLAM算法解析:抓住视觉SLAM难点,了解技术发展大趋势
SLAM(Simultaneous Localization and Mapping)是业界公认视觉领域空间定位技术的前沿方向,中文译名为“同步定位与地图构建”,它主要用于解决机器人在未知环境运动时的 ...
- 【Hector slam】A Flexible and Scalable SLAM System with Full 3D Motion Estimation
作者总结了SLAM前端和后端的区别 While SLAM frontends are used to estimate robot movement online in real-time, the ...
- 论文阅读笔记二十四:Rich feature hierarchies for accurate object detection and semantic segmentation Tech report(R-CNN CVPR2014)
论文源址:http://www.cs.berkeley.edu/~rbg/#girshick2014rcnn 摘要 在PASCAL VOC数据集上,最好的方法的思路是将低级信息与较高层次的上下文信息进 ...
- 当前的开源SLAM方案
开源方案 传感器形式 地址链接 MonoSLAM 单目 https://github.com/hanmekim/SceneLib2 PTAM 单目 http://www.robots.ox.ac. ...
- SLAM论文阅读笔记
[1]陈卫东, 张飞. 移动机器人的同步自定位与地图创建研究进展[J]. 控制理论与应用, 2005, 22(3):455-460. [2]Cadena C, Carlone L, Carrillo ...
随机推荐
- InvalidProgramException: Specifying keys via field positions is only valid for tuple data types
Run Flink实例时,出现如下错误: 原因:Java程序引用了Scala的Tuple2类 遇到的坑,记录下来!
- 加载Properties文件工具类:LoadConfig
import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; import javax.ws.rs.Path; impor ...
- [转]35张图就是为了让你深入AQS
以下文章来源于程序员cxuan ,作者一枝花算不算浪漫 谈到并发,我们不得不说AQS(AbstractQueuedSynchronizer),所谓的AQS即是抽象的队列式的同步器,内部定义了很多锁相关 ...
- 简单认识JAVA内存划分
Java的内存划分为五个部分 那么又是哪五个部分呢?跟着我往下看! 介绍: 每个程序运行都需要内存空间,所以Java也不例外:而Java把从计算机中申请的这一块内存又进行了划分!而所在目的是为了让程序 ...
- JS 鼠标放上去滑出内容案例
.sliderbar { width: 200px; height: 40px; position: relative; margin: 0 auto; } .sliderbar span { dis ...
- ECMAScript6新增数据类型symbol数据类型
25.Symbol目的:为了解决对象之间属性名冲突的问题,Symbol它是引用数据类型. Symbol( ),它代表着一个独一无二的值 [name]: '小红',//加中括号代表默认创建了一个Symb ...
- 从零搭建Spring Boot脚手架(3):集成mybatis
1. 前言 今天继续搭建我们的kono Spring Boot脚手架,上一文集成了一些基础的功能,比如统一返回体.统一异常处理.快速类型转换.参数校验等常用必备功能,并编写了一些单元测试进行验证,今天 ...
- Vue视图渲染原理解析,从构建VNode到生成真实节点树
前言 在 Vue 核心中除了响应式原理外,视图渲染也是重中之重.我们都知道每次更新数据,都会走视图渲染的逻辑,而这当中牵扯的逻辑也是十分繁琐. 本文主要解析的是初始化视图渲染流程,你将会了解到从挂载组 ...
- C#LeetCode刷题之#532-数组中的K-diff数对(K-diff Pairs in an Array)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3716 访问. 给定一个整数数组和一个整数 k, 你需要在数组里找 ...
- Java程序员面试必备:Volatile全方位解析
前言 volatile是Java程序员必备的基础,也是面试官非常喜欢问的一个话题,本文跟大家一起开启vlatile学习之旅,如果有不正确的地方,也麻烦大家指出哈,一起相互学习~ 1.volatile的 ...