[TOC]
SLAM面经汇总
SLAM通识基础
视觉SLAM方法的分类和对应的特点分析
视觉SLAM可以分为特征点法和直接法。特征点法是根据提取、匹配特征点来估计相机运动,优化的是重投影误差,对光照变化不敏感,是比较成熟的方案,常见的开源方法有ORB-SLAM等。
特征点法的优点:
(1)特征点本身对光照、运动、旋转比较不敏感,因此稳定性更好。
(2)相机运动较快,也能跟踪成功,鲁棒性较好。
(3)研究时间较久,方案比较成熟。
特征点法的缺点:
(1)关键点提取、描述子匹配时间长。
(2)特征点丢失的场景无法使用。
(3)只能构建稀疏地图。
直接法根据相机的亮度信息估计相机的运动,可以不需要计算关键点和描述子,优化的是光度误差,根据使用像素可分为稀疏、半稠密、稠密三种,常见的方案是SVO、LSD-SLAM等。
直接法的优点:
(1)速度快,可以省去计算特征点和描述子时间。
(2)可以在特征缺失的场合,特征点法在该情况下会急速变差。
(3)可以构建半稠密乃至稠密地图。
直接法的缺点:
(1)因为假设了灰度不变,所以易受光照变化影响。
(2)要求相机运动较慢或采样频率较高。
(3)单个像素或像素块区分度不强,采用的是数量代替质量的策略。
视觉SLAM框架及组成
请描述视觉SLAM的框架以及各个模块的作用是什么?
(1)传感器信息读取。在视觉SLAM中主要是相机图像信息的读取和预处理,在机器人中,还会有码盘、惯性传感器等信息的读取和同步。
(2)视觉里程计就是前端,其任务是估算相邻图像间相机运动,以及局部地图的样子。
(3)后端优化。后端接受不同时刻视觉里程计测量的相机位姿,以及回环检测的信息,对它们进行优化,得到全局一致的轨迹和地图。
(4)回环检测。判断机器人是否到达过去先前的位置,如果检测到回环,它会把信息提供给后端进行检测。
(5)建图。根据估计的轨迹,建立与任务要求对应的地图。
激光SLAM中的具体方法有什么?请解释一下每种方法的特点。
激光雷达分为单线和多线两种,单线雷达一般应用在平面运动场景,多线雷达应用在三维运动场景。
(1)单线雷达构建二维地图的SLAM算法称为2D lidar SLAM,包括Gmapping、hector、karto和cartographer算法,在二维平面内运动,扫描平面与运动平面平行。
Gmapping是一种基于粒子滤波的2D激光雷达SLAM,构建二维栅格地图。融合里程计信息,没有回环检测。优点是在小场景中,计算量小,速度较快。 缺点是每个粒子都携带一幅地图,无法应对大场景(内存和计算量巨大);如果里程不准或标定参数不准,在长回廊等环境中容易把图建歪。
hector SLAM是完全基于scan-matching的,使用迭代优化的方法来求匹配的最佳位置,为避免陷入局部极值,也采用多分辨率的地图匹配。 由于完全依赖于scan matching,要求雷达的测量精度较高、角度范围大,扫描速度较高(或移动速度慢)。噪声多、边角特征点少的场景就很容易失败。 原文所提出方法的特点还在于,加入IMU,使用EKF估计整体的6DoF位姿,并根据roll, pitch角将激光扫描数据投影到XY平面,因而支持激光雷达有一定程度的倾斜,比如手持或机器人运动在不是很平整的地面上。
karto是基于scan-matching,回环检测和图优化SLAM算法,采用SPA(Sparse Pose Adjustment)进行优化。
cartographer是谷歌开源的激光SLAM框架,主要特点在于: 1.引入submap,scan to submap matching,新到的一帧数据与最近的submap匹配,放到最优位置上。如果不再有新的scan更新到最近的submap,再封存该submap,再去创建新的submap。 2.回环检测和优化。利用submap和当前scan作回环检测,如果当前scan与已经创建的submap在距离上足够近,则进行回环检测。检测到回环之后用ceres进行优化,调整submap之间的相对位姿。为了加快回环检测,采用分枝定界法。
(2)3D lidar SLAM算法是针对多线雷达的SLAM方法,包括LOAM、Lego-LOAM和LOAM-livox等。
LOAM是针对多线激光雷达的SLAM算法,主要特点在于:1) 前端抽取平面点和边缘点,然后利用scan-to-scan的匹配来计算帧间位姿,也就形成了里程计;2) 由估计的帧间运动,对scan中的每一个点进行运动补偿;3) 生成map时,利用里程计的信息作为submap-to-map的初始估计,再在利用submap和map之间的匹配做一次优化。 LOAM提出的年代较早(2014),还没有加入回环优化。
LeGO-LOAM在LOAM的基础上主要改进:1) 地面点分割,点云聚类去噪;2)添加了ICP回环检测和gtsam优化。
LOAM_livox是大疆2019年公布的面向小FOV Lidar的LOAM算法。相比LOAM,做了一些改动。算法的特点: 1.添加策略提取更鲁棒的特征点:a) 忽略视角边缘有畸变的区域; b) 剔除反射强度过大或过小的点 ; c) 剔除射线方向与所在平台夹角过小的点; d) 部分被遮挡的点 2.与LOAM一样,有运动补偿 3.里程计中剔除相对位姿解算后匹配度不高的点(比如运动物体)之后,再优化一次求解相对位姿。
刚体运动
相似变换、仿射变换、射影变换的区别是什么?
解答1
相似变换相当于等距变换和均匀缩放的一个复合,用S表示变换矩阵,S为3×3矩阵, $$ \mathrm{S}=\left{\left{\mathrm{s}^* \mathrm{r} 11, \mathrm{
S}^* \mathrm{r} 12, \mathrm{tx}\right},\left{\mathrm{s}^* \mathrm{r} 21, \mathrm{
s}^* \mathrm{r} 22, \mathrm{ty}\right},{0,0,1}\right} $$ 左上角2×2矩阵为旋转部分,tx和ty为平移因子,具有4个自由度,即旋转、x方向平移、y方向平移和缩放因子s。相似变换前后长度比,夹角,虚圆点I,J保持不变。
仿射变换相当于一个平移变换和一个非均匀变换的复合,用A矩阵表示,A为3×3矩阵, $$ \mathrm{A}={ {\mathrm{a} 11, \mathrm{a} 12, \mathrm{tx}},{\mathrm{a} 21, \mathrm{a} 22, \mathrm{ty}},{\mathrm{0}, \mathrm{0}, 1}} $$ 其中A可以分解为: $$ \mathrm{A}=\mathrm{R}(\mathrm{a}) \mathrm{R}(-\mathrm{b}) \mathrm{DR}(\mathrm{b}) $$ 其中 $$ \mathrm{D}={ {\mathrm{c} 1, \mathrm{0}},{\mathrm{0}, \mathrm{c} 2}} $$
左上角2×2矩阵为旋转部分,tx和ty为平移因子,它有6个自由度,即旋转4个,x方向平移,y方向平移。它能保持平移性,不能保持垂直性,图像中各部分变换前后面积比保持不变,共线线段或者平行线段的长度比保持不变,矢量的线性组合不变。
射影变换由有限次中心射影的面积定义的两条直线间的对应变换称为一维射影变换,由有限次中心射影的面积定义的两个平面之间的对应变换称为二维射影变换。射影变换是最一般的线性变换,有8个自由度,保持重合关系和交比不变,但不会保持平行性。
解答2
- 等距变换:相当于是平移变换(t)和旋转变换(R)的复合,等距变换前后长度,面积,线线之间的角度都不变。自由度为6(3+3)
- 相似变换:等距变换和均匀缩放(sR,R是正交矩阵,s是缩放因子)的一个复合,类似相似三角形,体积比不变。自由度为7(6+1)
- 仿射变换:一个平移变换(t)和一个非均匀变换(A)的复合,A是可逆矩阵,并不要求是正交矩阵,仿射变换的不变量是:平行线,平行线的长度的比例,面积的比例。自由度为12(9+3)
- 射影变换:当图像中的点的齐次坐标的一般非奇异线性变换,射影变换就是把理想点(平行直线在无穷远处相交)变换到图像上,射影变换的不变量是:重合关系、长度的交比。自由度为15(16-1)
参考:多视图几何总结——等距变换、相似变换、仿射变换和射影变换
给一张图片,知道相机与地面之间的相对关系,计算出图的俯视图。
简单地说利用射影变换,将原本不垂直的线垂直化(用多视图几何上的话说就是消除透视失真),如下图所示 ...
参考:47. 给一张图片,知道相机与地面之间的相对关系,计算出图的俯视图。
四元数的相关概念是什么,请解释一下。
四元数在程序中使用很广泛,但在SLAM中四元数的概念比较难理解。四元数是Hamilton找到的一种扩展复数,四元数具有一个实部和三个虚部: $$ \mathbf{q}=q 0+q 1 i+q 2 j+q 3 k $$ 其中i,j,k是四元数的三个虚部,满足下式: $$ \left{\begin{array}{l} i^2=j^2=k^2=-1 \ i j=k, j i=-k \ j k=i, k j=-i \ k i=j, i k=-j \end{array}\right. $$ 也可以使用标量和向量来表示四元数: $$ \mathbf{q}=[s, \mathbf{v}], \quad s=q_0 \in \mathbb{R}, \mathbf{v}=\left[q_1, q_2, q_3\right] \in \mathbb{R}^3 $$ 在上式中,标量s是四元数的实部,向量v是虚部。
四元数可以表示三维空间中任意一个旋转,与旋转矩阵类似,假设某个旋转是围绕单位向量 $$ \mathbf{n}=[n x, n y, n z] \mathbf{T} $$ 进行了角度为θ的旋转,则该旋转的四元数形式为: $$ \mathbf{q}=\left[\begin{array}{c}
\cos \frac{\theta}{2}, n_x \sin \frac{\theta}{2}, n_y \sin \frac{\theta}{2}, n_z \sin \frac{\theta}{2} \end{array}\right]^T $$ 上式实质上是模长为1的四元数,也就是单位四元数。反之,也可以通过任意长度为1的四元数计算对应旋转轴和夹角: $$ \left{\begin{array}{l} \theta=2 \arccos q_0 \ {\left[n_x, n_y, n_z\right]^T=\left[q_1, q_2, q_3\right]^T / \sin \frac{\theta}{2}} \end{array}\right. $$ 如果某个四元数的长度不为1,可以通过归一化转化为模长为1的四元数。
对四元数的θ加上2π,就可以得到相同旋转,但对应的四元数变为-q。因此,在四元数中,任意的旋转都可以由两个互为相反数的四元数表示。如果θ为0的话,则得到一个没有任何旋转的四元数: $$ \mathbf{q}_0=[\pm 1,0,0,0]^T $$
坐标系转换
世界坐标系(world) 相机坐标(camera) 像素坐标(pixel)
world —— camera:$P c=T c w * P w$
camera —— world:$P w=T c w^{-1} * P c$
pixel —— camera:
$u=f x * X c / Z c+C x ; v=f y * Y c / Z c+C y$
camera —— pixel:
$X c=(u-C x) * Z c / f x ; Y c=(v-C y) * Z c / f y ; Z c=d$
求导 ![img](https://img-blog.csdnimg.cn/5565775bc78e45d6a8b151e978127092.png)
相机模型
相机传感器的分类及其优缺点是什么
视觉SLAM常用的相机包括单目相机、双目相机和深度相机。
单目相机的优点:
(1)应用最广,成本可以做到非常低。
(2)体积小,标定简单,硬件搭建也简单。
(3)在有适合光照的情况下,可以适用于室内和室外环境。
单目相机的缺点:
(1)具有纯视觉传感器的通病:在光照变化大,纹理特征缺失、快速运动导致模糊的情况下无法使用。
(2)SLAM过程中使用单目相机具有尺度不确定性,需要专门的初始化。
(3)必须通过运动才能估计深度,帧间匹配三角化。
双目相机一般有Indemind、小觅和ZED等。
双目相机的优点:
(1)相比于单目相机,在静止时就可以根据左右相机视差图计算深度。
(2)测量距离可以根据基线调节。基线距离越大,测量距离越远。
(3)在有适合光照的情况下,可以适用于室内和室外。
双目相机的缺点:
(1)双目相机标定相对复杂。
(2)用视差计算深度比较消耗资源。
(3)具有纯视觉传感器的通病:在光照变化较大、纹理特征缺失、快速运动导致模糊的情况下无法使用。
深度相机一般有Kinect系列、Realsense系列、Orbbec和Pico等。
深度相机的优点:
(1)使用物理测距方法测量深度,避免了纯视觉方法的通病,适用于没有光照和快速运动的情况。
(2)相对双目相机,输出帧率较高,更适合运动场景。
(3)输出深度值比较准,结合RGB信息,容易实现手势识别、人体姿态估计等应用。
深度相机的缺点:
(1)测量范围窄,容易受光照影响,通常只能用于室内场景。
(2)在遇到投射材料、反光表面、黑色物体情况下表现不好,造成深度图确实。
(3)通常分辨率无法做到很高,目前主流的分辨率是640×480.
(4)标定比较复杂。
单目,双目,深度相机对比
单目:成本低,搭建简单,单目相机有尺度不确定性,需要专门初始化
双目:不需要专门初始化,能够计算深度,基线距离越大,测量距离越远,可以用于室内和室外,标定较为复杂,视差计算比较消耗资源
深度:测量范围窄,噪声大,易受日光干扰,无法测量透射材料,主要用于室内
RGB-D的SLAM和RGB的SLAM有什么区别?
解释相机内外参数
相机内参包括焦距fx,fy,cx,cy,径向畸变系数k1,k2,k3,切向畸变系数p1,p2
其中内参一般来说是不会改变,但是当使用可变焦距镜头时每次改变焦距需要重新标定内参
当图像裁剪时内参cx,cy会发生改变,比如图像从8 * 8变成4 * 4时,cx,cy需要除以2
一般标定工业相机时只需要得到畸变系数k1,k2即可,对于畸变系数较大的鱼眼相机需要得到k3,p1,p2
相机外参分为旋转矩阵R和平移矩阵t,旋转矩阵和平移矩阵共同描述了如何把点从世界坐标系
转换到摄像机坐标系
写出单目相机的投影模型,畸变模型
投影模型一般应该都知道写,但是畸变模型就不一定了…参考《视觉SLAM十四讲》
投影模型如下:
注意啊,这里空间点(相机坐标系下的3D点坐标)是非齐次坐标,而像素变成了齐次坐标,如果空间点也是齐次坐标的话,需要讲变换矩阵写成3×4的矩阵,最后一列全为0;。
畸变模型如下:
(以下参数含义:平面上的任意一点 p 可以用笛卡尔坐标表示为 [x,y]^T , 也可以把它写成极坐标的形式[r,θ]^T,其中 r 表示点 p 离坐标系原点的距离, θ 表示和水平轴的夹角。径向畸变可看成坐标点沿着长度方向发生了变化 δr, 也就是其距离原点的长度发生了变化。切向畸变可以看成坐标点沿着切线方向发生了变化,也就是水平夹角发生了变化 δθ。)
畸变模型分为径向畸变和切向畸变,径向畸变如下:
切向畸变如下:
组合上面两式,通过五个畸变系数找到空间点在像素平面上的正确位置:
1.将三维空间点P(X,Y,Z)投影到归一化图像平面。设它的归一化坐标为。
2.对归一化平面上的点进行径向畸变和切向畸变纠正
3.将纠正后的点通过内参数矩阵投影到像素平面,得到该点在图像上的正确位置
值得一提的是,存在两种去畸变处理(Undistort,或称畸变校正)做法。我们可以选择先对整张图像进行去畸变,得到去畸变后的图像,然后讨论此图像上的点的空间位置。或者,我们也可以先考虑图像中的某个点,然后按照去畸变方程,讨论它去畸变后的空间位置。二者都是可行的,不过前者在视觉 SLAM 中似乎更加常见一些。
如果把一张图像去畸变,写公式,流程
视差d与深度z的关系
在相机完成校正后,则有 z=fb/d,其中d表示视差,b表示基线,f是焦距,z是深度。这个公式其实很好记,在深度和焦距 f 确定的情况下,基线越大,视差也会越大。
图像处理
给一个二值图,求最大连通域
这个之后单独写一篇博客来研究这个好了,二值图的连通域应该是用基于图论的深度优先或者广度优先的方法,后来还接触过基于图的分割方法,采用的是并查集的数据结构,之后再作细致对比研究。
简单实现cv::Mat()
Mat是如何访问元素的?先访问行还是先访问列?
Mat访问像素一共有三种方法:使用at()方法、使用ptr()方法、使用迭代器、使用data指针
(1)使用at()方法:at()方法又是一个模板方法,所以在使用的时候需要传入图像像素的类型,例如:
(2)使用ptr()方法: ptr()方法能够返回指定行的地址(因此正常是先访问行的),然后就可以移动指针访其他的像素。例如
这里需要注意的是,有时候在内存中会为了对齐而会对末尾的像素进行填充,而有时候没有填充。可以使用isContinue()来访问图像是否有填充,对于没有填充的图像,即连续的图像来说,遍历的时候就可以只要一层循环就可以了,他会自己换行将图像变成一维的来处理。
(3)使用迭代器:对Mat类型来说,他的迭代器类型可以使用MatIterator_或者Mat_::Iterator类型,具体使用如下
用这两个迭代器便可以指定Mat对象的迭代器,注意需要传入模板参数。对迭代器的初始化与C++中的STL一致。
遍历也和前面指针一样,从图像左上角第一个像素开始遍历三个字节,然后第二个字节,依次遍历,到第一行遍历完后,就会到第二行来遍历。
(4)使用data指针:用Mat存储一幅图像时,若图像在内存中是连续存储的(Mat对象的isContinuous == true),则可以将图像的数据看成是一个一维数组,而data(uchar*)成员就是指向图像数据的第一个字节的,因此可以用data指针访问图像的数据,从而加速Mat图像的访问速度。
一般经过裁剪的Mat图像,都不再连续了,如cv::Mat crop_img = src(rect);crop_img 是不连续的Mat图像,如果想转为连续的,最简单的方法,就是将不连续的crop_img 重新clone()一份给新的Mat就是连续的了,例如
李群&李代数
介绍一下李群和李代数的关系
解答:如上图所示(摘自《视觉SLAM十四讲》),从李群到李代数是对数映射,形式上是先取对数,然后取∨,从李代数到李群是指数映射,形式上先取∧,再取指数,下面具体说:
三维旋转:李群就是三维旋转矩阵,李代数是三维轴角(长度代表旋转大小,方向代表旋转轴方向),从李群到李代数是分别求轴角的角θ(通过矩阵的迹求反余弦)和向量a(旋转矩阵特征值1对应的特征向量),从李代数到李群就是罗德罗杰斯公式。
三维变换:李群是四元变换矩阵,李代数是六维向量,从李群到李代数同样先求角和向量,然后需要求t,从李代数到李群的话通过上面的公式计算。
为什么要引入李群李代数
旋转矩阵自身是带有约束的,正交且行列式为1,他们作为优化变量时,会引入额外的约束,时优化变的困难,通过李群李代数的转换关系,把位姿估计变成无约束的优化问题。
单应矩阵&基础矩阵&本质矩阵
ORB-SLAM初始化的时候为什么要同时计算H矩阵和F矩阵?
简单地说,因为初始化的时候如果出现纯旋转或者所有特征点在同一个平面上的情况,F矩阵会发生自由度退化,而这个时候H矩阵会有较小误差,因此要同时计算H矩阵和F矩阵,那么这里补充两个问题: