当前位置:网站首页>【视觉SLAM十四讲】第一章理论详解
【视觉SLAM十四讲】第一章理论详解
2022-08-01 05:32:00 【毅博明喆】
第一讲 概述与预备知识

现实世界中的相机(雷达等传感器)会以一定速率来采集真实世界的视频或图像,计算机视觉是依据这些信息(视频或图像)来进行相应的处理(物体识别、物体跟踪、物体检测、语义分割、…、SLAM等)。SLAM需要了解相机的位置以及它是怎么运动的,已经它所处场景的周围环境信息。SLAM的目的是估计相机的运动(及它所处位置和如何来运动的)【定位】;估计它所处的周围环境(建图)
SLAM是什么
室内/室外定位
稀疏-半稠密重建
(稀疏重建SfM、稠密重建MVS)
稀疏重建是通过相机运动恢复场景结构。(Structure-from-Motion)

三维重建笔记——稀疏重建 - Wxxuan - 博客园 (cnblogs.com)
SfM包括以下步骤:
- 特征点检测与匹配
- 外极几何图构造
- 摄像机位姿和场景结构估计
- 捆绑调整(BA)优化摄像机位姿和场景
CCCV2017讲习班笔记-基于图像的大规模场景三维重建(上)
稠密重建

CCCV2017讲习班笔记-基于图像的大规模场景三维重建(下)
SLAM可以用在哪些地方?

作业1. SLAM会在哪些场合中⽤到?⾄少列举三个⽅向。
答:虚拟现实/增强现实应用、动态场景、语义地图、多机器人协作、移动机器人的自主导航、无人驾驶、三维重建以及行星、空中、陆地和海洋勘探
SLAM: Simultaneous Localization and Mapping
• 同时定位与地图构建
• SLAM的数学基础知识
• SLAM相关的计算机视觉知识
• 工程实践

课程内容与预备知识

预备知识与课程使用的环境
• 数学: 高等数学、线性代数(矩阵论)、概率论
• 编程: C++、 Linux,了解语法和基本命令即可
• 英语:文献、文档阅读能力
• 环境: Ubuntu 16.04
• 不提供windows环境下的方案!
SLAM是什么
SLAM是什么
视觉SLAM学习–基础篇 - 爱码网 (likecs.com)
如上图的小萝卜机器人,要使其具有自主运动能力至少需要两个条件:
我在什么地方?——定位。
周围环境是什么样?——建图。
因此它既需要知道自身的状态-位置,也要了解所在的环境-地图。解决这些问题的方法非常多,如携带于机器人本体上的传感器,例如机器人的轮式编码器、相机、激光等等,另一类是安装于环境中的,例如导轨、二维码标志等等。

各传感器介绍


在视觉SLAM中主要是用相机去解决定位与建图问题。按照相机的工作方式,把相机分为单目(Monocular)、双目(Stereo)和深度相机(RGB-D)三个大类,如下图所示。直观看来,单目相机只有一个摄像头,双目有两个,而 RGB-D 原理较复杂,除了能够采集到彩色图片之外,还能读出每个像素离相机的距离。它通常携带多个摄像头,工作原理和普通相机不尽相同。此外,SLAM 中还有全景相机 、Event 相机 等特殊或新兴的种类。

单目相机 :
只使用一个摄像头进行 SLAM 的做法称为单目 SLAM(Monocular SLAM)。这种传感器结构特别的简单、成本特别的低,所以单目 SLAM 非常受研究者关注,它的数据格式就是常见的照片。
照片本质上是拍照时的场景(Scene),在相机的成像平面上留下的一个投影。它以二维的形式反映了三维的世界。显然,这个过程丢掉了场景的一个维度:也就是所谓的深度(或距离)。在单目相机中,我们无法通过单个图片来计算场景中物体离我们的距离(远近)——之后我们会看到,这个距离将是 SLAM 中非常关键的信息。由于我们人类见过大量的图像,养成了一种天生的直觉,对大部分场景都有一个直观的距离感(空间感),它帮助我们判断图像中物体的远近关系。比如说,我们能够辨认出图像中的物体,并且知道它们大致的大小;比如近处的物体会挡住远处的物体,而太阳、月亮等天体一般在很远的地方;再如物体受光照后会留下影子等等。这些信息可以都帮助我们判断物体的远近,但也存在一些情况,这个距离感会失效,这时我们无法判断物体的远近以及它们的真实大小。由于单目相机只是三维空间的二维投影,所以,如果我们真想恢复三维结构,必须移动相机的视角。
在单目 SLAM 中也是同样的原理。我们必须移动相机之后,才能估计它的运动(Motion),同时估计场景中物体的远近和大小,称之为结构(Structure)。如果相机往右移动,那么图像里的东西就会往左边移动——这就给我们推测运动带来了信息。另一方面,我们还知道近处的物体移动快,远处的物体则运动缓慢。于是,当相机移动时,这些物体在图像上的运动,形成了视差。通过视差,我们就能定量地判断哪些物体离得远,哪些物体离的近。
单目 SLAM 估计的轨迹和地图,将与真实的轨迹、地图,相差一个因子,也就是所谓的尺度(Scale)。由于单目 SLAM 无法仅凭图像确定这个真实尺度,所以又称为尺度不确定性。
单目相机数据
双目相机 (Stereo) 和深度相机 :
双目相机和深度相机的目的,在于通过某种手段测量物体离我们的距离,克服单目无法知道距离的缺点。如果知道了距离,场景的三维结构就可以通过单个图像恢复出来,也就消除了尺度不确定性。尽管都是为测量距离,但双目相机
与深度相机测量深度的原理是不一样的。双目相机由两个单目相机组成,但这两个相机之间的距离(称为基线(Baseline))是已知的。我们通过这个基线来估计每个像素的空间位置——这和人眼非常相似。我们人类可以通过左右眼图像的差异,判断物体的远近,在计算机上也是同样的道理。如果对双目相机进行拓展,也可以搭建多目相机,不过本质上并没有什么不同。
双目相机数据
深度相机数据
总结:
- 单目相机:以二维的形式反应了三维的世界,丢掉了深度,也就是物体到我们的距离。
- 双目相机:克服了单目相机的深度问题,通过已知两眼间的距离后大量计算。
- 深度相机(RGB-D):克服了深度问题。原理是通过激光传感器,通过主动向物体发射光并接收返回的光,测出物体离相机的距离,节省了大量计算,存在的问题是范围窄,视野小,易受日光干扰。
视觉SLAM框架

整个视觉SLAM流程包括以下步骤。(必须的是前端和后端;;回环检测和建图是额外的模块)
传感器信息读取。在视觉SLAM中主要为相机图像信息的读取和预处理。如果是在机器人中,还可能有码盘、惯性传感器等信息的读取和同步。
【主要用于采集实际环境中的各类型原始数据。包括激光扫描数据、视频图像数据、点云数据等。】
视觉里程计(Visual Odometry,VO)。视觉里程计的任务是估算相邻图像间相机的运动,以及局部地图的样子。VO又称为前端(Front End)。
【主要用于不同时刻间移动目标相对位置的估算。包括特征匹配、直接配准等算法的应用。】
后端优化(Optimization)(长时刻,长时间段内获取更符合观察模型的估计)后端接受不同时刻视觉里程计测量的相机位姿,以及回环检测的信息,对它们进行优化(非线性的优化问题),得到全局一致的轨迹和地图。由于接在VO之后,又称为后端(Back End)。
【主要用于优化视觉里程计带来的累计误差。包括滤波器、图优化等算法应用。
扩展卡尔曼滤波(EKF)算法和基于光束法平差(BA)的图优化算法;】
回环检测(Loop Closing)。回环检测判断机器人是否到达过先前的位置。如果检测到回环,它会把信息提供给后端进行处理。(对估计的轨迹进行调整,把当前的估计调整到正确的位置)
【主要用于空间累积误差消除】
建图(Mapping)。它根据估计的轨迹,建立与任务要求对应的地图。(安装自己的需求来调整,调整到自己需要的形式)
【用于三维地图构建】
其工作流程大致为:
传感器读取数据后,视觉里程计估计两个时刻的相对运动(Ego-motion),后端处理视觉里程计估计结果的累积误差,建图则根据前端与后端得到的运动轨迹来建立地图,回环检测考虑了同一场景不同时刻的图像,提供了空间上约束来消除累积误差。
1.传感器数据
在视觉SLAM中主要为相机图像信息的读取和预处理。如果在机器人中,还可能有码盘,惯性传感器等信息的读取和同步。
前端视觉里程计(VO-Visual Odometry)【图像特征提取与匹配】
根据视觉特征,对相邻帧间的位姿进行拟合运算。不同方式,最终结果都是完成相机平移、旋转的运算。(计算机中需要精确的描述:相机旋转了多少度,平移了多少米)
VO能够通过相邻帧间的图像估计相机运动,并回复场景的空间结构。称他为“里程计”是因为他和实际的里程计一样,只估计相邻时刻的运动,而和再往前的过去的信息没有关联。在这一点上,VO就像一种只有短时间记忆的物种。
由于视觉里程计(在最简单的情况下)只估计两个图像间的运动将会造成累计飘逸(Accumulating Drift)。因为每次估计都带有一定的误差。而由于里程计的工作方式,先前时刻的误差将会传递到下一时刻,导致经过一段时间之后,估计的轨迹将不再准确。
这就是所谓的飘逸(Drift)。为了解决飘逸问题,我们还需要两种技术:后端优化和回环检测。

视觉里程计(VO)也称前端。它根据相邻图像的信息,估计出粗略的相机运动,给后端提供较好的初始值。VO 的实现方法,按是否需要提取特征,分为特征点法的前端以及不提特征的直接法前端。基于特征点法的前端,长久以来(直到现在)被认为是视觉里程计的主流方法。它运行稳定,对光照、动态物体不敏感,是目前比较成熟的解决方案。
前端视觉里程计的功能是类似“里程计”的功能,其核心功能是进行初步的构图与定位,是指对机器人相机采集到的图像进行初步处理,也是视觉SLAM技术的起点。根据对图像处理方式的不同,可以分为直接法与间接法两种。
直接法(不提特征点)
直接法是指对相机所采集的图像在像素层面上直接进行求解,根据选取像素量的多少,又可以分为以下三种方案:
- 稀疏直接法
- 半稠密直接法
- 稠密直接法
从稀疏直接法到稠密直接法,其计算量依次增加,构图与定位的精度越高。
因此,在实际的使用过程中,根据应用场合选择合理的求解方案。但始终不变的是,直接法是对采集的图像直接进行求解,不进行图像处理层面的操作。
间接法
间接法一般称为特征点法。即对图像提取相应的特征点,然后对两帧图像进行特征匹配(找出两帧图像相同的特征),最后利用匹配好的特征进行位姿的求解。
由此可见,特征点法的实施过程主要求解两大问题:特征匹配和位姿。而在直接法中,并不需要特征匹配这一工作。
特征匹配主要是图像处理工作,目前的图像处理算法多种多样,而对于视觉SLAM技术里的图像处理算法,个人认为有以下几点要求:
- 能提取大部分场景下的图像特征
- 能匹配大量图像之间的特征
- 能够满足一定的实时性要求
因为基于特征点法的视觉里程计的要解决的首要问题便是特征提取与匹配,因此,前两个要求是毋庸置疑的,而视觉SLAM技术的应用特点决定了算法有较高的实时性的要求。目前主要的算法有:FAST、SURF以及ORB算法。
图像特征匹配算法只解决了视觉里程计的第一个问题,而最重要的问题是要利用匹配好的图像特征进行构图与定位。
后端优化(Optimization)(处理SLAM过程中的噪声,状态估计问题)
通过大量观测点的拟合,最终针对平移、旋转6个参数进行寻优,往往得到结果准确度是比较高的。但准确度再高,也会有误差,小误差累计起来,会对建图准确性产生很大影响。为了得到准确的建图结果,VO环节得到的位姿都输入到优化器内,当优化器收到回环检测信息时,即可对所有中间输入位姿全局优化,减小累计误差对建图准确性的影响。【滤波和非线性优化算法】

有前端就有后端,如果说前端里程计是进行“粗算”,那么后端的主要工作便是“细算”,因此,其核心的工作是对前端里程计的定位与构图进行优化。
在实际的求解过程中,后端优化所用到的数据集要比里程计要多得多,这也是可以进行优化的核心,因为随着机器人的移动,环境的变化,时间的推移等等,前端里程计求解的误差会累积,从而导致最后构图与定位偏离实际太多。因此,后端优化在视觉SLAM技术中必不可少。
目前主流的后端优化有两种:
- 扩展卡尔曼滤波(EKF)算法;
- 基于光束法平差(BA)的图优化算法;
在SLAM技术的早期,EKF算法应用较多,而近些年,图优化更受青睐。
后端优化主要是处理SLAM过程中噪声的问题。任何传感器都有噪声,所以除了要处理“如何从图像中估计出相机运动”,还要关心这个估计带有多大的噪声。
前端给后端提供待优化的数据,以及这些数据的初始值,而后端负责整体的优化过程,它往往面对的只有数据,不必关心这些数据来自哪里。在视觉SLAM中,前端和计算接视觉研究领域更为相关,比如图像的特征提取与匹配等,后端则主要是滤波和非线性优化算法。
SLAM问题的本质:对运动主体自身和周围环境空间不确定性的估计。
回环检测(Loop Closing)【本质:计算图像相似性的算法。来消除漂移】
通过关键帧的特征匹配,检测到相机回到之前走过的场景,此时就可以作为先验知识,使用优化器去将之前的位姿人为闭合。
这里没有专门研究过,想到了两个问题:
1.如果遇上相似场景,导致匹配误报,那场景岂不就大错特错了,是不是就得增加其他手段进行干预,比如GPS?对场景进行关联,限定当前帧匹配范围?
2.即使使用Bow,对特征匹配进行加速,当场景很大时,关键帧就会变得非常多,此时匹配的速度一定会变慢,并且误匹配的概率也会增加。应该也是需要分区域,限定匹配范围。

理论上,当机器人第二次到达同一个地点,根据采集的图像计算得到的位姿应该是同前面的计算结果一样的,对于同一个地点,视觉SLAM技术构建的位姿图应该是重合的。但在实际过程中,技术进行里程计与后端优化算法,位姿求解依旧有偏差,所以机器人在重复经过同一地点,位姿图会有微弱便宜现象,形成“重影”。
回环检测技术便是要去掉“重影”。对于SLAM来说,通过对比当前帧与过去关键帧的相似度,如相似度超过某一阀值时就可以被认为是检测到回环。
目前回环检测的主流方案是词袋模型。其基本思想是构建一本“词典”,把每帧图像的特征当作一个个“单词”,回环检测类似快速查词典的过程,当词典中存在与当前图像高度相似的“单词”时,便是检测到了回环。
回环检测也可以称为闭环检测,是指机器人识别曾到达场景的能力。回环检测提供了当前数据与所有历史数据的关联,在跟踪算法丢失之后,我们还可以利用回环检测进行重定位。因此,回环检测对整个SLAM系统精度的提升,是非常明显的。
建图(Mapping)【构建的地图分为度量地图和拓扑地图】
根据需求,构建相应性质的地图。
侧重于定位时,多采用稀疏的路标地图。
侧重于路径规划自主导航时,则需要稠密的地图,二维Grid、三维Voxel。
侧重于实景建模时,需要对三维地图进一步网格化。

建图主要是根据估计的轨迹建立与任务要求对应的地图,在机器人学中,地图的表示主要有栅格地图、直接表征法、拓扑地图以及特征点地图这4种。而特征点地图是用有关的几何特征(如点、直线、面)表示环境,常见于视觉SLAM技术中。
建图是对前期求解的所以数据进行后处理。根据机器人实际应用场合以及功能的不同,建立的整体图像的类型也不一样。如壁障机器人与导航机器人,它们所需要图像的特点便不一样。当只需要记住一点,建图只是基于前三部分的计算结果,在算法层面相对简单,在应用层面则显得尤为重要。
作业2. SLAM中定位与建图是什么关系?为什么在定位的同时需要建图?
答:定位和建图是相互依赖的,为了精确地定位在环境中,需要一个正确的地图,但是为了构造一个精确的地图,当元素被添加到地图中时,必须精确地定位。
定位:机器人必须知道自己在环境中位置;
建图:机器人必须记录环境中特征的位置(如果知道自己的位置);
机器人在未知环境中从一个未知位置开始移动,在移动过程中根据位置估计和地图进行自身定位,同时在自身定位的基础上建造增量式地图,实现机器人的自主定位和导航。
介绍各传感器
视觉SLAM数学表述与框架

假设小萝卜正携带着某种传感器在未知环境里运动,怎么用数学语言描述这件事呢?
首先,由于相机通常是在某些时刻采集数据的,所以我们也只关心这些时刻的位置和地图。这就把一段连续时间的运动变成了离散时刻 t = 1 , . . . , K t{\rm{ }} = {\rm{ }}1,{\rm{ }}.{\rm{ }}.{\rm{ }}.{\rm{ }},{\rm{ }}K t=1,...,K当中发生的事情。在这些时刻,用 x x x 表示小萝卜自身的位置。于是各时刻的位置就记为 x 1 , . . . , x k {x_1},{\rm{ }}.{\rm{ }}.{\rm{ }}.{\rm{ }},{\rm{ }}{x_k} x1,...,xk,它们构成了小萝卜的轨迹。地图方面,我们设地图是由许多个路标(Landmark)组成的,而每个时刻,传感器会测量到一部分路标点,得到它们的观测数据。不妨设路标点一共有 N N N个,用 y 1 , . . . , y N {y_1},{\rm{ }}.{\rm{ }}.{\rm{ }}.{\rm{ }},{\rm{ }}{y_N} y1,...,yN表示它们。在这样设定中,“小萝卜携带着传感器在环境中运动”,由如下两件事情描述:
- 什么是运动?我们要考虑从 k − 1 k-1 k−1 时刻到 k k k 时刻,小萝卜的位置 x 是如何变化的。
- 什么是观测?假设小萝卜在 k k k 时刻,于Xk处探测到了某一个路标 y j {y_j} yj,我们要考虑这件事情是如何用数学语言来描述的。
通常,机器人会携带一个测量自身运动的传感器,比如说码盘或惯性传感器。这个传感器可以测量有关运动的读数,但不一定直接是位置之差,还可能是加速度、角速度等信息。然而,无论是什么传感器,我们都能使用一个通用的、抽象的数学模型:
x k = f ( x k − 1 , u k , w k ) {x_k} = f\left( { {x_{k - 1}},{u_k},{w_k}} \right) xk=f(xk−1,uk,wk)
这里uk是运动传感器的读数(有时也叫输入), w k {w_k} wk为噪声。注意到,我们用一个一般函数 f f f 来描述这个过程,而不具体指明 f f f 的作用方式。这使得整个函数可以指代任意的运动传感器,成为一个通用的方程,而不必限定于某个特殊的传感器上。我们把它称为运动方程。与运动方程相对应,还有一个观测方程。观测方程描述的是,当小萝卜在 x k {x_k} xk位置上看到某个路标点 y j {y_j} yj,产生了一个观测数据 z k , j {z_k,j} zk,j。同样,我们用一个抽象的函数h 来描述这个关系:
z k , j = h ( y j , x k , v k , j ) {z_{k,j}} = h\left( { {y_j},{x_k},{v_{k,j}}} \right) zk,j=h(yj,xk,vk,j)
这两个方程描述了最基本的 SLAM 问题:当我们知道运动测量的读数 u u u ,以及传感器的读数 z z z 时,如何求解定位问题(估计 x x x )和建图问题(估计 y y y )?这时,我们把 SLAM问题建模成了一个状态估计问题:如何通过带有噪声的测量数据,估计内部的、隐藏着的状态变量。状态估计问题的求解,与两个方程的具体形式,以及噪声服从哪种分布有关。按照运动和观测方程是否为线性,噪声是否服从高斯分布进行分类,分为线性非线性和高 斯非高斯系统。其中线性高斯系统(Linear Gaussian, LG 系统)是最简单的,它的无偏的最优估计可以由卡尔曼滤波器(Kalman Filter, KF)给出。而在复杂的非线性非高斯系统(Non-Linear Non-Gaussian,NLNG 系统)中,我们会使用以扩展卡尔曼滤波器(ExtendedKalman Filter, EKF)和非线性优化两大类方法去求解它。
SLAM问题的数学描述资料
实践: Linux下的C++编程基础
linux相关知识
ubuntu 最常用的快捷键和命令
3.ubuntu 打开终端快捷键:
| 快捷键 | 含义 |
|---|---|
| ctrl + alt + T | 打开新的终端 |
| shift + ctrl + T | 在当前终端同级打开新的终端 |
2.在ubuntu的终端复制、粘贴的快捷键:
| 快捷键 | 含义 |
|---|---|
| ctrl+shift+v | 粘贴 |
| ctrl+shift+c | 复制 |
1.常用命令:
| 命令 | 对应英文 | 含义 |
|---|---|---|
ls | list | 查看当前文件夹下的内容 |
ls -alal | ||
pwd | print wrok directory | 查看当前所在文件夹 |
cd [+目录名] | change directory | 切换文件夹 |
touch [+文件名] | touch | 如果文件不存在,在当前目录下新建一个文件 |
vim [+文件名] | Vi IMproved | 以vim方式打开文件 |
cat [+文件名] | concatenate | 查看文件内容 |
mkdir [+目录名] | make directory | 在当前目录下创建一个文件夹(创建目录) |
rm [+文件名] | remove | 删除制指的文件名 |
clear | clear | 清屏 |
注:liunx下每一个目录都有权限(红叉表示不可访问);权限机制(root为超级管理员)
安装,下载文件
克隆github上的代码
1.通过执行sudo apt get install git 命令来下载git工具
2.或先添加依赖项,更新后,再安装
sudo add-apt-repository ppa:git-core/ppa
sudo apt-get update
sudo apt get install git
git --version
3.下载
这一步用git clone命令搞定,比如我现在要从github网站上的用户raulmur的仓库ORB_SLAM2中下载全部文件
只要在终端中,进入要存放代码的文件夹中,再用git clone命令+该仓库的网址(SSH或HTTP,在”clone or download”按钮的下拉菜单中选择网址复制即可),就可以完成。
git clone https://github.com/raulmur/ORB_SLAM2
终端会显示下载进度
视觉SLAM十四讲:从理论到实践 第一版电子版PDF
链接:https://pan.baidu.com/s/1SuuSpavo_fj7xqTYtgHBfw
提取码:lr4t源码
github链接:https://github.com/gaoxiang12/slambook.git视觉SLAM十四讲:从理论到实践 第二版
电子版PDF
链接:https://pan.baidu.com/s/1VsrueNrdqmzTvh-IlFBr9Q
提取码:vfhe源码
gittee链接:https://gitee.com/gnef233/slambook2.git
git clone https://gitee.com/suyunzzz/slambook.git
安装相应的包(软件包、依赖库等)
安装命令:sudo apt get install
安装cmake、gcc(编译器)、g++(c++的编译器) 、build-essential(编译器)【默认的 Ubuntu 软件源包含了一个软件包组,名称为 “build-essential”,它包含了 GNU 编辑器集合,GNU 调试器,和其他编译软件所必需的开发库和工具。】
sudo apt get install cmake gcc build-essential
代码运行相关知识
ubuntu下用CLion首次跑C++(CMake练习)
CMakeLists 的使用
作业:【视觉SLAM十四讲】第一章
使用视频运行 ORB-SLAM2(第一章实践作业)-myvideo练习
作业详解:链接
和工具。】
sudo apt get install cmake gcc build-essential
代码运行相关知识
ubuntu下用CLion首次跑C++(CMake练习)
CMakeLists 的使用
作业:【视觉SLAM十四讲】第一章
使用视频运行 ORB-SLAM2(第一章实践作业)-myvideo练习
作业详解:链接
边栏推荐
猜你喜欢
随机推荐
Selenium: Introduction
微信小程序接口调用凭证(获取token)auth.getAccessToken接口开发
I met a shell script
权重等比分配
Swastika line-by-line parsing and realization of the Transformer, and German translation practice (a)
The solution to the inconsistency between the PaddleX deployment inference model and the GUI interface test results
matplotlib pyplot
Speed up your programs with bitwise operations
数据湖:数据同步工具NiFi
用控件当画笔获得bitmap代码记录
对话MySQL之父:一个优秀程序员可抵5个普通程序员
Robot_Framework: Assertion
Error: AttributeError: module 'matplotlib' has no attribute 'figure'
JS的运行原理
Selenium:弹窗处理
从离线到实时对客,湖仓一体释放全量数据价值
微信小程序获取手机号phonenumber.getPhoneNumber接口开发
小白的0基础教程SQL: 安装MYSQL 03
深度比较两个对象是否相同
vsce package 后出现 Command failed: npm list --production --parseable --depth=99999 --loglevel=error异常









![[MySQL] 多表查询](/img/f0/c158750a5a84155ee82729daba2bb3.png)