双目DSO详解
转载 2020-08-11 10:08 斯坦德机器人 来源:斯坦德机器人众所周知,斯坦德机器人(深圳)有限公司是一家专注于工业级移动机器人的研发与生产的国家高新技术企业。目前已实现了从机器人底层定位算法、操作系统、控制器等核心技术的自主研发全覆盖,主要业务为激光SLAM自主移动机器人及柔性物流解决方案。
作为移动机器人行业的龙头企业之一,为了能更好的推动行业技术交流,积极用科技赋能社会,引领工业物流柔性变革,斯坦德机器人将开设“斯坦德机器人大学”学习栏目,和大家分享交流移动机器人相关的产品知识、技术研究经验、项目实施方案、行业销售动态以及市场洞察走向等内容,赋能嘉宾不仅来自于斯坦德内部专业团队,更有神秘行业大咖空降。
本次分享的嘉宾来自斯坦德slam算法技术团队的AndreYe,主要内容是关于双目DSO的详解。
关于DSO
今天我们来讲一讲视觉SLAM相关的东西,当然,既然是技术分享,那得讲点有难度的东西才行。至少,要讲的东西不是满大街都有的才行。所以今天我们来分析一下双目DSO这个东西它到底是怎么实现的。
DSO全称Direct Sparse Odometry,即直接稀疏里程计,是慕尼黑工业大学计算机视觉实验室的Jakob Engel博士在2016年提出的,到今年已经是第4个年头了。但是DSO相关的资料还是非常少,至少对比ORB-SLAM是少得可怜。大概这就是高翔博士所说的历史遗留问题带来的连锁反应吧。不过好在高翔博士在DSO的基础上优化了数据结构(LDSO),至少在前后端数据结构上是清晰了不少,至于DSO这个后端嘛... 希望大家能懂我这个尴尬的笑容: )
正所谓前人栽树后人乘凉,多亏了高翔博士在知乎的分享:DSO详解,这才使得这篇文章可以节省大量的篇幅。有关于DSO一些概念性的问题还有流程,我们大体都不会细究,主要是分析双目DSO和DSO不同的地方。
初始化
首先,先来看看初始化。DSO是一个单目视觉里程计,那么不可避免的会面临初始化的问题。
单目DSO初始化会在最开始的时候会为每一个点赋值深度,随后创建一个深度地图,通常这需要一个特殊的运动轨迹才能完成初始化。另外,在窗口优化以后,需要对新的关键帧提取未成熟点,由于新的关键帧只有一个视角,无法通过三角化得到深度信息,因而这些点的初始化范围通常会被设置为0到正无穷,显然这需要多次滤波才可能让深度值收敛。
双目DSO由于引入了固定基线,通过静态双目约束,可以为系统引入绝对尺度信息。那么它是怎么做到的呢?在初始化的时候,由于双目图像已经通过双目矫正,使得极线在水平方向,因此采用3*5的窗口沿着极线进行NCC搜索匹配,可以得到匹配关系,如果有人觉得3*5这个窗口太小不靠谱,可以尝试一下把它改大一点。通过双目立体视觉可以很容易得到深度信息。因此双目DSO的初始化地图可以直接从单一一个帧得到,无需特定的运动轨迹,简化了初始化的操作。在窗口优化以后,对新提取的未成熟点,同样也是利用双目匹配计算深度信息,为这些点提供一个较小的深度变化范围,在后续的深度滤波过程中可以非常快的收敛。是的,你可以认为对新关键帧提取点之后,给点估计的深度值不需要特别准确,只要包含在该深度范围里就好了,因为后面滤波会让他慢慢收敛的。当然,能准确的估计就更好了,毕竟这会对定位精度带来一定影响。
如图1 我们的NCC匹配效果
窗口优化
窗口优化其实跟单目DSO差不大多,只不过将双目的右目相机考虑进来了。但是这里有一个假设,就是左右目之间的相机内参是一致的。那么结果就变成:每一个关键帧需要优化的变量有14维,其中包括相机内参4维、左相机位姿6维、左右相机各两个光度仿射参数,记作
正常来说,左右相机之间的内参数差别是不大的,如果很不幸,相机的内参数差别较大,那么很可能每一帧需要优化的参数得有18维了。
在窗口优化中,我们会将滑动窗口中的所有关键帧以及激活点(通常DSO窗口中包含7个关键帧和2000个左右的激活点)全部包含进一个优化函数中。
同原文一样,为了方便,这里我们省略了Pattern的记号。这个函数的意思是指将第 i 个关键帧中的点 p 反投影到第 j 个关键帧中,计算二者之间的光度误差。具体怎么反投影的,我们就不在这里展开了,在高翔博士的那篇知乎里写得非常详细。这里我们可以看到,为了对光照变化进行建模,DSO引入了两个光度仿射参数,每一个帧都有一对这样的参数a, b。那么对于双目相机来说,当然得有两对啦。
公式(3)这东西,双目DSO里管它叫动态残差。有动态就得有静态,不然没必要分那么清楚。通过双目固定基线约束引入的残差,就叫静态残差,如公式(4)所示。
与前面介绍的动态残差一样,只不过是将第i 个关键帧中host的激活点,投影到对应的右帧中,构建残差函数。从上面可以看出,双目DSO与DSO差别的地方就在于多了个双目约束。
上面完成了对问题的描述,接下来得进入关键节点了。首先先假设滑动窗口中有 N f 个关键帧, N p 个激活点。于是,我们需要优化的变量有:
优化的操作基本上跟单目DSO基本没有差别,不过需要注意的是零空间需要去除尺度项,毕竟已经提供了绝对尺度了,尺度不确定性的问题就克服了。否则,得到的轨迹仍然是单目的。
边缘化
边缘化的操作跟DSO比起来就更没有什么不同之处了。为了让大家更加方便的看出双目DSO和单目DSO的差别,我们这里做一下对比:
实验
在实验部分,首先我们先看看原论文的这个图(图2),很多人很好奇为什么会需要加一个这样的静态双目权重。这应该算是一个小技巧了,通过引入一个权重,对静态双目更多重视,这样可以让定位更加准确一些。可是作者并没有给出运动轨迹图,这让许多研究人员非常容易忽略这个细节。
图2 双目DSO论文实验静态双目权重
那么我们既然打算写这篇文章,那肯定就本着专业的心态,为大家提供一下这个直观一点的解释。首先先看图3,在未加权重的时候,我们会得到一个比较大的定位误差,在测评的时候这个定位的轨迹绝对误差最高可能会达到46米,最低也不低于10米。从图3中可以看到,红色方框那个区域是导致轨迹误差偏大的主要原因。那么加了权重以后是怎么样的呢?看看图4,这是在加了权重的运动结果,整体应该是比较符合实际情况的,总体轨迹误差大概是在一米左右,属于可接受的范围。
图3 KITTI06未添加双目权重时的估计轨迹与真值轨迹对比
图4 KITTI06添加双目权重后的估计轨迹与真值轨迹对比
后续在KITTI数据集上测试的效果基本上与原文差不太多,所以详细的实验配置大家可以参考双目DSO原始论文即可。最后放几个实验图看看效果。
图5 KITTI06 未添加双目权重的轨迹图
图6 KITT06 添加双目权重的轨迹图
图7 KITTI07添加双目权重的轨迹图
以上,本期关于双目DSO的知识分享就到这里了。如果有感兴趣的学习伙伴、同行朋友,欢迎前来沟通交流【hello@standard-robots.com】