资讯详情

资讯详情

SVO视觉里程计深度解析:特征点法与直接法的融合之道及实践踩坑

SVO这套方案我研究了很多年从最初的论文到源码再到自己在无人机模拟环境里部署算是把它的脾气摸得比较透了。如果你正在视觉SLAM的坑边徘徊或者已经跑过了ORB-SLAM、LSD-SLAM这类经典框架那你一定听说过SVO这个名字。很多人把它简单归类为直接法或者特征点法其实都只说对了一半。SVO的真正身份是一个把特征点法的精度和直接法的速度用一种非常聪明的方式缝在一起的混合方案。这篇文章不打算复述论文原文我想把它拆开揉碎说说它到底是怎么把两种流派缝合起来的为什么缝合之后反而比两边都更适合某些场景以及你在实际跑它的时候会遇到哪些理论根本不会告诉你的坑。1. 特征点法和直接法的内斗给了SVO一个折中答案1.1 特征点法的可靠性天花板精度高但架不住慢先聊点背景不然直接上SVO的架构图你会看得一头雾水。特征点法在早期SLAM里占据了绝对主导地位它的思路很直白图像的本质是像素矩阵但像素本身不包含语义所以先从图像里挑出那些角点、斑点等具有显著纹理特征的关键点然后给每个关键点算一个描述子靠描述子在不同帧之间做匹配匹配上了就能建立2D像素到3D空间点的对应关系再用对极几何或PnP把相机的运动解算出来。这个思路有一个致命优点描述子具备很强的抗干扰能力光照变了、视角偏了、物体稍微动了一下描述子依然能匹配上。所以特征点法的鲁棒性非常强这也是它在众多开源方案中依然活跃的原因。但它的代价也很明显提取特征点、计算描述子、暴力匹配这一整套流程每一步都是计算量黑洞。你想想一张1280×720的图可能提取出上千个特征点每个特征点是128维甚至256维的浮点数组匹配复杂度是O(n²)级别还要做RANSAC剔除误匹配。一套下来单帧处理时间轻松突破20毫秒要是算法写得不够讲究50毫秒也不奇怪。在电池容量和算力都受限的嵌入式平台上这个开销往往直接决定你能不能跑到实时帧率。另一个隐藏问题是特征点的均匀性困局。特征提取算法只管在纹理丰富的地方疯狂出点结果就是墙角、桌角、海报边缘堆满了点而白墙、天空、整片地面这样的低纹理区域几乎没有特征点。相机朝向这些区域转动时位姿解算依赖的点数骤减精度立刻大跳水。1.2 直接法的速度优势与脆弱假设直接法走的是另一条路线它干脆不做特征。像素就是它的特征亮度就是它的描述子。它的核心思路是光度一致性假设同一个空间点在不同帧里的投影位置对应的像素亮度应该是一样的。于是位姿估计就被转化成了一个优化问题——我调整相机的位姿让当前帧所有像素和参考帧对应像素的亮度误差尽可能小。这个思路一度被认为非常优雅因为它跳过了所有特征工程直接对原始数据建模。你可以把直接法理解成地毯式轰炸我不在乎哪个像素长得特别有特点我在乎的是所有像素放在一起能不能给我一致的运动约束。这种朴素的做法让它获得了两大优势一是省掉了特征提取和匹配的时间单帧处理速度能压到5毫秒以内二是它能利用图像中所有的信息即使一条纹理边缘被截断只要亮度梯度还在它就能提供约束。低纹理场景下直接法往往比特征点法活得好。但直接法的问题在于它的基本假设太脆弱了。光照变化让亮度不一致运动模糊让梯度失真甚至相机的自动曝光都会让同一个点的亮度在前后帧里完全对不上。更麻烦的是极端情况下它会把一部分错误的像素当成正确的约束来优化一旦最开始位姿给得不好优化就掉进局部最小值然后整个跟踪就飞了。业内常说直接法快但脆这个评价并不冤枉它。1.3 SVO的折中设计逻辑SVO的全称是Semi-direct Visual OdometrySemi这个前缀说明了一切它不在特征点和直接法之间二选一而是各取了一半。它的聪明之处在于把特征点的作用场景从每一帧压缩到关键帧把直接法的优化目标从全局像素压缩到稀疏特征块。展开说SVO只在关键帧里提取特征点普通帧不提取特征点、不算描述子、不做匹配。普通帧的位姿靠什么定靠稀疏直接法——把上一帧的像素块沿着极线方向做亮度对齐得到本帧的匹配位置然后拿这些匹配结果去解算位姿。到了新的关键帧再重新提取特征点估计新地图点的深度。这样一套下来大部分帧的位姿估计都避开了特征点法的高昂开销却又通过稀疏特征块的亮度对齐保留了直接法的速度优势。这种设计本质上是在问一个问题我到底需不需要每一帧都做特征匹配不需要。特征匹配的鲁棒性我用关键帧来继承直接法的速度我用普通帧来变现。把昂贵的操作稀释到稀疏的帧序列上把廉价的操作留在高频的普通帧上这就是SVO整体架构的底层逻辑。2. 一次完整的SVO位姿估计涉及三大步骤的衔接现在我带你走一遍SVO在一张普通帧上干了什么。这一步非常关键因为它决定了你对SVO整个工作流的理解是否到位。SVO把每一帧的运动估计拆成了三个阶段每个阶段都建立在特定的假设之上。2.1 初始位姿预测恒速模型撑起第一根拐杖任何优化类方法都需要一个初始值直接法尤甚。SVO拿到一帧新的图像时第一步不是提取任何东西而是假设相机在短时间内做匀速运动。这个被俗称为恒速模型的假设在快速实验环境下大概率成立上一帧相对上上帧的相对位姿乘以当前帧相对上一帧的时间间隔就能粗略算出这一帧的位姿。SVO直接用上一帧解出来的运动参数给当前帧一个猜出来的初始值。这一步看似简单却是整个跟踪起死回生的关键。你可以试试随便写一个直接法优化把初始位姿设的单位矩阵优化器大概率会带你去一个完全错误的地方。恒速模型虽然粗糙但它通常能把初始位姿放到正确的误差盆地附近。如果恒速模型失效了怎么办SVO会在更粗的金字塔层级上重新尝试一次对齐相当于把搜索范围放大。我在实际测试中发现相机突然剧烈加速时单靠恒速模型确实不够SVO有一定的容错机制但容错上限并不高这也提醒我们它并不是为剧烈的自由落体运动设计的。2.2 特征对齐把老地图点重新投影到新图像上拿到初始位姿后SVO把关键帧里提取的3D地图点投影到当前帧上。因为初始位姿有一点偏差投影出来的像素位置和真实位置之间大概率有偏移而且每个地图点的偏移方向、偏移大小各不相同。接下来的操作是SVO最核心的特色之一——特征对齐。它对每个重投影的2D位置附近取一个小图像块然后在当前帧和参考帧之间做一个块对块的光度误差求解优化的是这个局部小块的位移。说白了这一步是做了一次mini版本的光流法但用的是已知3D点投影的初始位置以及参考帧里的图像块作为模板。这里有个值得注意的细节这一步完全不涉及相机位姿的改动它只负责把每个点的投影位置修正到更准确的位置是图像层面的对齐。这个设计的妙处在于它让后续的位姿优化拿到的是相对干净的2D-3D对应关系而不是被初始位姿误差污染的脏数据。相当于先把每颗棋子擦干净再来看棋局本身。这个步骤在SVO论文里有个专门的名词叫feature alignment很多看过源码的人把它误当成普通的光流其实不对。普通光流还牵扯到相邻帧之间的纹理假设SVO这里直接用已知参考帧的纹理块约束更明确也不需要在时间上相邻。2.3 位姿精修只优化一个SE(3)经过特征对齐SVO拿到了一组修正后的2D坐标和它初始的3D坐标匹配关系现在进入位姿精修阶段。它采用一个标准的几何误差最小化方案——把每个3D点通过当前的位姿外参投影到成像平面计算投影坐标和特征对齐后的修正坐标之间的重投影误差然后对这个误差函数进行非线性优化优化变量就是相机的6个自由度位姿参数。这一步最大的特点是不优化任何地图点的坐标只优化位姿。为什么因为地图点坐标在关键帧处理阶段已经由深度滤波器定下来了SVO认为在当前跟踪阶段这些点的位置是可靠的不需要每帧都去动它。这在计算上省了一大笔开销因为你不需要维护一个庞大的雅可比矩阵只需要处理一个6维变量的优化问题每一轮迭代里需要求导的项也大幅度减少。实际运行中这个优化迭代收敛得非常快两三轮基本就稳定了。在源码里你会发现SVO对这一步还做了一点非常实用的变通它在优化时会根据梯度和误差项自动调整核函数试图让那些明显是被遮挡或者噪声污染的外点不影响主优化方向。这个机制保证了即便有少数特征对齐给出了错误的位置整个位姿估计结果也不会被带偏。2.4 地图点重投影与耦合跟踪的最终判定位姿精修完之后SVO会把所有已建图的地图点重新投影到当前帧上再次检查它们是否落在图像范围内。如果落进来的地图点数量足够多SVO就认为当前帧跟踪成功继续下一帧如果数量掉得太快SVO会有条件地启动新的关键帧创建流程。这里有一个特别值得聊的细节SVO并不像一些方案那样在帧与帧之间直接接力跟踪它走的是从关键帧出发再回归关键帧的路线。普通帧的作用本质上只是验证关键帧生成的地图点在时间上的稳定性以及顺带把相机的运动细粒度地推算出来。正因为有这个特性SVO对关键帧的质量要求极高关键帧提取出的特征点质量直接决定了后续一串普通帧的跟踪质量我在项目中甚至遇到过某个模糊关键帧导致后续十几帧偏差越来越大的情况最后迫不得已清除了缓存才恢复。3. 被很多人低估的深度滤波器概率建模才是SVO的精髓如果说特征对齐和位姿精修是SVO的骨架那深度滤波器就是它的灵魂。几乎每一篇讲SVO的技术博客都会把重点放在半直接上但说实话真正拉开SVO和普通VO距离的是它对地图点深度值的概率化处理思路。这一部分没看透你对SVO的理解就永远是一个加快版的稀疏光流,仅此而已。3.1 深度滤波器的前置动机为什么不能一次性三角化在特征点法里新地图点的深度通常靠三角化确定同一个3D点在两个视角被同时观测到从两帧相对位姿和2D投影射线做交会算出一个深度值这个值一般只算一次后续如果观测多了就做一次BA优化把位置改改。但SVO做了一个在当年颇具进攻性的决定它不给地图点一次性定案而是给每个点维护一个概率分布这个分布在连续的观测中不断被更新。原因也很实际SVO的位姿估计本身就有误差一次三角化算出来的深度可能被一个像素级的噪声粗暴拉偏。与其相信一次三角化不如为每个点维护一个深度是某个值的可能性模型每次新观测都贡献一点信息量多帧累积之后深度的分布自然收敛到真实值附近。我用一个生活化的例子帮你建立直觉假设你想知道对面楼的一扇窗离你多远但手里只有一把不太准的卷尺。如果你量一次就信一次读数可能骗你但如果同一个位置你用不同角度、不同时间量了十几次取加权平均结果会稳很多。SVO的深度滤波器做的就是这件事只不过它把多次测量取平均升级成了用概率密度函数做递归贝叶斯估计。3.2 高斯均匀混合模型与递归更新公式SVO深度滤波器的核心是假设一个点在当前关键帧观测到的深度值其真实深度服从一个由两部分组成的混合分布一个以当前估计深度为中心的高斯分布代表我大概觉得深度在这个范围附近的连续可能性一个均匀分布代表我完全不知道它在哪里的离散可能性。这个均匀分布的权重实际上是用来吸收测量中的异常值和错配它允许当前观测完全不可信。每次新帧到来深度滤波器会根据当前帧的位姿、地图点的2D极线约束计算一个新的深度观测值并基于观测结果更新高斯分布的均值和方差同时更新高斯分布与均匀分布之间的权重比例。如果连续多帧的观测结果一致性强均匀分布的权重会被压制到很低高斯分布方差越来越小深度值最终被锁定如果观测持续不稳定均匀分布权重会上升这个点会被视为不可靠并被抛弃。这个递归过程需要一套相当精致的场景裁剪策略尤其是在极线方向和不确定性传播上。深度滤波器必须知道当前点的不确定性有多大才能决定沿极线搜索多长的范围。SVO的做法是把当前高斯分布的方差沿着极线投影到图像平面上形成搜索区间。这个区间如果太大你就得在更宽的像素范围内搜索匹配点计算量随之上升如果太小就容易错过真正的匹配位置。SVO能保持实时运行很大程度上是因为它把搜索区间的计算做得非常精准而不是盲目地把搜索范围扩展到整条极线。一个在源码阅读时容易困惑的地方是SVO更新深度滤波器的时机不是每一帧都更新而是只对候选点做概率更新。这些候选点是还没有达到关键帧资格的暂定地图点一旦深度方差收敛到一定阈值候选点就会被转正为正式地图点参与后续的位姿约束如果长时间没有收敛它就会被淘汰。这让SVO在内存和计算资源上都很节俭因为你不会为了一个永远无法确认的点持续付出代价。3.3 深度不确定性如何决定关键帧的生成深度滤波器的另一个顶层作用在于它天然定义了关键帧的生成时机。SVO无需像某些方案那样设定间隔N帧取一个关键帧的机械规则它根据当前所有候选点的深度不确定度来判断如果当前帧提供的视差已经足够让一批候选点的深度方差明显收缩那么继续等待新帧的收益就降低了此时还不如立刻把当前帧升级为关键帧对整批点做一次确定性更新。这种由数据驱动的决策机制让SVO对相机运动的节奏特别敏感相机缓慢平移时它取关键帧的频率会降低因为需要更多帧才能积累足够的视差相机快速旋转或平移时它取关键帧的频率会上升因为视差很快就被攒出来了。我实测下来SVO在室内的走廊场景里取关键帧的间隔大约在8到15帧之间具体数值完全取决于你手里相机的运动速度。这种自适应机制是硬编码的关键帧策略做不到的。4. 实测中的表现与避坑经验低纹理、快速运动和资源陷阱理论聊了一大堆接下来进入工程环节。我在自己的模拟巡检机器人项目里把SVO跑过好几轮也在一个以室内场景为主的自采集数据集上做了细致的压测。坦率地说SVO在不少环境里表现优秀但它有几个非常容易踩的坑每个坑都是论文里很少正面写的。4.1 低纹理环境稀疏法的硬伤无可避免SVO虽然在普通帧上避开了特征提取但它骨子里仍然依赖特征点建立地图。这意味着如果场景本身没有足够多的角点或者纹理边缘SVO会很早进入无点可用的窘境。我测试过一个纯白墙和光滑地板组成的模拟房间SVO在最初几步还能靠少量远处桌椅的边缘勉强维持跟踪但当相机转到一个完全空旷的角落时关键帧提取的特征点数量骤降之后几帧内跟踪就因为点数不足而宣告失败。这种场景恰恰是直接法的强项因为LSD-SLAM可以靠梯度一致的像素块继续推位姿哪怕墙是白的只要有细微的光照梯度它就能找到约束。SVO为了速度牺牲了对低纹理场景的适应力这是它设计上的固有取舍。如果你预感到应用场景里会有大量低纹理区域要么为SVO额外融合IMU或者轮式里程计的数据要么直接换用更强调稠密光度一致性的方案不要硬扛。4.2 快速运动和曝光突变引发的跟踪崩盘SVO对帧间运动的容忍度不算高这主要体现在两个环节一是恒速模型失效二是特征对齐阶段的极线搜索范围受限。我做过一个实验用一台手持相机快速甩过桌面SVO在甩动幅度较大的两个连续帧之间会直接丢失跟踪。它在丢失前不会给你任何预警只是下一帧的位姿估计结果明显跳变或者重投影误差爆炸式增长。另一个比快速运动更隐蔽的问题是曝光突变。SVO的亮度误差完全建立在光照一致性假设上但很多消费级相机都有自动曝光功能你从明亮的窗边转到昏暗的屋内时图像整体亮度会连续变化亮度误差项会被系统性地污染。SVO对这种情况的耐受力比DSO还差一些因为DSO在初始化时会估计一个逐帧的光度校正系数SVO早期的公开版本没有显式维护这个系数。我当时的应对策略是直接把相机固定到手动曝光模式关闭自动增益。如果你的场景必须在自动曝光下运行那就要谨慎评估SVO的长期稳定性。4.3 复现SVO源码时的环境细节与参数调整经验SVO的官方实现基于ROS环境依赖项包括Sophus、Fast角点检测器以及其他几个数学库。我第一次编译的时候遇到了不少麻烦尤其是版本兼容性方面的问题。我的建议是严格锁定在老版本的ROS环境中用系统自带的编译工具链不要轻易升级OpenCV到最新版。SVO的源码对OpenCV接口的变化很敏感升级之后很可能出现无法定位到某几个函数的情况。编译完成后还需要花时间调几个关键参数关键帧之间允许的最小旋转量和平移量、特征对齐的搜索窗口大小、深度滤波器收敛所需的方差阈值。这些参数之间互相牵连比如你把搜索窗口调大能提高对快速运动的容忍度但也会显著增加单帧计算时间你把深度收敛阈值调松关键帧生成会变快但地图点精度会下降长期来看位姿漂移会更明显。我个人的经验是先用原始参数跑几遍数据集观察哪些环节先出问题再针对性地调参。不要上来就是一通乱调因为SVO每个参数的改动都会触发其他模块的链式反应。比如你把旋转阈值调小相机稍微转一下就会触发关键帧关键帧一多地图点数量膨胀后续的位姿优化耗时也会上涨你可能莫名其妙地发现帧率掉了一半却根本不知道根源在哪。5. SVO的横向坐标和主流方案的对比以及它后来的演变5.1 在特征点法和直接法之间SVO站在哪个位置想认识一个方案最好的方式是把它放在坐标系里看邻居。特征点法的代表作是ORB-SLAM它长期霸占着开源SLAM的稳定可靠标签有回环检测、有全局优化地图可以复用精度在缓慢运动场景下表现非常好代价是每帧都要做特征提取和匹配嵌入式平台上很难达到理想实时性。直接法的代表作是LSD-SLAM和DSO。LSD-SLAM偏稠密适合建图任务但位姿精度一般DSO把直接法的稀疏化做到了极致位姿精度非常出色对环境的光度变化也更敏感但缺少回环检测和真正的全局地图复用能力。SVO站在两者的交汇处。它不像ORB-SLAM那样有完整的闭环能力也不像DSO那样激进地抛弃一切特征工程。SVO在轻量级实时VO这个细分领域里几乎没有对手它是最早把速度推向极限的方案之一为后续无人机、嵌入式设备上的视觉惯性导航铺平了道路。5.2 四类方案的关键维度对照维度特征点法代表方案直接法代表方案SVO匹配方式描述子匹配像素亮度对齐关键帧特征点普通帧图像块对齐每帧计算量高中低低对光照变化的耐受力强弱中等低纹理场景适应力弱较强弱回环检测能力原生支持通常不支持不支持地图点精度高可全局优化高光度一致性强中高概率深度收敛典型应用离线建图、精准定位快速里程计无人机、嵌入式实时VO这张表能让你快速判断一个场景是否适合用SVO如果你需要的是长时间、大范围的建图和回环修正SVO不是首选如果你要的是在资源受限平台上把位姿实时跑起来SVO几乎是天生的合适人选。5.3 从SVO到后代的进化从纯视觉到多传感器紧耦合SVO的代码和思路后来启发了一系列更新一代的视觉里程计算法。SVO本身在发布之初只做纯视觉的位姿估计不关心IMU也不做回环。后来的迭代版本开始把IMU数据作为先验信息融合进来形成视觉惯性紧耦合的结构。这个方向上的演化思路非常清晰既然SVO已经能把视觉的计算量压得很低那么把IMU的数据融合进来让恒速模型有更好的初始值同时利用IMU的加速度信息估计尺度就能让整个系统在快速运动和弱纹理场景下都获得明显提升。我在实际测试中深切体会到视觉纯靠纹理信息在某些场景里就是这么无助加上惯性数据之后SVO的可用范围被放大了很多。你可以把它想象成给人配了一根拐杖视觉是眼睛IMU是前庭系统两者一起工作才能让双足机器人在突然被推一把时不至于立刻摔倒。SVO的这条路还印证了一个趋势未来实时SLAM的方向不是某一种方法的胜利而是多种传感器的融合、多种信息源的共识。特征点法和直接法之间的争论在某种程度上已经被新一代方案搁置了它们更关心的是如何在资源约束内最大化可用信息量。SVO作为一个承前启后的节点在理论上依然有非常高的学习价值。最后说一点个人体会如果你问我SVO这套方案最值得学习的是什么我不会说是它的特征对齐速度或者深度滤波器细节而是它整个设计里无处不在的效率意识。SVO几乎在每一个环节都在问同一个问题这个操作有没有必要在当前帧做如果没必要推迟到什么时候做推迟了会不会损失足够多的信息这个问题在SLAM领域里看似简单实际上却是方案成败的分水岭。不少框架功能齐全、精度也高但就是跑不快根源就是它们在每一帧上都重复做了太多次昂贵的事。SVO用关键帧承担主要开销普通帧只用轻量手段这个朴素策略回答了这些问题。所以不管你是要在自己的设备上部署视觉里程计还是只是在校验自己对SLAM架构的理解我都建议你认认真真把SVO的源码过一遍。它的代码量不大模块边界清晰是那种麻雀虽小五脏俱全的典范。读完之后你再去看ORB-SLAM的工程化设计或者DSO的光度模型都会多一层理解所谓先进方案无非是在各种约束条件里做出合适取舍。希望这篇文章能帮你省去一些读源码时的弯路也欢迎大家在实际跑通之后回来聊聊你调参时踩到的坑。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →