资讯动态

视觉重定位:层级场景坐标回归如何拆解分类与回归难题

发布时间:2026/10/14 12:55:55 来源:尧图企业网站定制
1. 视觉重定位到底在解决什么问题视觉重定位这个词第一次接触的人容易把它和SLAM搞混。SLAM是一边走一边建图同时知道自己在哪里而重定位是我手里有一张图或者我正站在某个位置拍了一张照片我要算出这张照片对应的相机位姿。换句话说SLAM是连续跟踪重定位是从零开始找位置。这个区别很关键因为它决定了重定位面对的是一个没有先验、必须全局搜索的问题。那为什么重定位这么难核心矛盾在于图像是二维的而位姿是六自由度的三个位置加三个旋转。从一张二维图像反推六自由度位姿本身就是一个高度病态的问题。更麻烦的是现实场景里存在大量重复纹理、光照变化、视角变化、动态物体遮挡这些都会让这张图到底是在哪儿拍的变得极其困难。传统的重定位方案大致分两条路。一条是基于特征点匹配的路线比如把查询图和数据库里的图做特征匹配再用几何验证算位姿。这条路在纹理丰富、视角变化不大的场景下表现不错但一旦遇到弱纹理墙面、大面积重复结构特征点就抓瞎了。另一条是场景坐标回归Scene Coordinate Regression它的思路很直接对查询图里的每一个像素直接预测它在场景三维坐标系里的位置也就是所谓的场景坐标然后拿这些二维到三维的对应关系去做PnP求解位姿。场景坐标回归的好处是不依赖数据库图像的检索和匹配理论上对视角变化更鲁棒。但它也有自己的软肋一个回归网络要同时学会这个像素属于场景里哪个区域和这个区域在三维空间里的精确坐标这两件事的难度完全不一样。前者是分类问题后者是回归问题。让一个网络一肩挑往往两头都不讨好。这篇2020年的工作标题里点得很清楚——层级场景坐标回归而且把分类和回归拆开了。这个拆法不是拍脑袋而是针对上面那个软肋来的。我后面会详细拆解它为什么这么设计、怎么落地、实测中会遇到什么。2. 把分类和回归拆开这个设计到底妙在哪2.1 一个网络同时干两件事的困境先说说如果不拆会怎样。假设你用一个标准的编码器-解码器结构输入一张RGB图输出一张和输入同分辨率的场景坐标图每个像素三个通道代表XYZ。训练的时候用真实位姿把深度图反投影得到每个像素的ground truth坐标然后算L1或者L2损失。这个方案听起来很干净但实际训练时会发现两个问题。第一坐标的数值范围可能很大比如一个房间场景X坐标可能从-5米到5米网络要回归出精确到厘米级的数值对最后一层的数值敏感度要求极高。第二场景里不同区域的坐标分布差异巨大靠近原点的区域坐标值小远离原点的区域坐标值大网络容易在数值大的区域产生系统性偏差。更本质的问题是回归任务对局部歧义非常敏感。比如一面白墙上面的像素看起来都差不多但它们的三维坐标可能横跨好几米。网络看到相似的输入却要输出差异很大的坐标这会让训练信号互相打架。2.2 分类先缩小范围回归再精修层级方案的核心思想是先让网络判断这个像素大概属于场景的哪个区域这是一个分类问题输出的是离散的类别概率确定了大区域之后再在这个区域内做精细的坐标回归。这就好比你要找一个朋友先问他在哪个城市分类再问他在哪条街哪栋楼回归。直接让你报经纬度误差肯定大分两步走每一步的难度都降低了。具体来说场景被划分成若干个空间单元每个单元有一个类别标签。网络的第一级输出是每个像素属于各个单元的概率取概率最高的单元作为粗定位结果。第二级则在这个单元的局部坐标系里回归精确坐标。因为局部坐标的范围小了很多回归的数值稳定性大幅提升。这个设计还有一个隐含的好处分类分支可以提供置信度。如果某个像素的分类概率很分散说明网络对这个位置没把握后续做PnP的时候可以把这个点降权或者剔除。这在传统回归方案里是很难做到的因为回归输出就是一个数值没有天然的置信度。2.3 层级结构带来的训练稳定性从训练角度看分类损失比如交叉熵和回归损失比如Smooth L1的梯度特性完全不同。分类损失的梯度在预测错误时较大能快速推动网络纠正回归损失的梯度则和误差成正比误差大时梯度也大容易导致训练初期震荡。把两者分开各自用适合的优化策略整体收敛会更平稳。我在复现类似结构时发现如果分类分支先单独训练几个epoch让网络先学会大致在哪再联合训练回归分支最终精度会比端到端一起训要高。这个trick在论文里不一定写但实操中很管用。3. 网络结构与坐标编码的具体实现3.1 骨干网络的选择与取舍这类任务对分辨率要求比较高因为场景坐标是逐像素预测的如果特征图下采样太狠边界处的坐标就会糊掉。常见的选择是类似U-Net的编码器-解码器结构编码器用ResNet或者类似的残差结构提取多尺度特征解码器通过上采样和跳跃连接恢复空间分辨率。但这里有个权衡分辨率越高显存占用越大推理越慢。如果目标是实时重定位可能需要在分辨率和速度之间找平衡。一个实用的做法是输出半分辨率或者四分之一分辨率的坐标图然后通过插值恢复到全分辨率。实测下来四分之一分辨率对最终位姿精度的影响通常在厘米级但速度能快好几倍。另一个细节是输入图像的分辨率。如果原始图像是1080P直接喂进去显存吃不消通常会缩放到640x480或者更小。但缩放会损失细节尤其是远处的小纹理。我的经验是如果场景比较大、纹理比较细尽量保持长边在640以上如果场景小、纹理粗480也够用。3.2 空间单元的划分策略空间单元怎么划直接影响到分类分支的难度和回归分支的精度。划得太粗每个单元覆盖的范围大回归分支的负担重划得太细类别数爆炸分类分支容易混淆而且每个单元内的训练样本可能太少。论文里通常采用均匀网格划分比如把场景的包围盒在XYZ三个方向各切若干份形成三维网格。网格的大小需要根据场景尺度和训练数据量来定。一个经验法则是每个单元内至少要有几百个训练像素否则分类分支学不好。如果场景是房间级别几米到十几米单元边长在0.5米到1米之间比较合适如果是更大的室内空间可以适当放大。还有一种更聪明的做法是用数据驱动的方式划分比如用聚类算法根据训练像素的坐标分布来生成单元。这样能保证每个单元内的样本分布相对集中分类边界也更自然。但缺点是单元形状不规则后续局部坐标系的定义会麻烦一些。3.3 局部坐标回归的数值处理确定了单元之后回归分支预测的是像素在该单元局部坐标系下的坐标。局部坐标系的原点通常设在单元中心这样坐标值的范围就是单元边长的一半数值小且对称对网络友好。但这里有个坑如果像素刚好在单元边界附近它的局部坐标会接近边界值而相邻单元的局部坐标定义不同会导致训练时边界像素的标签在相邻单元间跳变。解决办法是在训练时对边界像素做加权降低它们的损失权重或者在推理时对边界像素的分类概率做平滑。另外回归输出通常会经过一个tanh或者sigmoid激活把数值限制在[-1,1]或者[0,1]之间再乘以单元边长的一半映射回实际坐标。这样做的好处是输出有界训练更稳定。但要注意如果真实坐标超出了这个范围比如标注误差导致梯度会饱和所以标注质量要控制好。4. 从坐标图到位姿PnP求解的实操细节4.1 坐标图到2D-3D对应的转换网络输出的是每个像素的场景坐标但并不是所有像素都可靠。需要先做一轮筛选分类置信度低于阈值的像素丢掉回归坐标超出单元范围的丢掉位于图像边缘或者深度不连续处的像素也建议丢掉。筛选完之后剩下的像素就构成了2D-3D对应点对。这里有个容易忽略的点像素坐标要转换到相机归一化平面。也就是说如果像素坐标是(u,v)相机内参是(fx, fy, cx, cy)那么归一化坐标是((u-cx)/fx, (v-cy)/fy, 1)。PnP求解用的是归一化坐标和三维点不是像素坐标直接配三维点。这个转换如果搞错位姿会整体偏移。4.2 RANSAC与PnP的配合有了2D-3D对应下一步就是求解位姿。标准做法是RANSAC加PnP。RANSAC的作用是剔除错误对应因为网络预测的坐标不可能全对总有一些像素会预测偏。RANSAC随机采样最小点集PnP通常需要4个点求解位姿然后统计内点数量迭代若干次后取内点最多的解。这里的内点阈值设置很关键。阈值太松错误对应也被算作内点位姿不准阈值太紧内点太少可能求解失败。一个实用的做法是根据重投影误差来定阈值比如设成2到3个像素。如果图像分辨率高可以适当放宽。还有一个加速技巧如果分类置信度提供了每个点的权重可以在RANSAC采样时按权重采样让高置信度的点更容易被选中。这样能用更少的迭代次数达到同样的精度。4.3 位姿精修与异常处理RANSAC给出的位姿通常还不够精细可以再用所有内点做一次非线性优化最小化重投影误差。这一步用LM或者高斯牛顿都行通常迭代几次就能收敛。异常处理方面如果内点数量太少比如少于20个或者优化后的重投影误差仍然很大就应该判定这次重定位失败不要硬输出一个位姿。在实际系统里失败信号比错误位姿更有价值因为后续模块可以据此决定是否重新尝试或者切换到其他定位方式。5. 训练数据与标注绕不开的脏活累活5.1 场景坐标的获取方式训练这个网络需要每个像素的场景坐标作为监督。获取方式主要有两种。一种是在仿真环境里直接渲染深度图结合相机位姿反投影得到坐标这种方式干净但存在仿真到现实的域差距。另一种是在真实场景里用深度相机或者激光扫描获取三维模型再把模型和图像对齐这种方式更真实但标注成本高。如果场景是静态的可以先用SfM或者激光扫描建一个三维模型然后把每张训练图通过特征匹配对齐到模型上再反投影得到像素坐标。这个流程里对齐精度直接决定了监督质量。如果对齐有偏差网络学到的坐标就是错的后面怎么调都白搭。5.2 标注噪声的处理真实数据里标注噪声几乎不可避免。深度相机的深度值在边缘处往往不准SfM重建的模型在弱纹理区域可能有空洞。这些噪声如果直接拿来训练网络会学到错误的映射。处理办法有几个。一是对深度图做滤波比如中值滤波或者双边滤波去掉明显的离群值。二是对反投影得到的坐标做一致性检查比如同一个三维点投影到多张图上的坐标应该一致不一致的丢掉。三是在损失函数里用鲁棒核比如Huber损失降低离群点的影响。我在处理这类数据时通常会先可视化一批训练样本的坐标图看看有没有明显的系统性偏差。如果发现某个区域的坐标普遍偏了一个固定值那很可能是标定或者对齐出了问题得回去查。5.3 数据增强的边界数据增强在重定位任务里要特别小心。颜色抖动、亮度变化这些通常没问题因为场景坐标和颜色无关。但几何变换就要慎重了如果你对图像做旋转或者裁剪像素对应的场景坐标也会变必须同步变换标签。如果只是简单地对图像做几何变换而不改标签网络会学到完全错误的映射。一个安全的增强方式是只做光度变换不做几何变换。如果一定要做几何变换必须保证变换后的像素仍然在图像范围内并且标签同步更新。另外随机遮挡也要小心遮挡区域的像素没有可靠的坐标标签训练时应该把这些像素的损失屏蔽掉。6. 实测中容易踩的坑与排查思路6.1 位姿抖动与帧间不一致如果把这个方案用在视频序列上可能会发现相邻帧的位姿有抖动即使相机没动。原因通常是每帧独立做重定位网络输出的坐标图有随机噪声导致PnP解有微小差异。解决办法有两个方向。一是时序滤波比如用卡尔曼滤波或者滑动窗口平均把历史位姿信息利用起来。二是让网络在时序上更稳定比如输入连续几帧输出中间帧的坐标这样网络能利用帧间信息抑制噪声。后者需要改网络结构成本高一些但效果更根本。6.2 大场景下的类别不平衡场景大了之后空间单元多了分类分支会面临类别不平衡问题有些单元训练样本多有些少。样本少的单元分类精度差进而拖累回归。处理办法包括对损失函数做类别加权让少样本类别的损失权重更大或者在采样时做平衡采样保证每个batch里各个类别的样本数量相对均衡。还有一种做法是合并样本过少的单元减少类别数。6.3 推理速度的优化如果目标是实时应用推理速度是硬指标。网络前向本身可能就要几十毫秒再加上PnP和RANSAC很容易超过预算。优化手段包括降低输出分辨率、用轻量骨干网络、把RANSAC的迭代次数控制在合理范围、用GPU加速PnP。还有一个思路是只在关键帧做完整重定位中间帧用跟踪这样能大幅降低平均耗时。6.4 失败案例的复盘方法重定位失败时不要只看最终位姿对不对要往回查。先看坐标图如果坐标图本身就很乱那是网络的问题如果坐标图看起来合理但PnP失败那可能是对应筛选或者RANSAC参数的问题如果PnP成功但位姿偏差大那可能是标注或者标定的问题。我习惯把失败案例的坐标图、筛选后的对应点、RANSAC内点分布都可视化出来一眼就能看出问题出在哪一环。这个习惯帮我省了很多瞎调参数的时间。7. 这套方案适合什么场景不适合什么场景层级场景坐标回归这套思路最适合的是静态的、有纹理的、尺度中等的室内场景比如房间、走廊、展厅。这些场景里空间单元划分比较自然纹理足够支撑分类和回归尺度也不会大到让坐标数值失控。不太适合的场景包括大范围室外环境因为空间单元数量会爆炸而且室外纹理重复度高分类容易混高度动态的场景因为场景坐标本身就在变网络学到的映射很快失效弱纹理场景比如纯白墙面或者玻璃幕墙因为像素外观区分度太低分类和回归都难做。如果非要在这些场景用可能需要结合其他传感器比如IMU或者轮式里程计用多模态融合来补足视觉的短板。或者把场景坐标回归和特征匹配结合起来用匹配结果来约束回归输出。从工程落地角度看这套方案的门槛主要在数据标注和场景建模网络结构和训练流程反而相对标准化。如果场景固定、可以离线建图那前期投入是值得的如果场景频繁变化、需要快速部署那可能基于检索的方案更灵活。我个人在实际项目里的体会是不要指望一个方案通吃所有场景。层级场景坐标回归在它擅长的场景里能做到很高的精度和不错的鲁棒性但前提是你把数据质量、单元划分、参数调优这些脏活都做扎实了。任何一个环节偷懒最终位姿都会给你颜色看。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑