news 2026/10/16 23:50:44

动态环境下的视觉SLAM与SfM:干扰源分类与处理策略

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
动态环境下的视觉SLAM与SfM:干扰源分类与处理策略

动态环境四个字出现在综述标题里,听起来像一句套话,但真正跑过一版视觉SLAM的人都知道,一个在走廊里来回走动的人,就足以让原本稳定的位姿估计在十几秒内现出原形。运动恢复结构(Structure from Motion)也一样,街景里出现行人和车辆时,离线重建出来的点云会长出一片“幽灵点”。Visual SLAM与SfM在静态场景下拥有成熟的理论框架,工程上也有很多可复用的工具;一旦环境变动态,问题就从“怎么解方程”切换成“怎么先知道哪些方程不能信”。

这篇综述把视觉SLAM、基于运动恢复结构的离线重建,以及多视图几何统一到同一条“动态环境”主线下。上篇先交代问题定义、干扰源分类、主流处理策略和评估逻辑。对准备做动态场景实验的算法开发者来说,这一半内容基本决定了你后面能不能看懂各种新方法的出发动机;对刚接触三维视觉的新手而言,它也是一张很合适的地图。下面是我读上篇时整理的笔记,带着自己的理解讲,不负责逐句转述原文。

1. 动态环境为何是SLAM与SfM的“照妖镜”

1.1 静态假设是两套算法共同的地基

视觉SLAM通常按时间顺序处理图像,实时估计相机自身位姿,同时增量维护一张地图;SfM则拿到一段图像序列或一组照片,离线恢复相机轨迹和三维稀疏点云。两者在实现细节上差得很远,但共享同一套几何前提:场景主体是静止的,图像之间观察到的是同一个刚体世界在不同视角下的投影,相机的运动是引起图像变化的唯一主要因素。

这个“静态假设”平时不太会被察觉,因为大多数公开测试序列都干干净净。可它几乎是两套算法的地基。特征点的匹配依赖它,本质矩阵和基础矩阵的估计依赖它,光束法平差(BA)构建的误差项也依赖它。一旦场景里出现真正的运动物体,这些计算环节里就会混入“按静物来处理”的误匹配。

综述里反复强调一个点:动态问题不是某个模块的缺陷,而是数学框架自身边界之外的东西。你可以在特征提取阶段换更鲁棒的描述子,也可以在位姿优化阶段加更强的核函数,但只要模型假设仍然是“世界静止”,运动物体就永远是一个需要单独处理的例外。所以动态SLAM的研究重点,从来不是把某个基础算法改得更好,而是先教会系统分辨哪些观测属于例外。

1.2 动态目标在四个核心环节上“拆台”

读综述时我习惯把动态干扰拆到具体环节里看。上篇虽然没有用“四个环节”这种说法,但对照原文描述,动态目标主要冲击的是特征匹配、鲁棒位姿估计、局部地图维护和全局优化。

特征匹配阶段,运动目标自身往往纹理丰富。比如一件带条纹的衣服,一辆反光的车身,它们的特征点数量可能比背景墙还要密集。前后帧里,这些点在图像坐标系下确实可以从一个位置移动到另一个位置,但它们对应的三维世界点其实并不固定。于是常规最近邻匹配会给出一个“看起来正确、实际物理错误”的对应关系。

鲁棒位姿估计阶段,常用RANSAC一类方法从匹配点里筛外点。动态目标通常只占画面一部分,少量外点混在内点里,RANSAC还有可能扛得住;但如果运动物体占据画面比例很高,或者纹理极强,外点甚至可能形成伪内点,把正确运动模型往错误方向拉。这是很多算法在动态环境下精度骤降的直接原因。

局部地图维护和全局优化就更隐蔽。动态点的特征一旦被误插入地图,后续帧就会反复往那个错误的三维位置投影,形成持续的误差源。BA阶段为了“让所有点都舒服”,会不自觉地调整相机位姿去迁就那几颗动态点,最终表现为轨迹缓慢漂移、重投影误差居高不下。这也是为什么很多纯SLAM系统在动态走廊里跑一分钟没事,跑十分钟就开始飘。

1.3 综述把“动态”的范围划得比我预想更宽

我原本以为动态环境指的就是行人和汽车,结果上篇给的定义要宽得多。除了物体本身的位移,它还包含物体的形态变化、遮挡造成的外观突变,以及由物体运动引起的阴影和反光变化。用一句话来概括:凡是让同一世界点的图像投影在时间上不稳定的因素,都可以算进动态环境的考察范围。

这个边界有一个很实际的意义。很多工程文档里把动态物体检测等同于“人车识别”,可真正影响视觉定位的往往还包括移动的树影、玻璃幕墙上的反射、被风吹动的衣摆,以及一段墙壁上忽明忽暗的光照。这些因素不改变三维几何位置,却改变光度信息,特征是同一个特征点,但描述子可能完全变了。

当然,综述也画了一条红线:相机自身的运动不被视为环境动态,因为那是需要求解的量,不是干扰。这个区分看似多余,实际上非常必要——如果不先定义清楚,后续分类就会把“场景运动”和“观测运动”混在一起。动态估计的第一步不是识别什么在动,而是明确什么不可以动。

2. 干扰源分类:先把“动态”拆成一张表

2.1 按运动性质划分:刚性、非刚性、微动

上篇对动态干扰源的分类,第一条主线是按物体的运动性质拆成刚性、非刚性和微动。

刚性运动最好处理。人体躯干、车辆、箱子,它们整体做三维刚体变换,依然满足刚性几何约束。算法只需要判断“这个三维点簇是否经历了同一个刚体变换”,就能大概率把动态区域筛出来。这也是早期动态SLAM大多数从几何方法入手的原因,成本低、不依赖预训练模型。

非刚性运动就麻烦得多。人的四肢、飘动的旗子、弯曲的布料,它们的局部仍然刚体,但整体不再满足任何单一三维变换。基础矩阵或本质矩阵只能约束点在极线上的位置,不能约束它必须是某个刚体上的点。于是对极几何能给出一个“弱否定”,却很难给出“强确认”。

微动又是另一个极端,比如树叶在风中抖动、水面波纹、远处草地的轻微摆动。这些运动幅度小、像素位移浅,在特征点层面很难和噪声分开。它们通常不会让SLAM崩溃,却会让局部地图区域持续抖动,最终表现为中等程度的漂移和模糊。综述把这三类分开列出,是为了提醒读者:没有一种单一判定方法能同时覆盖它们。

2.2 按时间尺度划分:短暂遮挡、长期占用、反复经过

第二种分类角度是时间尺度,这个角度在工程里特别重要。

短暂遮挡指行人从镜头前一闪而过,或者车辆快速穿越视野。它造成的最大问题是特征跟踪中断,相机瞬间失去一小片区域的匹配点。对视觉SLAM来说,短暂遮挡最危险的时候正是平移或旋转剧烈的时候,系统失去定位锚点容易产生位姿跳变。

长期占用更棘手,比如一辆停在路边的车,或者靠在墙边不动的人。它们在几何上是“静止”的,常规几何方法会判定为静态点并插入地图。等到物体启动开走,地图里就会出现一块残留的“幻影结构”,不仅污染建图结果,还会在后续定位时诱导位姿估计。上篇特别强调,这类物体属于“潜在动态”而不是“当前动态”,需要语义先验来提前识别。

反复经过则体现为同一位置不断出现、消失的动态占用,比如商场出入口、地铁闸机旁边。它既不形成稳定的地图点,也不制造明显的幻影,却会不断打断局部区域的匹配连续性。长期跑下来,系统在这一带的关键帧质量会明显下降。三种时间尺度对应的问题不一样,这也为后面章节选择“几何先验还是语义先验”提供了依据。

2.3 光照和反射:动态环境里最常见的“隐形干扰”

读到这里我才意识到,之前自己调试建图系统踩过的大坑,其实被这张分类表覆盖得很清楚。某个用玻璃幕墙建筑的场景,白天和下午各跑一遍,重建出来的墙面点云完全不同,不是几何错了,是描述子在反射区域的匹配对不上。这类现象在综述里被归为“光度动态”,并在上篇里被单独列出来提醒。

阴影是最典型的例子。一棵树在阳光下移动阴影,地面本身的几何结构没动,但在图像上,阴影边界处的像素灰度发生剧烈跳变。特征点提取器可能在阴影边界附近找到大量关键点,而前后帧这些点的描述子差异巨大。匹配失败还是轻的,更麻烦的是它可能把位姿估计往错误方向拽。

反光和透明材质同样麻烦。水面波纹、汽车漆面、玻璃窗户都会让原本应该一致的光度模型失真。综述指出,这类“光度动态”通常不能用几何约束来解决,因为投影位置的几何关系没有错,只是观测量不可信。它们需要额外的先验,比如已知类别属性、多曝光融合、或者把特征提取器设计得对灰度变化更钝感。

2.4 一张表把干扰源收拢起来

我读综述时做了一张最小化的汇总表,方便对照后续方法分别解决哪个问题。这张表不是原文原样的章节结构,而是我把上篇内容按自己的理解整理出来的。

干扰类型典型样例主要破坏环节几何方法效果语义方法效果
刚性运动行人、车辆、推车误匹配、地图幻影较好较好
非刚性形变四肢摆动、布料、旗帜匹配、位姿优化较弱中等
微动树叶、水面、草丛局部地图抖动几乎无效无效
长期占用路边停靠车辆、静止人地图幻影、定位漂移无效好
光度动态阴影、反光、光照突变特征描述、匹配无效部分有效

这张表直接决定了你选方法时的优先级。以后看到某个算法声称“在动态场景下效果好”,我会先去查它解决了表格里哪一行,而不是直接去看精度曲线。

3. 上篇方法主线:如何给特征点打上“动态标签”

3.1 几何路径:对极几何和多视图一致性

上篇梳理的方法,最早的一支以几何约束为主,核心思路是“用静态框架反推谁不符合静态框架”。输入是对应点证据,输出是动态点的概率或硬标签,整个流程不依赖语义类别信息。

基础矩阵和本质矩阵是这套路线的核心工具。理想静态场景下,所有正确匹配都严格落在极线上。一旦某个点对应一个动态物体,它就会明显偏离极线约束,在RANSAC循环里被当成外点。单目双帧几何约束就能提供不错的初筛,多视图一致性则更稳,因为同一个动态点会在多帧之间反复呈现不一致,置信度可以累计。

几何方法的优点是泛化性好。你不需要知道“那个东西是人还是车”也能判断它有问题。它的缺点同样明显。对微小运动不敏感,对非刚性形变约束偏弱,对“潜在动态”完全无能为力。一个静止站在路边的人,几何方法一定会把它的特征纳入静态地图,直到它起身才后知后觉地开始处理。综述说得很直接:几何是必要手段,但不是充分手段。

3.2 语义路径:把“会动的东西”提前列进黑名单

语义先验是动态SLAM在深度学习流行后的大分支。目标检测或实例分割网络在跟踪线程之外每帧跑一次,把行人、车辆、骑车人等类别对应的像素区域找出来,直接禁止这些区域的特征点进入位姿估计。有些方法更进一步,把这些区域的特征点标记为“动态候选”,在后续几何校验里再确认一遍。

这种路径最大的好处是能处理长期占用。车停在路边不动,几何方法看不出问题,语义方法却能提前把它认出是“可运动的物体”,主动从地图构建里排除。人在门口站着不动也一样,系统知道它不是一个“固定的雕塑”,迟早会移动,于是干脆不把它计入地图。

但语义路径也有自己的坑。分类器永远长着一双“它认识的眼睛”,只识别训练集里见过的类别。公园里的滑板少年、商场里的清洁机器人、工地上的吊臂,凡是没进过训练集的新物体,都会被当成静态背景。真实动态环境永远有新类别上线,这是我在工程里对语义方法保持谨慎的根本原因。上篇也承认,纯语义方案的召回率上限受模型类别覆盖度限制。

3.3 时序路径:让系统从“历史的动静里”学习

时序先验走的是另一条路:通过连续多帧的变化模式来识别动态区域。最简单的做法是看光流和背景模型是否一致。静止背景的光流场会随着相机运动呈现整体平滑的模式,而动态物体上会叠加快速且独立的光流分量。把这种“不一致”提取出来,就给动态区域打了标签。

这类方法对完全未知的动态物体有效,因为它不依赖类别表。只要物体在画面里产生独立于背景的运动,时序模型就能捕捉。它也很适合在线SLAM场景,因为跟踪线程本来就要计算帧间特征匹配,额外统计光流一致性成本可控。

时序方法的短板是响应速度。它必须观察到连续若干帧后才敢判定“这里有动态”,在物体第一次进入画面的短时间内,系统仍然会把这些点视为正常点。遇到快速穿过镜头的物体,等标签打上时,它已经给位姿估计贡献了至少一两帧的误差。所以时序先验适合做“确认”,不太适合做“预测”。很多综述里提到的混合做法,其实就是让语义负责预测、时序负责确认、几何负责兜底。

3.4 三种先验怎么配合,才是上篇真正想讲的事

把三种路径分开看都不复杂,难的是组合。动态SLAM里常见的一条流水线是:先让语义分割网络给出“疑似动态区域”,再用极线约束检查这些区域的特征点在几何上是不是真的违背了静态模型,最后用帧间时序信息做平滑,防止单帧误检造成标签抖动。这个顺序背后有一套逻辑。

语义先验回答“它可能动”,因为人、车天然具备运动能力。几何先验回答“它正在动”,因为一旦运动确实发生,它必然违反多视图几何一致性。时序先验回答“它一直在动”,用来过滤单帧噪声、填补几何方法暴露的盲区。三个答案重叠得越多,动态标签的置信度就越高。

这套组合逻辑在综述里不算新,但让我印象深刻的是它对“失败模式”的描述。如果只用语义,会把静止的车辆排除掉,地图稀疏,对定位精度不利。如果只用几何,会漏掉潜伏的动态物体。如果只用时序,会产生检测延迟。各自的失败模式几乎互补,所以上篇总结出的方向不是挑选某一种,而是设计一套“谁先发表意见、谁最后拍板”的流程。

4. 动态场景下的评测逻辑:不能只看轨迹误差

4.1 动态序列评测,ATE高不代表动态处理得好

看到这里有一个容易踩的坑:评测SLAM在动态场景下的表现,不能只报绝对轨迹误差(ATE)。ATR衡量的是相机位姿和真值轨迹的偏差,但它不区分误差来源于动态干扰,还是来源于普通累积漂移。一个系统可能因为没有把动态物体剔除干净而恰好产生了“抵消性误差”,ATE数值反而好看。

更麻烦的是,动态场景本身的真值就很有讲究。真值轨迹通常由一个外部定位系统提供,比如运动捕捉设备。但这个真值只描述相机运动,不描述场景里行人的位置。于是同一个序列、同一个位姿真值,有人在评测时把动态物体全部手动标注出来,有人在评测时完全不管。两套标准跑出来的指标根本没有可比性。

综述在上篇建议,评测至少应该分两层看:底层看追踪连续性,也就是有没有明显跳变和跟踪丢失;上层看地图质量,包括动态区域有没有被错误插入静态地图、静态背景有没有被误删。只报一个ATE数字,等于把所有问题都压到一条曲线里,信息量太低了。

4.2 SLAM与SfM对动态物体的“期望”并不一致

视觉SLAM和SfM虽然共享很多几何原理,但它们的输出目标不同,导致动态处理的评价标准也不一样。SLAM在线运行,每一帧都要给出相机位姿,它最关心的是动态干扰会不会造成位姿跳变和地图污染。所以动态物体能不能被“临时屏蔽”比它能不能被“准确重建”更重要。

SfM离线运行,目标是重建整个场景的三维结构。它更关心动态物体是否产生了错误的三角化点。对街景重建项目来说,行人和车辆是纯粹的噪声,重建系统希望把它们彻底滤掉,甚至连痕迹都不要留。但在另外一些应用里,比如影视制作的动作捕捉,动态物体的结构重建本身就是目标。同一条几何流程,前者把动态当垃圾扔掉,后者把动态当宝贝取出,评测标准自然不能共用。

这也解释了为什么综述上篇会反复强调“预留分类任务”。用同一套SLAM系统去处理动态环境,你先得定义好自己的产品要“剔除动态”还是“重建动态”,方法路线会完全不同。我见过不少项目在方案讨论阶段争论用哪种检测网络,实际上应该先争论产品到底要哪个结果。

4.3 公开数据集能说明问题,但不能说明全部问题

动态SLAM领域有几种常见的数据集形态:室内运动捕捉序列,包含大量行人活动的视觉惯性序列,以及自动驾驶场景的影像数据集。它们各有优势,也各有软肋。室内场景真值精确、动态目标可控,但环境外观单一,行人数量最多也就十几个,无法覆盖长期占用和光度动态。

自动驾驶序列场景丰富,但真值计算成本极高,还会引入传感器坐标系对齐误差。最重要的,这些数据集都默认有固定语义类别:车辆、行人、骑行者。如果一个算法的动态处理能力完全依赖语义分割的质量,换个没有“滑板车”类别的环境,效果马上跳水。

综述上篇提到的一个通用建议是把算法拿到没有训练分布的重叠的序列上做压力测试。动态区域占比从5%逐步增加到40%,看系统在哪个区间开始失效。这个压力测试思路很适合工程团队复制,因为它能直接画出一条“动态鲁棒性曲线”,比单个数据集上的百分之零点几的精度差异有说服力得多。

4.4 我发现的最关键“评测变量”:动态比和动态速度

如果让我从评测逻辑里抽出两个最关键的变量,我会选动态比和动态速度。动态比是指动态区域占画面面积的比例。比例很低的场景,鲁棒估计本身就能处理,不需要动态模块;比例超过一定值后,内点数量不够,即使完美剔除动态也会造成退化。

动态速度则是像素层面的运动速度。慢速目标容易被时序方法忽略,快速目标容易形成大位移导致光流失败。这两种变量在真实环境里彼此独立:一辆车慢慢驶过路口可以占大面积,一支笔快速挥动可以占小面积。上篇虽然没有给出某个统一公式,但它对评测条件的强调,已经暗示理想场景应该覆盖“高/低比例”和“高/低速度”的笛卡尔积。

5. 读过上篇之后,我更倾向记住的五条判断

5.1 静态点越充足,动态处理越要保守

很多人误以为动态处理的责任是把所有运动物体都标出来,其实不是。关键目标是保证静态点数量足够且干净,位姿估计才能稳定。如果某个疑似动态区域只占画面很小一部分,即使把它漏掉,RANSAC也能用大量静态内点把外点压住。这时候强行开启动态检测,反而可能把静态点误删,降低内点数量。

我自己的建议是:动态模块的输出不要做成二值标签,而是做成“信任程度”。低于阈值的位置不参与位姿估计,不代表它们不能保留在地图维护的候选区里。这样即使标签出了错,系统损失的也只是一部分信息,而不是直接丧失一片区域的跟踪能力。

5.2 语义模型的“未知类别”问题比精度更致命

语义路径表现出的最终性能往往不取决于模型在公开数据集上的mAP,而取决于它能不能对未知物体保持“不知道自己不知道”的谦逊。在工程现场,新动态物体是常态,一只飞过的鸟、一个倾倒的纸箱、一台自动导引车,都可能不属于任何预设类别。追求更高的分割精度边际收益有限,真正有用的设计是让语义模块输出“未知动态候选”的置信度,交给几何时序模块去确认。

5.3 几何校验永远不要省,哪怕你有最贵重的语义模型

因为语义模型再强,它也会遇到训练分布之外的区域。几何校验是唯一不依赖类别的“物理安检”,你不需要知道物体是什么,只需要确认它是否符合刚体世界的基本规则。把语义检测框里的特征点全部跳过,而不做几何确认,等于把系统命运完全交给训练集的覆盖率。做过一次真实实验就会明白,训练集之外的动态物体往往最容易让纯语义方案现出原形。

5.4 时序平滑模块不是锦上添花,是必须的

特征点动态标签如果单靠单帧判定,一定会在连续帧间来回抖动。同一面墙,这一帧被误判为动态,下一帧恢复静态,就会导致地图点被反复插入、删除,对BA和地图维护的影响非常大。加上时序平滑后,标签更新会考虑历史状态,误检的杂波被抑制,系统整体稳定度显著提升。代价只是少数帧的理解延迟,在大部分场景里可以接受。

5.5 面对真实项目,先测量“动态场景分布”再选方案

最后一个判断偏工程。无论是做扫地机器人、园区巡检还是AR定位,第一步都不是选模型,而是先测量产品看到的到底属于哪种动态干扰。是人物反复穿行,还是车辆长期停靠,还是阳光造成的阴影迁移?对照上篇那张干扰源分类表,每种分布对应的最优方法几乎都不一样。先花一周统计真实数据里的动态占比、动态速度和动态类别,比试十个开源方案都管用。

如果把上篇浓缩成一个动作,我会把它想象成给每一帧画面建立一张“哪些位置暂时不值得相信”的信任地图。静态与动态的分离,从来不是把所有运动物体扔出画面,而是让系统在每一个时刻都知道该把信任放在哪里。对我个人来说,读完上篇收获最大的不是多记了几种方法名,而是学会了先看问题分类再决定用什么工具。这篇笔记的下半部分,再接着整理语义几何融合、稠密重建和实时性之间的取舍。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 23:42:59

计算机二级C语言资源实战:从编译环境到gdb调试的避坑指南

简介:这份资源面向备战计算机二级C语言考试的考生,尤其适合需要系统梳理基础语法与核心考点的在校学生和自学者。压缩包共4个文件,以2个c源码文件为主,另含1个gitignore版本控制配置和1个txt说明文档,整体约9KB&#x…

作者头像 李华
网站建设 2026/10/16 23:30:47

新手做新媒体,零基础多平台分发工具推荐

很多刚接触新媒体的新手,都会遇到一个共同的痛点:写完一篇内容,要挨个打开十几个平台的后台,重复复制粘贴、调整排版、上传封面,半小时的创作可能要花一小时分发。选对一款适合自己的多平台分发工具,能直接…

作者头像 李华
网站建设 2026/10/16 23:28:29

AI项目存储选型:训练数据、模型权重与向量索引如何分层

做模型训练的同学应该都有过这种经历:GPU利用率上不去,显卡在等数据,训练脚本的日志里好半天不见一个step更新。一开始大家会去调模型结构、调学习率,折腾了半天才发现,瓶颈不在算力,在数据喂不上来。进入A…

作者头像 李华
网站建设 2026/10/16 23:15:49

C语言指针数组详解:从二维数组模拟到动态内存分配实战

1. 指针数组为何是“二维”的关键先聊聊我自己的体会。学指针最绕的坎有两个:一个是“指针的指针”,一个是“数组与指针的关系”。而“定义指针数组(二维)”这个标题,恰好把两个坎叠在了一起。很多教材上讲二维指针数组…

作者头像 李华
网站建设 2026/10/16 23:14:40

BusinessSkinForm v8.42 Full Source实战:Delphi皮肤引擎接入与避坑指南

简介:BusinessSkinForm v8.42 Full Source 是一套专为 Delphi 与 CBuilder 开发者打造的界面皮肤组件完整源代码包,解决企业级应用界面美观度不足、控件样式不统一以及皮肤二次定制困难等实际问题,适用于中高级桌面软件开发与组件库维护场景。…

作者头像 李华
网站建设 2026/10/16 23:14:38

OpenSpec:以规范驱动AI编程,终结需求模糊与代码烂尾

聊一个最近在开发者圈子里热度上升很快的词:OpenSpec。如果你这几周一直在刷 GitHub Trending,多少会看到它。我第一次刷到的时候,第一反应是“又一个 Open 开头的协议”,但真正花时间跑了一遍之后,我的判断改变了——…

作者头像 李华