SLAM面试题汇总
要回答的几个问题
1. 单应矩阵 H 和基础矩阵 F 的区别(至少两个方面),推导两者的求解过程及改进求解的方法
答:
- 基础矩阵F和单应矩阵H的区别为所求相机获取图像状态不同而选择的不同矩阵。
- 本质矩阵E和基础矩阵F之间相差相机内参K的运算。
- 只旋转不平移求出F并分解的R,t与真实差距大不准确,能求H并分解得R。
2. 对于单目相机,F和H矩阵有何不同,E和F矩阵有何不同,只旋转不平移能不能求F、能不能求H?
答:
- 特征点共面的时候,或者相机发生纯旋转的时候,基础矩阵自由度下降,会出现退化现象。为了避免退化,会同时估计基础矩阵F和单应矩阵H,选择重投影误差较小的那个作为最终的运动估计矩阵。
- 遇到了纯旋转的情况,t=(0,0,0),H不为零,直接等于$KRK^{-1}$,可以计算出旋转R。x`
3. 本质矩阵E,基础矩阵F,单应矩阵H 自由度分别是多少?为什么?
答:
矩阵的自由度是指:想要解矩阵中的未知参数,需要通过列几个线性方程组?对于nn的矩阵,如果该矩阵存在k个约束,那么其自由度为nn-k。
其中,基础矩阵7个自由度,本质矩阵5个自由度,单应性矩阵8个自由度。
本质矩阵E: 相机的内参K在slam中是已知的,E有五个自由度,所以最少用5对点求E,实际中经常使用8点法;
基础矩阵F: F=\(K^{-T}*E*K^{-1}\),其中E为本质矩阵,E=t^*R
。自由度为7;
意义:F描述的实际是一种点和直线的映射关系,而不是一种点对点的约束关系,并不能给出另一个点的确切位置
应用:可通过E恢复出相机运动的R,t。如果初始化遇到了纯旋转的情况,t=(0,0,0),理论矩阵F为0矩阵,受到噪声影响,由匹配点对推算F矩阵不为0,分解后的R,t受到噪声影响大
单应矩阵H: (Homography Matrix),自由度为8,H 矩阵可通过4对匹配特征点算出(8点);
意义:描述了两个平面的映射关系。准确的来说,H矩阵直接描述了图像坐标p1和p2之间的变换,p2等价于H*p1。\(H=K(R-t*n^T/d)K^-1\);也可以说是,单应矩阵反应的是世界坐标系下平面上的点之间的对应关系,就是现实平面上的点到相机平面上的点的射影变换矩阵,具有8个自由度,就是说单应矩阵就是射影变换。相反,本质矩阵或基础矩阵则没有这个限制。
应用:H不像对极约束,它需要场景的结构信息,它要求场景的点必须在同一个平面上,因此单应矩阵H也就能够对两图像上对应点的提供更多的约束,知道了某点在一幅图像的像点位置后,可以通过单应矩阵,求得其在另一幅图像中像点的确切位置。相机只有旋转而无平移的时候,两视图的对极约束不成立,基础矩阵F为零矩阵,这时候需要使用单应矩阵H,场景中的点都在同一个平面上,可以使用单应矩阵计算像点的匹配点。 相机的平移距离相对于场景的深度较小的时候,也可以使用单应矩阵H。
4. 重定位与回环检测的区别
答:
重定位指的是当跟丢之后重新找回当前的姿态,通过当前帧与关键帧的特征匹配,定位当前帧的相机位姿。
顾名思义,这是“ 重新”定位,当前图像因为和最近的图像或者局部地图之间缺乏足够的匹配,导致机器人无法确定自己的位姿,此时处于当前状态的机器人不再知道其在地图中的位置,也叫做机器人被“绑架”,就说的是人质被蒙上双眼带到未知地方,蒙罩去掉后完全不知道自己在哪里,这时候就需要充分利用之前建好的地图或者存好的数据库。此时机器人需要观察周围环境,并且从已有地图中寻找可靠的匹配关系(一般是关键帧信息),这样就可以根据已有信息“ 重新 ”估计机器人的姿态。
回环检测是为了解决解决位置估计随时间漂移的问题。主要是通过识别曾经到过的场景,将其与当前帧对应,优化整个地图信息,包括3D路标点、及相机位姿、相对尺度信息.
回环的主要目的是降低机器人随时间增加,轨迹中累积的漂移,一般发生在建图过程中。这是因为基于运动传感器或者视觉信息的里程计容易出错,使估计的轨迹偏离其实际真实的情况。通过回环,优化整个地图信息,包括3D路标点、及相机位姿、相对尺度信息。回环检测提供了回环帧与所有历史帧的关系,可以极大减小误差。
回环主要是纠正机器人/相机轨迹,而重新定位在从未知状态找回姿态。两者都需要当前图像预先访问过之前的位置附近,本质上都是一个图像识别问题。
区别:二者目的不同,重定位主要为了恢复姿态估计,而回环为了解决飘移,提高全局精度。之所以容易混淆,可能是因为重定位通常也需要找到与之前帧的对应关系来解出姿态,而这可以通过回环检测来完成。也就是说,二者在匹配帧上可以共享一些算法。然后是第一个问题。专门研究重定位的论文很多,实际在单目VSLAM算法用的比较多的还是基于BoW的匹配方案(ORB-SLAM,VINS等),也有基于机器学习匹配patch的方法(PTAM)。同时也有一些简单粗暴的解决方案,比如单独开线程暴力匹配之前所有关键帧(LSD),或者只扰动初始值不断与上一个关键帧进行匹配(DSO)。
联系
5. ROS中rosrun与roslaunch的区别
先看官网中的说法
rosrun allows you to run an executable in an arbitrary package without having to cd (or roscd) there first.
roslaunch is a tool for easily launching multiple ROS nodes locally and remotely via SSH, as well as setting parameters on the Parameter Server. It includes options to automatically respawn processes that have already died. roslaunch takes in one or more XML configuration files (with the .launch extension) that specify the parameters to set and nodes to launch, as well as the machines that they should be run on.
翻译成中文就是:
rosrun 允许您在任意软件包中运行可执行文件,而无需先在其中进行cd(或roscd)。
roslaunch 是一种工具,可通过SSH在本地和远程轻松启动多个ROS节点,以及在参数服务器上设置参数。 它包括自动重生已经死掉的进程的选项。 roslaunch接收一个或多个XML配置文件(带有.launch扩展名),这些文件指定要设置的参数和要启动的节点以及应在其上运行的计算机。
可以看出:rosrun只能运行一个nodes, roslaunch可以同时运行多个nodes.
roslaunch可以用来启动定义在launch文件中的多个节点,通常的命名方案是以.launch作为启动文件的后缀,启动文件是xml文件,一般把启动文件存储在取名为launch的目录中,用法
$ roslaunch [package] [filename.launch]
可以看出:rosrun是运行一个单独节点的命令,如果要运行多个节点,则需要使用多次rosrun命令,roslaunch采用xml的格式对需要运行的节点进行描述,可以同时运行多个节点,例如
<launch>
<node name="listener" pkg="rospy_tutorials" type="listener.py" output="screen"/>
<node name="publish_on_shutdown" pkg="rospy_tutorials" type="publish_on_shutdown.py" output="screen"/>
</launch>
可以同时运行listener和publish_on_shutdown两个节点。