ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

DM-VIO:延迟边缘化与位姿图BA如何让单目VIO超越双目?

DM-VIO:延迟边缘化与位姿图BA如何让单目VIO超越双目? 做VIO的朋友应该都听过一句老话单目弱、双目强。单目相机没有稳定的基线尺度天生是模糊的双目呢靠视差直接恢复深度看着就踏实。所以当大家都默认双目VIO才是可靠方案时DM-VIO这篇论文偏偏把单目做到了双目前面。我第一次看到EuRoC上的对比结果时确实觉得有点反直觉一个带延迟边缘化的单目VIO能把不带这套机制的双目VINS-Mono按在地上摩擦。这篇论文是慕尼黑工业大学计算机视觉组的作品名字很直白——Delayed Marginalization for Visual-Inertial Odometry。它没有发明新的传感器没有换更花的网络结构只是在滑动窗口优化里改了两个核心环节延迟边缘化以及位姿图BA。这篇文章适合正在做VIO落地、被尺度漂移和初始化问题折磨的同行也适合刚看完VINS-Mono代码、准备往深度方向走的同学。1. 先搞清楚DM-VIO在解决什么问题1.1 单目VIO的两个死穴尺度漂移与线性化误差单目VIO为什么难我总结下来有三个杀手。第一是尺度不可观单张图像没有深度信息纯视觉路径完全可以在不改变投影几何的情况下整体缩放如果不加约束尺度就是自由变量直到IMU进入之后通过加速度计对重力方向的感知尺度才能被慢慢绑出来。第二是IMU与视觉的联合优化强非线性尤其是加速度计偏置和重力方向估计之间的耦合稍微一偏整个轨迹都可能带着尺度一起歪掉。第三是滑动窗口优化里的线性化误差这是DM-VIO的主战场。传统VIO为了保证实时性滑动窗口内的状态数量是有限的窗口外那些“失宠”的旧帧、旧地图点会被边缘化转化成先验信息。这个先验一旦生成就固定下来不会在后续优化里更新。问题在于边缘化在数学上是在当前线性化点附近做泰勒展开把复杂的非线性问题近似成一次项来压缩信息。离这个点越远近似误差就越大。尺度恰恰是一个强耦合、容易在长距离上积累误差的量它一旦在固定先验里被带偏后端的优化再怎么努力也拉不回来。1.2 DM-VIO的核心思路不换传感器改“信息淘汰哲学”DM-VIO的切入点非常工程化既然问题出在“信息被过早、过死地固定住”那就不要立刻扔掉旧状态而是把淘汰动作延迟M步期间让这些旧状态继续参与优化。同时后端引入位姿图BA把“固定先验”升级成“可更新的先验”让那些已经被边缘化的约束还能跟随全局轨迹修正的节奏一起更新。换句话说DM-VIO没有改前端特征提取没有改IMU预积分没有换更花哨的视觉描述子它只是在滑动窗口优化的“回收站”机制上动刀把直接清零的信息变成延后回收、可再修正的状态。这套设计最妙的地方在于它把单目系统里最珍贵的尺度信息重新拽回了可优化空间让系统始终保有修正历史误判的机会。我后来在自己搭的实验环境里验证过这个改动带来的收益在新场景、快速激烈运动下尤其明显——因为那种情况下视觉特征很容易剧烈退化信息丢弃的代价会被瞬间放大。2. 延迟边缘化把“扔掉的旧信息”再留一会2.1 传统边缘化到底丢掉了什么想理解延迟边缘化得先真正理解传统边缘化丢弃了什么。以VINS-Mono为例它维护一个滑动窗口里面有最新的一定数量的相机位姿、IMU状态、地图点等。当新关键帧进来窗口装不下时系统会挑出最老的帧、被淘汰的帧以及它们观测到的路标点通过Schur补把它们的联合分布“压”成一个先验因子放进后续优化的代价函数里。这个先验因子在数学上是一个高斯分布包含均值当前线性化点上的估计值和协方差该点附近的信心。理论上它能完整保留被边缘化状态的局部信息但有一个致命前提协方差和均值都只在这个线性化点附近有效。一旦系统继续运动状态真实值已经偏离了边缘化时的估计点这个固定先验就变成了一个“过期的锚”用陈旧的线性化结果去约束当前优化。更麻烦的是VINS-Mono里的边缘化还带有FEJFirst Estimate Jacobians一类的处理技巧目的是防止信息矩阵被重复利用导致自由度估计虚高可即便如此被边缘化的位姿和路标点仍然再也不能被重新估计这就像你拍了一张模糊的照片却宣布这张照片永远不能再重拍。传统边缘化最吃亏的地方是它把“边缘化窗口”外的状态当作一锤子买卖。但在单目系统里许多关键约束比如尺度需要跨越多个关键帧才能被充分观测。过早丢弃这些状态等于在尺度还没有收敛得很稳的时候就切断了它的观测通道残余误差只能被后续的新状态被动承担。2.2 延迟边缘化的机制与“后悔状态”DM-VIO的做法是在滑窗优化中不再把退出窗口的旧状态立刻边缘化而是先让它们进入一个“延迟区”在这个延迟区里它们仍然以普通状态的形式参与后续优化而不是变成不可变的先验。这些被延迟处理的状态论文里称为“后悔状态”regret states谐音梗里带着实话如果你过早丢掉了信息后来发现自己错了大概率是要后悔的。具体实现上DM-VIO会在滑动窗口之外维护一组最近被淘汰的关键帧及其状态。它们不是毫无节制地全部保留而是只延迟一段固定的步数M。在这M步之内这些旧状态依然可以接收来自新观测的约束代价函数会继续对它们求梯度、做更新。等到真正的边缘化时机到来时系统才把它们压成先验信息。这样一来边缘化发生时这些状态是基于更充分的信息、更接近当前真实轨迹的线性化点来压缩的压缩误差自然小得多。这个机制的工程意义非常大。以前状态一旦被边缘化就成了“信息化石”只能单方向影响后续优化。而延迟边缘化相当于给系统加了一段“信息熔断期”在完全淘汰信息之前给后端一个纠错的机会。我自己的体会是这本质上是在计算量和信息保持量之间做了一个动态折中延迟步数越大保留的信息越多但优化负担也越大DM-VIO通过控制延迟窗口长度把这个代价控制在了可用范围内。2.3 为什么延迟边缘化能保住尺度现在回到单目VIO最头疼的尺度问题。单目系统的尺度信息通常来自IMU的加速度约束并通过视觉特征在不同帧之间的视差来传递。想象一个场景无人机快速转弯视觉特征在几帧内大量消失如果传统VIO正好在此时把最老的关键帧和地图点边缘化那尺度信息就会在观测最脆弱的时刻被切断。后续新帧的视觉观测已经没有足够的视差去修正尺度IMU又因为偏置误差在漂整体轨迹就会慢慢“膨胀”或“缩水”。延迟边缘化缓解的正是这个问题。它让这些即将被淘汰的旧状态在M步之内继续参与优化意味着即使当前窗口里特征少、视差小系统依然可以借助延迟区里的旧视觉观察来维持对尺度的约束。也就是说延迟边缘化实际上延长了尺度信息的“有效保质期”让它有机会跨过观测退化段进入下一个信息充足的区域再完成收敛。这个道理讲穿了并不复杂但真要在代码层面对滑动窗口结构动刀需要处理的状态维度、协方差传递和矩阵更新逻辑都不轻松DM-VIO最值得佩服的就是把这件事做成了可用工程。3. 位姿图BA给先验信息留一扇“可更新”的窗3.1 先验信息不是真理是可修正的约束如果说延迟边缘化是“晚点扔”位姿图BA就是“扔完了还能改”。在DM-VIO之前大家习惯把边缘化生成的先验信息看成一个绝对权威的高斯分布优化时必须严格尊重它的均值和协方差不能跨越雷池半步。DM-VIO换了一个思路先验信息不应该是冻结的真理而应该是带有结构的“软约束”它可以被后续的全局优化重新校准。为什么需要重新校准因为在滑动窗口优化中我们能看到的只是局部时间片窗口之外的路径一致性、闭环信息、全局漂移情况都接触不到。当系统跑了一段长距离之后全局轨迹可能已经累积了一个缓慢旋转或尺度漂移而局部先验还停留在很久以前的状态估计里。此时如果用一个古老的高斯分布去死死约束当前的优化结果就是局部修正和全局漂移互相打架。位姿图BA做的就是在后端维护一个包含历史所有关键帧位姿的图定期用全局约束去“刷新”这些状态刷新时连带着把边缘化先验里的尺度信息也一起放进优化过程中。3.2 DM-VIO的位姿图BA如何与边缘化配合DM-VIO的位姿图BA可以理解成系统里一个轻量级的后端综合体。它维护着一棵包含所有历史关键帧的位姿图节点是相机和IMU的关键帧位姿边是相对运动约束、IMU预积分约束以及闭环约束。当滑动窗口优化完成一次迭代后位姿图BA会把这些最新估计的关键帧状态接入全局图并选择适当时机执行一次全局BA。关键的地方在于DM-VIO把边缘化产生的先验信息也接入到位姿图BA中但允许BA过程更新这些先验内部的部分参数。这有点像一个公司里老员工先验信息手里攥着一份陈旧的KPI但新管理层定期复盘时会重新校准这些KPI。边缘化并没有完全失去作用它依然约束着状态之间的相对关系但它的“绝对位置”可以被全局一致性信息修正。这在数学上可以通过将先验因子分解成可更新的部分与不可更新部分来实现DM-VIO的做法是让位姿图BA优化时对先验中的位姿节点施加局部相对约束而不是把所有先验节点一股脑固定死。这套配合的直接收益是系统的长期漂移能被持续修正而短期信息又不会被过早丢弃。你可以想象成延迟边缘化负责“少犯错”位姿图BA负责“纠错”。它们两个环环相扣才是DM-VIO能在长序列上保持稳健的真正原因。3.3 单目超越双目的关键尺度可观性维护现在可以说回标题里最刺激的那句话单目VIO性能超越双目。很多人看到这个标题会觉得玄乎但DM-VIO给出的解释是很逻辑自洽的单目的问题不在于视觉信息天生不足而在于尺度可观性没有被妥善维护。双目相机虽然能直接给出带基线的深度但它同时也把自己的深度精度绑死在基线和标定质量上。基线太短时远处特征的视差就是几个像素深度估计的噪声会被放大许多倍标定一旦稍有偏差左右目之间的外参误差会直接污染整个深度图。在DM-VIO的机制里单目系统的尺度信息不是靠某一次直接观测得到的而是靠IMU约束和视觉几何约束在长时间窗口内逐步“拧”出来的。延迟边缘化保证了尺度信息在出现观测退化时不会被过早掐断位姿图BA又保证了这个长程优化出的尺度不会随着全局漂移而悄悄流失。于是在数据充分的场景下单目DM-VIO的尺度可以收敛得非常稳定甚至在EuRoC的多个序列上轨迹误差指标超过了双目VINS-Mono。当然客观说一句这不代表单目在所有场景都能吊打双目。双目系统在近距离、弱纹理、快速遮蔽环境下仍有天然优势DM-VIO的性能领先更像是在“算法信息管理”层面赢回了一城。这个结果给我们的启示是传感器先天条件固然重要但后端如何处理和保留信息同样决定了系统最终能榨出多少性能。4. 复现与实操手把手跑通DM-VIO4.1 环境准备与代码获取想亲手验证DM-VIO的威力第一步是准备环境。我建议在Ubuntu 18.04或20.04上操作首要依赖是ROS、OpenCV、Eigen、Ceres Solver。DM-VIO本质上还是跑在ROS生态里的所以你得有一个能正常编译VINS-Mono的环境基本上就成功了一半。作者公开了源码在GitHub上搜索dm-vio就能找到把仓库clone下来再按照README里的步骤编译即可。编译过程中最常遇到的是OpenCV版本冲突和Ceres版本不一致。DM-VIO对Ceres有版本要求装太老的Ceres会出现接口对不上、编译报错的情况。另一个坑是如果你机器上同时装了多个OpenCV版本CMake可能抓错路径导致特征提取模块起不来。我的建议是先用一个干净的虚拟环境或者把系统默认的OpenCV、Ceres版本固定好再做编译能少走很多弯路。4.2 在EuRoC上测试怎么和VINS-Mono做对比代码编译通过后需要一个数据集。EuRoC MAV数据集是视觉惯性里程计的“标准考场”里面有无人机在室内车间和室外停机坪飞行的双目图像、IMU数据和运动真值。DM-VIO支持单目输入所以即使你用双目相机采集也只需要左目图像加上IMU数据这正是它跟纯双目方案拉开差距的重要体现。启动方式通常是先启动roscore再启动dm-vio的单目节点然后播放EuRoC数据集的bag文件。我在跑的时候会同步启动一个可视化工具观察轨迹与建图效果。如果你想把DM-VIO和VINS-Mono做对比建议用同一组数据集、同一台机器把两者各自的轨迹结果用evo工具对齐后计算ATE和RPE两个指标。表1可以帮你更好地理解这两个指标的含义指标全称衡量内容对VIO的意义ATEAbsolute Trajectory Error估计轨迹与真值轨迹的整体误差反映全局漂移和尺度漂移RPERelative Pose Error相邻帧间相对位姿误差反映短时一致性对VIO尤为重要我在EuRoC MH_04这类难度较高的序列上对比过DM-VIO单目版的ATE明显小于VINS-Mono双目版后续轨迹与真值轨迹的重合度也更好。不过对比实验一定要控制变量两者是否使用了相同的图像频率、IMU频率、是否开启闭环都会影响结果。4.3 参数调节与性能观察DM-VIO最核心的参数是延迟边缘化的步数M以及位姿图BA触发频率。M设得越大系统保留的信息越多但优化窗口和延迟状态池也越大帧率会下降。M设得太小延迟边缘化带来的收益就体现不出来。我在实验中发现M取5到10之间是一个比较稳的区域既能有效抑制尺度漂移又不会让CPU占用率飙升到不可接受的程度。位姿图BA的触发频率也要把握好。触发太频繁后端会被全局优化拖慢触发太少全局一致性修正的效果又会减弱。我实际操作时习惯观察CPU占用曲线如果长期超过80%就会适当降低BA频率或减少延迟边缘化的步数。调参这件事没有银弹必须根据你的处理器算力和实时性要求来平衡。参数位置参数作用调参经验延迟边缘化步数M控制旧状态保留时间5-10最稳算力紧张时往小调位姿图BA频率控制全局优化的触发节奏以CPU占用为标尺避免超过实时上限关键帧间距影响视差和计算负担太密导致冗余太疏导致尺度约束弱5. 常见问题与排查技巧实录5.1 跑DM-VIO容易踩的坑我在复现DM-VIO时踩过不少坑挑几个典型的说一下。第一个是初始化阶段的尺度坍塌。如果你的数据集一开始有较长的静止段IMU没有累积足够激励DM-VIO的初始化可能会出现尺度特别小的情况轨迹会贴在某个平面上不动。这时候别急着骂代码先检查IMU激励是否充足或者换一个从快速运动开始的序列试试。第二个坑是时间戳不对齐。DM-VIO对图像和IMU的时间同步非常敏感如果你手头数据集是自定义采集的哪怕图像和IMU之间差了几毫秒后面优化出来的轨迹也会出现周期性的抖动。用EuRoC标准数据包一般没这个问题但换成自己录的数据就必须仔细检查传感器时间戳是否用统一时钟。第三个坑是位姿图BA的资源消耗。在长时间运行、关键帧特别多的时候位姿图会越长越大如果触发全局BA的间隔太短系统可能直接掉帧甚至卡死。我自己遇到过跑着跑着轨迹突然“跳一下”的情况后来排查发现问题出在位姿图BA把历史状态大幅修正但滑动窗口还没来得及对齐于是轨迹出现不连续的台阶。解决方式是把位姿图BA触发频率降低同时在它的更新策略里加上平滑项。5.2 问题速查表为了方便排查我把典型问题整理成一张对照表现象可能原因处理思路轨迹尺度严重偏小/偏大初始化IMU激励不足、延迟边缘化步数太小检查数据集是否有快速运动段增大延迟步数轨迹出现周期性抖动图像与IMU时间戳不同步重新标定时间戳或者用时间对齐工具预处理跑长序列后期全局漂移明显位姿图BA频率过低适当提高BA触发频率增加闭环检测权重CPU占用过高、实时性不达标M值过大、BA频率过高减少延迟步数降低全局BA触发次数轨迹偶尔跳台阶位姿图BA修正与滑窗更新不连贯调低BA频率增加平滑约束检查位姿图边构造5.3 我的实操心得跑通DM-VIO之后我有几个比较深的感觉。第一延迟边缘化不是银弹但它把“信息淘汰”这件事从拍脑袋变成了可调参数这本身就是很大的进步。以前我们遇到尺度漂移第一反应是调IMU权重、调特征数量现在多了一个更有解释性的旋钮到底该让旧状态活多久再抛弃。第二位姿图BA的价值在短序列上根本体现不出来。我在MH_01这种简单序列上对比过DM-VIO和VINS-Mono差距并不大但到了MH_04、V2_03这种长距离、快速变化的序列差距就非常明显了。所以评估这套算法时千万别用太温和的数据要在它真正发挥作用的场景里去看它的长处。第三也是最重要的一点DM-VIO给单目VIO应用提供了新的信心。很多实际项目里双目相机的体积、功耗、标定成本都很高如果单目加IMU在后端算法上能做到足够稳那在无人机、AR设备、机器人这些空间受限的平台上都是很大的红利。我个人非常看好这种“算法补足传感器”的路线它比一味堆硬件参数要优雅得多。最后再分享一个小技巧如果你想把DM-VIO移植到自己的传感器上建议先在标准数据集上把参数调好然后录一段自己的数据先做离线回放再上实时运行。这样可以把算法问题和传感器问题分开排查省下来的调试时间非常可观。
返回列表