此系列的目的是为了让同学们能快速入门高翔博士的《视觉SLAM14讲》这本书。这本书的内容包含两个方面:理论与实践。本来是打算按原著的章节一章一篇博客来写。考虑到程序实践部分的复杂性,决定将代码调试专门用一篇博客来解决,因此目前的内容主要与理论部分有关。
一、内容简介
SLAM--Simultaneous Locatization and Mapping,即同时定位与地图构建的缩写。视觉SLAM就是基于计算机视觉的SLAM,它是一种让计算机对摄像机拍摄结果进行数据处理,获得摄像机位姿以及目标位置的系统。
摄像机可视为一个刚体,因此其运动包括其上某一点(一般选光心)的平动以及摄像机的转动两方面。前者涉及摄像机的位置,后者涉及摄像机的姿态,二者合称位姿。为了在三维空间中表示摄像机的位姿,首先要建立参考坐标系。坐标系根据原点和坐标轴方向的不同分为很多种,好在后面的章节会介绍变量在不同坐标系下的变换方法,因此暂时不必纠结于这个问题。在三维度空间中摄像机(光心)位置可用其在某个参考坐标系中位矢(从坐标系原点指向摄像机光心)投影的坐标列阵来表示;位姿可用其体固联坐标系相对参考坐标系的三个旋转角偏航--俯仰--滚转
来表示。观测对象即地图上的任何一个特征点都可以用一个三维坐标
来表征。摄像机对地图进行观测时,可以同时获得很多个特征点的坐标
。
显然,在已知摄像机位姿和
以及地图特征点坐标
的情况下,并不难计算特征点在摄像机中的观测值
。假设
和
均为世界坐标系(地面坐标系)中的投影结果,
为摄像机相对地面坐标系的三个旋转角,
为观测结果在相机坐标系中的投影,则
(1)
其中表示从世界坐标系到相机坐标系的坐标变换矩阵,基于
可根据坐标变换理论计算得到。在实际应用中,摄像机的位姿
和
以及地图特征点位置
往往是未知的,而观测结果
则是已知的。SLAM的目的就是根据观测结果
反过来计算摄像机的位姿以及
和
以及地图的特征点位置
。这个问题好比我们小学时候思考过的鸡兔同笼问题类似。如果已知鸡和兔的数量,要计算脚和头的个数并不难,但反过来在已知脚和头的个数求鸡和兔的只数就比较复杂了。读初中后我们就发现,解决鸡兔同笼这类问题应当用解方程的方法来解决。因此,SLAM问题可以类似地先引入摄像机的位姿
和
以及地图特征点位置
这两个未知数,然后通过罗列求解观测结果
的过程得到一组方程;最后将
视为已知数,
和
视为未知值,通过求解这组方程来确定
和
。
在实际应用中,这个问题会变得更为复杂,我们需要介绍一个解决此类问题的统一理论框架,然后关注某些特别情况下的此类问题求解。首先观测结果中可能包含随机误差,且观测模型不一定如式(1)所示。考虑到这两方面因素,可以将观测方程改写为
(2)
其中表示
时刻的摄像机状态,即某种位姿
和
;
此时刻的目标位置,即
;
表示摄像机相机观测模型,可以是式(1)或其他更复杂的表达式;
是这个时刻的观测噪声或随机误差;
表示观测结果。其次,明确更多的关系或罗列更多的方程相当于为模型的求解提供更多的信息,有助于提高
、
和
的求解精度。好比说,我们若已知相机的运动规律,就可以罗列一个关于
和
的方程。这种运动规律一般可根据刚体运动的动力学(本质就是牛顿第二定律)和运动学模型来描述,不失一般性可描述为
(2)
其中为
时刻的输入,比如相机所受的力和力矩等;
为
时刻的摄像机状态;
为模型噪声,是未建模因素所引起的。之所以会出现
这一项是因为运动模型一般用微分方程来表示,将这种微分方程转换成一阶微分方程组并进一步用差分方程组来近似就会出现
项。
现在我们的目标就是在存在运动噪声和观测噪声
的情况下根据观测结果
来确定摄像机状态
和目标特征点位置
。对于此类问题有两种解法,第一种是每获得一个新的观测值
,马上估算
的值。这种算法称为滤波算法,常见的有卡尔曼滤波和不敏滤波等。因为此类算法在每一时刻仅估算当前的状态
,计算量小,可作为实时算法。另外一种是等收集一定数量的观测值
后,再对一系列的状态
进行估算,这类算法称为优化算法。优化算法的缺点是缺乏实时性,优点是估计结果更精确。这是因为
时刻前状态
的估计会用到
时刻以后的观测值,由于采用了更多的观测信息,其估计结果一般会比滤波算法更为精确。高博书中主要讨论优化算法,作为此书的简化版,此系列博客将只涉及优化算法。
二、实践:编程基础
这部分内容主要涉及项目的构建,即编译和链接等工作。高翔博士在这个章节介绍了三部分内容,分别是基于g++,cmake和IDE的方法。这三种方法只要学一种就可以,g++方法对于大项目太复杂,IDE方法软件很多,一下子难以选择。根据笔者的经验,建议跟着文中的2.4.2节过一遍g++方法,了解程序的编译和链接过程。至于IDE方法,就本书的学习而言感觉还不如cmake,可以暂时不学,因此这里的学习重点在于cmake方法。
因为我们后面的代码运行,以及代码运行前的库安装都要用到项目构建的技术,所以需要认真掌握。对于cmake方法,用于构建项目时简单说就以下几个步骤
(1)找到有CMakefiles.txt文件的目录,在其中建一个目录build;
(2)Ctrl+Alt+T键打开Ubuntu文字界面,通过上一篇介绍的目录操作方法(即命令cd)进入build目录
(3)输入cmake ..并回车
(4)输入make并回车,如果要加快编译,可输入make -j4或make -j8
(5)对于需要安装的软件,最后还要输入sudo make install
(6)对于高翔博士书上的程序,要运行的话还要输入make后生成的可执行文件并回车。
三、小结
这章的学习可简要归结如下:
1.阅读本博客第一节,了解SLAM技术的核心内容,以后的章节都是基于这个内容展开的。
2.阅读高翔博士书上2.4.2了解项目构建的基本原理并了解g++。阅读2.4.3节学会使用cmake的基本步骤。阅读2.4.4节了解库的生成和使用方法。
3.回顾本博客第二节,你是不是觉得自己在cmake技术上还是有所欠缺?这就对了,这里推荐高博所推荐cmake的辅读材料,免费链接如下。同学们花点时间读一下,以后可结合高博士所提供代码中的CMakefiles.txt文件,逐渐学会自己写CMakefiles.txt文件。
至此,你已经为视觉SLAM学习做好了基本准备。后续的章节均是围绕本博第一节内容展开的,比如第三章的主要内容就是摄像机运动描述;第五章是观测模型描述;第四和第六章则是关于模型求解的方法研究等。