2026/11/3 3:56:52

MonoScene单目3D语义场景补全:2D到3D投影与复现调参

MonoScene单目3D语义场景补全:2D到3D投影与复现调参 一张普通的室内照片你能看懂画面里有几张桌子、几把椅子但镜头没拍到的角落、家具背后被挡住的墙根、沙发底下那一片全是一团模糊的猜测。MonoScene 想干的事情就是让模型也只凭这一张图把整个三维空间的占据情况和语义类别一起补出来——哪些体素是地板、哪些是墙、哪些是悬空着的椅子腿全都要给出答案。这就是单目3D语义场景补全Monocular Semantic Scene Completion要解决的问题。它不需要激光雷达不需要多视角输入就是一张 RGB 图输出是一整块带语义标签的体素网格。我接触这个方向是因为手里有个室内机器人导航的小需求深度相机成本压不下来退而求其次只能考虑纯视觉方案。翻了一圈资料MonoScene 算是把“2D 特征怎么合理地送进 3D 空间”这件事讲得比较透的一个方案代码结构也相对干净。下面我按自己复现和改造的实际过程把这个模型的设计思路、关键细节、参数取舍和踩过的坑完整拆一遍。不管你是刚接触 3D 视觉的学生还是想把它挪到自己项目里的工程师应该都能从里面抠出点能直接用的东西。1. 先把问题摆清楚单目3D语义场景补全到底难在哪1.1 从一张2D图到一整块3D体素中间隔着什么语义场景补全这个任务本质上是“预测一个三维网格里每个小方块属于什么类别”。体素网格里的每个格子有三种状态空、被占据但不知道是什么、被占据且知道是椅子/桌子/墙。模型要做的是把后两者尽量准确地填出来。这和普通的3D目标检测不一样检测只关心框住的物体场景补全关心的是整个空间包括地板、天花板、墙面这些大面积的东西也包括那些只露出一个小角的物件。单目版本又额外加了一层难度。多视角或者带深度的方案至少知道每个像素对应的三维点在哪儿投影关系是确定的。单目只有一张图深度信息完全靠猜。模型必须从纹理、遮挡关系、透视缩放这些线索里推断出“这个像素大概在多远”再把这个推断结果和语义信息绑在一起。我一开始低估了这件事的难度觉得无非是“2D 分割 深度估计”两个网络拼一拼实际跑起来才发现深度误差会沿着视线方向被无限放大一个 10% 的深度偏差投射到 4 米远的地方就是 40 厘米的偏移体素级别早就错位了。所以这个任务的难点不在分割也不在深度而在于如何让 2D 的语义特征和 3D 的空间结构在同一个表示空间里对齐。MonoScene 的核心贡献基本都围绕这件事展开。1.2 三个绕不开的硬骨头我把复现过程中遇到的困难归了归类大致是三个层面。第一个是遮挡区域的无中生有。一张图里桌子挡住了它后面的椅子那部分体素在图像上根本没有对应的像素。模型必须靠场景常识去补桌子后面通常是椅子或者墙地板会一直延伸下去。这个“靠常识补”的能力纯靠卷积很难学到得在 3D 空间里做足够大的感受野。第二个是类别极度不平衡。室内场景里空体素占绝大多数墙、地板、天花板加起来又能占掉剩余的一大半真正的椅子、书本、电视这些“小物件”可能只占千分之几。如果直接拿交叉熵去训模型很快就学会“全猜墙”损失照样降得很好看但 mIoU 惨不忍睹。这个坑我在第一个版本里踩得结结实实。第三个是内存和算力的硬约束。240×144×240 的体素网格八百多万个格子用 3D 卷积在上面跑显存是按 GB 往上跳的。我最早拿单卡 24G 试batch size 只能开到 1还时不时 OOM。这个约束会反过来影响你的架构选择、分辨率设置和 batch 配置不是纯粹的工程问题。1.3 为什么“单目”这个前缀值得单独拎出来说市面上做场景补全的方案不少有拿 RGB-D 的有多帧融合的有靠激光点云体素化的。单目方案的价值在于部署成本。一个普通的 USB 摄像头就能跑不需要标定深度相机不需要处理多传感器时间同步装在移动设备或者低成本机器人上都不心疼。代价就是精度会掉一截尤其是远处和遮挡区域。我的判断是如果你的场景是室内、作用距离在 5 米以内、对远处精度要求不高单目方案完全够用如果是要做高精度建图或者近距离抓取那还是老老实实上深度传感器。MonoScene 这个工作的意义不在于它把单目做到了多高的精度而在于它给出了一套相对完整的“2D 到 3D 特征搬运”的方法论这套东西你换成 RGB-D 输入照样能用甚至效果更好。2. MonoScene的整体设计2D特征如何被“抬升”到3D2.1 网络骨架的三段式结构MonoScene 的整体结构可以粗暴地切成三段2D 特征提取、2D 到 3D 的投影桥接、3D 编解码与输出。这个三段式不是它独创的但每一段的具体处理方式有自己的讲究。第一段是标准的 2D 主干用 ResNet 系列的编码器把输入图像压成多层特征图。这里有个细节值得注意它不是只取最后一层而是取了多个 stage 的输出。原因很直接深层特征语义强但分辨率低浅层特征分辨率高但语义弱而 3D 体素对空间精度要求很高只用深层特征去投影边界会糊成一团。多尺度特征分别投影再融合是我实测下来比较稳的做法。第二段是投影桥接也就是论文里的 FLoSP 模块。这一段是整个方法的核心后面单独展开说。第三段是 3D 的编码解码结构用 3D 卷积在体素空间上做特征提取和上采样中间穿插了关系建模模块。输出层是一个逐体素的分类头类别数取决于数据集NYU 那套设置是 12 类含空类。整个前向过程的数据流大致是图像 → 2D 多尺度特征 → 沿视线投影成 3D 特征体 → 3D 编解码 → 逐体素类别概率。理解这条链路后面的调试才有方向感。2.2 FLoSP沿视线投影这件事为什么成立FLoSP 全称是 Feature Line of Sight Projection翻译过来就是“沿视线的特征投影”。这个名字起得很准确它的做法确实就是沿着相机视线把 2D 特征“射”进 3D 空间。具体的逻辑是这样对于 3D 体素网格里的任意一个体素它的中心点坐标是已知的。用相机内参把这个三维点投影到图像平面上会落在一个像素位置或者落在图像外。取该像素位置上的 2D 特征向量作为这个体素的特征。所有落在同一条视线上的体素共享同一个 2D 特征。这个做法初看有点粗糙——同一条射线上不同深度的体素拿到完全一样的特征深度信息完全丢失了。但仔细想想这件事在单目条件下是唯一合理的选择。因为单目本来就没法确定深度一条视线上的所有点在你的观测里是不可区分的强行给它们不同的特征反而是无中生有。FLoSP 的聪明之处在于它把这个“不确定性”原封不动地保留下来交给后面的 3D 网络去消解。3D 卷积的感受野会结合邻域信息逐步把这些共享特征分化开——比如一条射线上靠近地面的体素周围都是地板特征它自然会被判成地板射线中段悬空的部分周围是空的它就被判成空。投影的数学表达很简单。给定体素中心的相机坐标 (X, Y, Z)内参矩阵的焦距 (fx, fy) 和主点 (cx, cy)像素坐标为u fx * X / Z cx v fy * Y / Z cy这里 Z 是沿光轴方向的深度。取整之后去特征图上采样。如果 (u, v) 落在图像边界外就用零向量填充。这个边界处理看着不起眼但我在调试时发现它对边缘区域的预测质量影响挺大后面会细说。还有一个实现上的关键点多尺度特征怎么投影。不同 stage 的特征图分辨率不同投影时要用对应尺度的内参做缩放。比如原图是 480×288某个 stage 的特征图是 60×36那像素坐标要按比例缩到 60×36 的坐标系里再采样。这个缩放系数算错了整个投影就全歪了而且歪得很隐蔽——损失照样能降只是结果一直是糊的。2.3 3D Context Relation Prior让体素之间会“说话”光有投影还不够。FLoSP 给每个体素的特征是“这条视线上看到了什么”但没告诉模型“这个体素和周围的体素是什么关系”。室内场景里有大量强结构先验椅子一定在地板上墙一定是竖直连续的天花板和地板平行。这些关系必须在 3D 空间里建模。论文里用了一个叫 3D CRP 的模块本质上是 3D 空间上的自注意力变体。它在 3D 特征图上做通道维度和空间维度的关系建模让每个体素能“看到”一定范围内的其他体素。这个模块插在 3D 编解码器的中间层不放在最前面也不放在最后面——放最前面的话特征还没成型关系建模没有意义放最后面的话计算量太大而且此时特征已经定型改不动了。我在复现时做过一个对照实验把 CRP 模块整个去掉其他不变mIoU 掉了差不多 3 个点主要损失集中在墙面边界和家具的支撑结构上。这说明它确实在补“结构一致性”这块短板。但也要注意这个模块的显存开销不小我在 24G 卡上跑的时候把它的通道数砍了一半才勉强塞进去。3. 关键细节与参数动笔前必须想明白的几件事3.1 相机内参与坐标系对齐这是整个项目里最容易出错、又最容易被忽视的一环。MonoScene 的体素坐标系和图像坐标系之间的转换全靠内参一旦内参对不上后面所有的投影都是错的而且错误不会以“报错”的形式出现只会表现为“模型怎么训都不准”。先说清楚坐标系约定。我用的是相机坐标系X 向右Y 向下Z 向前沿光轴。体素网格的原点放在相机光心网格范围是 X 方向 [-2m, 2m]、Y 方向 [-1.44m, 1.44m]、Z 方向 [0, 9.6m] 这一类设置具体数值跟数据集走。体素尺寸 4cm那么 X 方向的格子数就是 4m / 0.04m 100 格……等等这里要小心。NYU 那套标准设置是 240×144×240 的网格体素 4cm对应物理尺寸是 9.6m × 5.76m × 9.6m。但注意轴向的对应关系240 对应的是图像的高度方向还是宽度方向不同代码库的实现不一样。我见过有的实现把第一个维度当高度有的当宽度混用的话投影出来会是一个转了 90 度的结果。判断方法很简单拿一张有明显地板线的图投影后看地板是不是水平的歪了就是轴搞反了。体素中心到相机坐标的转换公式X (i - W/2) * voxel_size Y (j - H/2) * voxel_size Z k * voxel_size其中 i、j、k 是体素索引W、H 是网格在 X、Y 方向的格子数。这个公式里的偏移量取决于你把原点放在网格中心还是角上。我的建议是先拿一个已知的三维点做单元测试。手动算一个点的体素坐标再走一遍投影函数看能不能落到预期的像素上。这个测试花十分钟能省掉后面两天的排查。提示不要相信任何“默认内参”。不同数据集的焦距、主点差别很大NYU 用的是 518.86 左右的焦距和接近图像中心的的主点但具体数值要去数据集官方说明里核对不要从别的项目里抄。3.2 体素网格的尺寸取舍与显存账体素分辨率的选型是个典型的“精度 vs 算力”权衡。4cm 的体素尺寸是 NYU 这套基准的惯例好处是能和别人的结果直接对比坏处是显存吃紧。算一笔账。240×144×240 的网格总共约 830 万个格子。假设 3D 特征图的通道数是 32用 float32 存单层特征就是 830万 × 32 × 4 字节 ≈ 1.06 GB。3D U-Net 编解码器里通常有五六层这样的特征图再加上梯度、优化器状态显存轻松破 20G。这还没算 2D 主干和注意力模块。我的实际配置是单卡 24Gbatch size 23D 部分的基础通道数从论文的 32 砍到 24并且把 CRP 模块只在最低分辨率层启用。这样能跑起来但训练速度是每轮四十多分钟一个完整的训练周期得按天算。如果你也想复现我给几条路方案做法代价降分辨率体素尺寸从 4cm 放到 8cm网格变成 120×72×120细节丢失小物件基本没了降通道3D 基础通道 32→16mIoU 掉 1-2 点稀疏化只对非空体素做卷积实现复杂需要额外写稀疏卷积混合精度开 AMP显存省 30% 左右偶尔有数值不稳我个人优先推荐混合精度 适度降通道这两个组合起来显存能压到 12G 以内损失可控。稀疏卷积效果最好但工程量最大除非你打算长期在这个方向上做否则不建议一上来就啃。3.3 损失函数的构成与权重分配MonoScene 的损失由两块组成体素级的交叉熵和论文提出的场景类别亲和损失SCAL。交叉熵好理解逐体素算分类损失。SCAL 是专门对付类别不平衡和空间结构一致性的值得单独说。SCAL 分两个子项。第一个是语义亲和项思路是让同一类别的体素特征在特征空间里靠拢不同类别的推开。它不看单个体素的分类对不对而是看整类的特征分布是不是紧凑。这个设计对长尾类别特别有效因为即使某个类别的样本很少只要它们特征聚在一起模型就能学到这个类的“形状”。第二个是视锥比例项这个更巧妙。它利用了一个统计先验在相机前方不同距离的视锥里各类别占据的比例应该大致稳定。比如近处的地板占比高远处墙占比高但总体上不会出现“某个视锥里全是椅子”这种离谱情况。这一项约束的是全局分布能防止模型在局部过拟合。权重设置上我的经验是交叉熵和 SCAL 大概 1:1 起步SCAL 内部两个子项再各占一半。如果发现小类别完全不学可以把语义亲和项的权重往上调调到 1.5 左右试。但别调太高太高会让特征过度聚拢边界变得模糊墙和地板的交界处会出现大片误判。注意SCAL 的实现依赖 batch 内的类别统计batch size 太小比如 1的时候统计量不够损失会非常不稳定。我当时 batch size 设为 1 跑了一晚上损失曲线跟心电图一样后来改成 2 才稳下来。4. 动手复现从数据到第一个可视化结果4.1 数据管道的搭建要点数据这块的坑主要在标注格式上。NYU 那套场景补全的标注是体素级的但每个样本给的是一堆稀疏的点云标注再体素化还是直接给体素网格不同发布版本不一样。我拿到的是点云版本需要自己写体素化脚本。体素化的逻辑不复杂对每个标注点算它落在哪个体素格子里把类别填进去。但有几个细节必须处理。第一同一格子可能落多个点类别冲突时按优先级取我的做法是面积大的结构类墙、地板优先小物件其次。第二深度截断超过 9.6 米的点直接丢掉不然网格装不下。第三坐标系对齐标注点云和图像必须是同一时刻、同一相机坐标系下的这一点如果数据集给的是世界坐标还得先转到相机坐标。数据增强方面我用的是随机水平翻转加颜色抖动。这里要特别小心水平翻转之后相机内参的 cx 也要跟着翻不然投影会镜像错位。这个 bug 我调了大半天才发现症状是模型在验证集上表现正常但只要开了增强训练损失就居高不下。原因是翻转后的图像和没翻转的内参不匹配投影出来的特征全是错的。加载效率也值得提一句。体素标注单个样本就有几 MB如果每个 batch 都现读现算GPU 大部分时间在等数据。我的做法是预处理阶段把体素标注压成稀疏格式只存非空格子的坐标和类别加载时再还原IO 量能降一个数量级。4.2 FLoSP与投影模块的代码骨架投影这块是整个项目里最需要自己写清楚的部分我给一个简化版的实现骨架重点看坐标变换和边界处理。import torch import torch.nn.functional as F def build_voxel_coords(grid_size, voxel_size, device): 生成体素中心的相机坐标形状 [N, 3] W, H, D grid_size xs (torch.arange(W, devicedevice) - W / 2) * voxel_size ys (torch.arange(H, devicedevice) - H / 2) * voxel_size zs torch.arange(D, devicedevice) * voxel_size grid_x, grid_y, grid_z torch.meshgrid(xs, ys, zs, indexingij) coords torch.stack([grid_x, grid_y, grid_z], dim-1) return coords.reshape(-1, 3) def project_to_image(voxel_coords, intrinsic, feat_hw): 体素坐标投影到特征图坐标返回归一化采样网格 fx, fy intrinsic[0, 0], intrinsic[1, 1] cx, cy intrinsic[0, 2], intrinsic[1, 2] X, Y, Z voxel_coords[:, 0], voxel_coords[:, 1], voxel_coords[:, 2] Z Z.clamp(min1e-3) u fx * X / Z cx v fy * Y / Z cy # 缩放到特征图分辨率 fh, fw feat_hw u u / intrinsic[2, 2] * (fw / (2 * cx)) * 2 - 1 # 简化写法实际按图像宽度算 v v / intrinsic[2, 2] * (fh / (2 * cy)) * 2 - 1 return torch.stack([u, v], dim-1) def flosp(feature_2d, voxel_coords, intrinsic): 把2D特征沿视线投到3D B, C, fh, fw feature_2d.shape grid project_to_image(voxel_coords, intrinsic, (fh, fw)) grid grid.unsqueeze(0).expand(B, -1, -1) sampled F.grid_sample(feature_2d, grid, align_cornersFalse, modebilinear, padding_modezeros) return sampled.squeeze(-1)上面这段是示意实际用的时候有几个地方要改。project_to_image里的归一化那两行我写得比较糙正确的做法是先把像素坐标除以特征图宽高再映射到 [-1, 1]这样边界处理才准。padding_modezeros保证图像外的体素拿到零特征这一点很重要不然会在视野边缘产生虚假响应。另外多尺度特征投影时每个尺度都要单独跑一遍flosp然后把结果在通道维拼接。拼接之前记得做一次通道对齐不同 stage 的输出通道数不一样。3D 解码器那部分我是直接用的现成 3D U-Net 结构把下采样次数从 4 次减到 3 次因为网格在深度方向的有效范围其实只有前半段过度下采样会让远端的体素直接消失。4.3 训练配置与个人调参记录我的训练配置大致是这样优化器 Adam初始学习率 1e-4weight decay 1e-4余弦退火batch size 2训练 30 轮左右。这个配置是在 24G 单卡上摸索出来的跟原论文的多卡设置肯定有出入但趋势是对的。调参过程中有几个印象比较深的节点。第一轮跑完验证集 mIoU 只有 0.12比瞎猜好不了多少。排查发现是 SCAL 权重设得太大把交叉熵压死了模型只顾着让特征聚拢完全不管分类对不对。把 SCAL 权重从 1.0 降到 0.3mIoU 立刻跳到 0.18。第二个节点是发现模型对“天花板”这个类几乎完全预测不出来。原因是训练集里天花板被裁掉的比例很高——很多样本的图像顶部根本拍不到天花板标注里有但图像里没有模型自然学不会。我的处理是把图像上方 10% 的区域在 3D 监督里屏蔽掉让模型只对“看得到”的部分负责mIoU 反而涨了。第三个节点是学习率。1e-4 在前期降得很快但到第 15 轮左右就平了。换成 2e-4 配合更长的预热最终结果好了大约 1 个点。这个和 batch size 有关batch 小的时候学习率不能太大否则梯度噪声太大。下面是我整理的一组对照记录供参考配置项尝试值观察结果SCAL 权重1.0 / 0.5 / 0.30.3 最稳1.0 会导致分类退化学习率1e-4 / 2e-42e-4 配合预热略好3D 通道数32 / 24 / 1624 是当前显存下的最优折中batch size1 / 21 时损失震荡严重不推荐混合精度开 / 关开显存省约 30%精度无损4.4 推理、评估与可视化评估这块标准的指标是场景补全 IoU 和各类平均 IoU。计算的时候要注意空类通常不参与 mIoU 平均不然所有模型都能刷到 0.9 以上。我见过有人把空类算进去结果报出来的数字好看得离谱实际一点用没有。可视化我认为是这个项目里最有价值的一环。体素结果直接看数字很难判断好坏必须画出来。我的做法是把预测结果转成点云用不同颜色标不同类别然后从侧视角和俯视角各渲一张图。俯视图特别能暴露问题——如果墙是歪的、地板有洞、椅子悬空俯视图上一眼就能看出来。推理速度方面单帧前向在单卡上大约 200 毫秒这个速度做离线处理没问题做实时控制就有点勉强了。如果真要上机器人得做模型剪枝或者换成更轻的 3D 主干这是另一个话题了。5. 踩坑记录那些让训练白跑一整晚的问题5.1 投影错位最常见的假bug投影错位是我遇到最多的坑而且它的表现形式特别有迷惑性——损失在降loss 曲线很漂亮但预测出来的体素永远是糊的边界不清位置整体偏移。排查这类问题的第一步是可视化中间结果。把 FLoSP 输出的 3D 特征沿着深度方向做一个最大值投影看看它在俯视图上是不是和图像的语义分布对得上。如果对不上说明投影链路有问题。我做过一个简单的调试脚本取图像上一个明显的物体比如一把椅子手动算它的三维中心然后检查这个位置上的 3D 特征是不是和椅子所在像素的 2D 特征一致。不一致就往前追看是坐标算错了还是采样网格算错了。常见的错位原因有这么几个。内参的主点 offset 方向搞反了这在一些数据集里很常见因为不同库对主点的定义有差异。特征图分辨率缩放时用了整数除法导致小数部分丢失投影出现半个像素的系统性偏移。还有体素坐标原点放在角上还是中心这两种约定差出来的偏移量正好是网格尺寸的一半。提示写一个单元测试固定一组内参和一个三维点断言投影结果的像素坐标在容差范围内。这个测试在改代码之后跑一遍能挡住大部分回归问题。5.2 类别塌缩与损失不降类别塌缩的症状是训练损失一路下降看起来很健康但验证集上 mIoU 卡在 0.15 左右不动可视化出来发现除了墙和地板其他全空。这本质上还是类别不平衡的问题。我的解决办法是三层。第一层在损失函数上加权对小类别给更高的交叉熵权重权重按类别频率的倒数开根号来算开根号是为了不让权重过分极端。第二层靠 SCAL 的特征聚拢这个前面说过。第三层在采样上做文章保证每个 batch 里至少包含一个有稀有类别的样本。还有一个隐蔽的原因是标注噪声。有些样本的标注里被遮挡区域的类别填得不准模型学到这些错误标注之后反而拉低了整体表现。我当时的处理是把这些样本的对应区域在损失里 mask 掉相当于告诉模型“这里不确定别学”。损失不降的另一种可能是梯度消失。3D U-Net 深了之后浅层的梯度传不回去。加残差连接是最直接的办法我在每一层 3D 卷积后面都加了残差训练稳定性提升明显。5.3 显存爆掉后的几条活路显存问题几乎是绕不过去的我前后试过五六种方法按效果排序大概是混合精度训练。改造成本最低一行torch.cuda.amp的事显存直接省三成。唯一要注意的是损失里如果有除法或者对数运算要做数值保护。梯度累积。显存不够开大 batch就用累积的方式模拟。设accum_steps4等效 batch 就是 4 倍。代价是训练时间变长但结果基本等价。3D 特征通道裁剪。这个要小心砍太多会伤精度我的经验是基础通道不低于 16。激活检查点。用时间换显存前向的时候不存中间激活反向的时候重算。显存能省一半速度慢三成左右。稀疏卷积。效果最好工程量最大建议放到最后考虑。还有一个容易被忽视的点数据加载器本身也吃显存。如果用了pin_memoryTrue加上多进程预取会额外占掉一两个 G。显存紧的时候把这个关掉虽然加载慢一点但能救回来不少。5.4 问题速查表我把这一路踩过的坑整理成一张表遇到问题时可以按症状对照着查。症状可能原因排查方向损失下降但预测全糊投影尺度对不上检查多尺度特征的坐标缩放系数某个方向系统性偏移体素坐标原点约定错误用单点测试验证坐标换算小类别完全不出现类别权重不足 / 采样不均加类别权重检查 batch 内类别分布开启增强后性能骤降内参没跟着翻转检查增强管线里的内参同步损失震荡剧烈batch 太小导致统计不稳增大 batch 或改用梯度累积边缘区域预测乱图像外体素的特征填充方式确认 padding 为 zero 且归一化正确推理显存不够一次处理所有体素分块推理沿深度方向切开训练到一半 loss 变 nan混合精度下的除零在对数、除法处加 eps 保护6. 这套思路还能往哪延展6.1 稀疏深度先验的接入方式纯单目的精度上限摆在那儿但如果手头有一点点深度信息——哪怕是从手机上拿到的稀疏深度点或者是从结构光模组拿到的低分辨率深度图——把它接进 MonoScene 的框架里效果会有明显提升。接入方式有两种。第一种是改投影方式不再沿视线均匀投影而是根据深度先验把 2D 特征放在特定的深度位置上其余位置做插值填充。这个改法对代码改动小但需要对深度先验做平滑处理不然会出现明显的分层。第二种是加一个深度引导的特征调制模块用深度图作为条件对 3D 特征做逐体素的加权。这个改动大一些但更灵活也更容易训。我自己试过第一种在深度先验覆盖率 10% 左右的情况下mIoU 能提升 2 到 3 个点主要收益在物体边界上。深度覆盖率再低就没啥效果了稀疏到 1% 以下基本等于没有。6.2 换到别的场景要改哪些地方MonoScene 的默认设置是室内场景挪到别的地方要动几处东西。如果要做室外场景体素尺寸得放大4cm 在外面连一辆车都装不下至少得 20cm 起。同时网格尺寸要拉长深度方向可能要延伸到 50 米。这会带来显存爆炸必须配合稀疏化或者分块处理。类别体系也要换室内的“椅子”“桌子”在室外没意义得换成“车辆”“行人”“路面”这些。如果要做工业场景比如仓库或者车间结构先验会比室内更强——货架是规则排列的地面是平的通道是直的。这种情况下可以引入更强的几何约束比如强制地面体素的法向朝上这能显著提升地面区域的准确率。如果是做动态场景那就要引入时序信息了。单帧的 MonoScene 处理不了运动物体得在特征层面做帧间融合或者干脆改成用视频输入。这个方向的工程量比单帧大得多建议先把单帧跑稳再说。我个人的体会是MonoScene 这套框架的价值在于它给出了一个清晰的“2D 特征如何进 3D”的范式。FLoSP 这个思路可以迁移到很多地方——你把 2D 主干换成别的任务的分割网络把 3D 解码器换成点云补全或者占据栅格预测的网络中间的投影桥接逻辑基本不用改。我后来把它挪到一个仓库货物体积估算的小项目里只改了类别体系和体素尺寸投影部分原封不动跑出来的结果基本可用。这种可迁移性比单纯的精度数字更有意思。