EXP-3D-RGBD-DEPTHSPLAT-PROBE-V1(探索性)
用户 2026-10-05 的指示:"DepthSplat用这个作为基座,进行尝试"。本目录记录以 DepthSplat 为基座的探索性检查。 - 基座:cvg/depthsplat @2dad25a7,MIT 许可;base 模型 re10k+dl3dv,448×768,randview2-6。 - 开发队列:主要在 DEV(8 个场景、32 个查询)上进行;扩大规模的开发检查用 EVAL-V3/V4(83 个场景,以前已被多个实验使用)。 - 全部只作描述,没有预注册;没有读取 EVAL_V5、TRAIN_EXT、REPLICA 和受保护的保留集。 - 来源与校验见 provenance.txt 和 SHA256SUMS。代码在 code/,结果文件在 results/,日志在 logs/。 - 预测(npz)和微调权重不在 git 里,路径见 provenance.txt。
设置
- 环境:
~/envs/depthsplat,torch 2.4.0+cu121。 - CUDA 光栅化扩展:diff-gaussian-rasterization-modified @1250c420,glm @5c46b9c0。hit 连 GitHub 不稳定,按用户选择,从本机下载官方 codeload 压缩包再中转到 hit,sha256 见 provenance.txt。用 CUDA 12.2、sm_86 编译。
- DINOv2 代码:DepthSplat 用
torch.hub加载 DINOv2 代码。这里改为从本地 hub 缓存加载,pretrained=False。 - 原因:原来的调用每次都要访问 GitHub 判断分支,并下载 ImageNet 权重;而这部分权重已全部包含在 DepthSplat 检查点里,加载编码器时缺任何键都会报错。
- 缓存代码树的 sha256 与 V31 校验过的 117c2d92… 一致。
- 推理配置:
+experiment=dl3dv,num_scales=2,upsample_factor=4,lowest_feature_resolution=8,monodepth_vit_type=vitb,gaussian_scale_max=0.1,supervise_intermediate_depth=false;near 0.5 m,far 200 m。 - 输入:128×160 帧双线性放大到 256×320。内参归一化为 (cx+0.5)/W;位姿为 OpenCV 约定的 c2w;渲染输出 128×160。
- 渲染深度的含义:DepthSplat 渲染的深度是 Σα·T·z(零背景),没有按累积不透明度归一化。因此同时渲染了累积 α。打分中:
- "覆盖"指 α ≥ 0.5;
- DSN = z/α,只在覆盖处有值;
- FAR_DSN_SCALED = NEAR 区域和未覆盖的 FAR 区域用调和填充,已覆盖的 FAR 区域用 DSN。
- 深度单位:深度一律换算为沿射线距离,与记录一致:Hypersim
depth_meters,项目里的射线是单位方向。 - 区域与基线:
- FAR = V17 的 NEAR 掩码之外的有效像素,NEAR 掩码由 3 个 RGB-D 上下文视角重投影、取 8 px 邻域得到;
- 调和填充 = REPROJ_HARMONIC;
- G1 = V21 的 G1,T24000;DEV 上用 3 个种子,EVAL34 上用 1 个种子;
- 基线都由通用 arms 评估器封存,查询深度只在打分时读取。
- GPU:4 号卡,与另一用户常驻的 1.3 GB 进程共用(用户 10/5 批准)。启动命令为
cv_gpu_run.sh --with-others,日志里标记为 co-tenant。 - 代码版本:DEV 的运行早于位姿正交化和
--min-query-gap选项。这两项改动不影响 DEV 已有运行的设置;DEV 位姿已正交到 1e-6。归档的 code/ds_predict.py 是最终版本。
1. 零样本(只用 RGB,3 个上下文视角)
| 方法(DEV,AbsRel) | ALL | NEAR | FAR |
|---|---|---|---|
| REPROJ_HARMONIC | 0.2059 | 0.1438 | 0.3284 |
| G1(3 个种子) | 0.3217 | 0.3291 | 0.3274 |
| DepthSplat 渲染深度 | 0.5184 | 0.4420 | 0.8771 |
| FAR_DSN_SCALED | 0.2138 | 0.1438 | 0.3618 |
- DepthSplat 在上下文视角上的深度:AbsRel 0.142,δ1 0.83。实测与预测的比值中位数为 0.99,所以尺度基本是公制。
- FAR 区域的覆盖率只有 13%。
2. 相机约定自检(渲染回上下文相机本身)
| 变体 | 上下文自渲染 PSNR(均值,范围) | 渲染深度与编码器深度的 AbsRel | 查询 PSNR |
|---|---|---|---|
| 采用的约定(c2w,+0.5) | 20.8 dB(11.8–28.7) | 0.086 | 14.5 dB |
| 改传 w2c | 15.8 dB(7.6–23.8) | 0.325 | 10.7 dB |
| 去掉 +0.5 | 19.6 dB(11.7–26.3) | 0.084 | 14.3 dB |
采用的约定在各项上都最好,所以结果差不是接线错误。即使渲染回自身视角,PSNR 也只有 20.8 dB,说明多视角深度之间不一致。
3. 用实测深度替换 DepthSplat 的上下文深度
做法:把最终上下文深度换成实测深度(平面 z,最近邻放大),保留 DepthSplat 的特征、匹配概率和高斯参数头。
结果: - FAR 覆盖率从 13% 降到 4%。之前的覆盖来自位置放错的高斯。 - FAR_DSN_SCALED 的 ALL / NEAR / FAR 为 0.2058 / 0.1438 / 0.3295,与调和填充几乎相同。 - 原因:高斯只能放在观测到的表面上,碰不到 FAR。
4. 额外帧:每条记录 9 个没有任何角色使用的帧
额外帧排在 3 个上下文之后,按帧序等距选取。表中"调和 − X"取 FAR 区域;场景 bootstrap 10,000 次,种子 20260928。
| 变体(DEV) | FAR 覆盖率 | FAR_DSN_SCALED FAR | 调和 − X(FAR)[95%] | 好/差 | 调和 − X(ALL) |
|---|---|---|---|---|---|
| 3 上下文 RGB,无额外帧 | 0.13 | 0.3618 | −0.0334 [−0.0641, −0.0092] | 1/7 | −0.0080 |
| 3 上下文注入实测,无额外帧 | 0.04 | 0.3295 | −0.0011 [−0.0036, +0.0002] | 2/1 | +0.0000 |
| +3 额外帧,全部只用 RGB | 0.49 | 0.3897 | −0.0613 [−0.1144, −0.0016] | 2/6 | −0.0063 |
| +3 额外帧只有 RGB(上下文注入) | 0.42 | 0.3458 | −0.0174 [−0.0808, +0.0414] | 3/5 | −0.0009 |
| +3 额外帧带实测深度(上限) | 0.35 | 0.2725 | +0.0559 [+0.0216, +0.0928] | 6/1 | +0.0072 |
| +9 额外帧,全部只用 RGB | 0.66 | 0.3168 | +0.0116 [−0.0693, +0.0973] | 5/3 | +0.0172 |
| +9 额外帧只有 RGB(上下文注入) | 0.65 | 0.3053 | +0.0231 [−0.0617, +0.1091] | 5/3 | +0.0158 |
| +9 额外帧带实测深度(上限) | 0.54 | 0.2190 | +0.1093 [+0.0432, +0.1871] | 7/1 | +0.0334 |
| +3 只有 RGB,测试时尺度对齐 | 0.41 | 0.3466 | −0.0182 [−0.0755, +0.0354] | 3/5 | −0.0005 |
| +9 只有 RGB,测试时尺度对齐 | 0.64 | 0.3093 | +0.0191 [−0.0618, +0.1036] | 5/3 | +0.0167 |
尺度对齐的做法:用 3 个实测视角上"实测 / 预测"的中位数比(0.96–1.06)校正只有 RGB 的视角的预测深度,再生成高斯。
5. 用 TRAIN 数据微调 DepthSplat 的深度预测器
做法(code/ds_finetune.py): - 数据:TRAIN72 加上 SEG-V1 的 240 段,共 312 条记录。 - 采样:每步随机取 3–6 帧 RGB。 - 损失:每个视角的 log-L1 深度损失,在 128×160 上计算。 - 训练范围:只训练深度预测器,ViT 用十分之一学习率;高斯参数头保持发布版本;模型保持 eval 模式。 - 步数与选择:固定 4000 步,取最后一步,不做选择。DEV 曲线只作记录。
| 运行 | 学习率(ViT) | DEV 上下文深度 AbsRel:0 / 500 / 1000 / 2000 / 3000 / 4000 步 |
|---|---|---|
| ft_v1 | 2e-5(2e-6) | 0.1416 / 0.1041 / 0.2962 / 0.1668 / 0.1486 / 0.1445(约 850–1000 步时发散) |
| ft_v2 | 5e-6(5e-7) | 0.1416 / 0.1062 / 0.0967 / 0.1012 / 0.1073 / 0.1089 |
| 变体(DEV,调和 − FAR_DSN_SCALED,FAR) | 零样本 | ft_v1 | ft_v2 |
|---|---|---|---|
| 无额外帧,RGB | −0.0334 | −0.0310 | −0.0504 |
| +3 只有 RGB(上下文注入) | −0.0174 | −0.0093 | +0.0250 [−0.0075, +0.0617],5/3 |
| +9 只有 RGB(上下文注入) | +0.0231 | −0.0596 | −0.0249 [−0.0780, +0.0256],3/5 |
| +9 全部只用 RGB | +0.0116 | −0.0886 | −0.0524 |
ft_v2 让单视角深度明显变好:AbsRel 从 0.142 降到 0.109,δ1 从 0.83 升到 0.85。但 FAR 没有一致的改善。
6. 不经高斯渲染的深度融合(code/ds_fuse.py)
做法: - 把每个额外视角的深度反投影,再用 z-buffer 投到查询视角。 - FUSE_ANY:取最前面的候选。 - FUSE:要求至少 2 个视角在 5% 以内一致。 - 两种方法都只替换 FAR 区域,其余像素用调和填充。
| 额外 9 帧的深度来源(DEV) | 调和 − FUSE_ANY(FAR) | 调和 − FUSE(FAR) |
|---|---|---|
| 实测深度(无模型) | +0.1208 [+0.0479, +0.2062],8/0 | +0.0528 [+0.0100, +0.1068],7/0 |
| DepthSplat 零样本 | +0.0219 [−0.0612, +0.1064],4/4 | −0.0055 [−0.0557, +0.0430],4/4 |
| DepthSplat ft_v2 | −0.0153 [−0.0695, +0.0306],4/4 | +0.0106 [−0.0205, +0.0455],5/3 |
7. EVAL-V3/V4 开发检查(83 个场景,332 个查询)
- 探针根
probe_eval34:把 EVAL-V3(57 个场景)和 EVAL-V4(26 个场景)的记录合并成一个清单,见 code/make_probe_root_eval.py。split 改为 EVAL34,记录本身不变。arms 评估器封存了调和插值、NEAR 掩码和 G1(V21,T24000,1 个 seed)。 - 设置:与 DEV 完全相同,没有做任何调整。唯一的改动来自一个位姿问题:
- EVAL-V3 ai_045_001 第 0 帧的 |det − 1| = 2e-5,正交误差 0.006,触发了 DepthSplat 的旋转断言;
- 因此给 DepthSplat 的位姿一律换成最近的正交旋转(SVD),最大修正量记录在 run_info.json;
- DEV 的位姿正交到 1e-6,这一改动对 DEV 没有实际影响;
- 第一次失败的部分输出保留在
~/cv_work/depthsplat/_attempts/,不在 git 中。
| 方法(EVAL34,AbsRel) | ALL | NEAR | FAR |
|---|---|---|---|
| 调和插值 | 0.2890 | 0.2262 | 0.4869 |
| G1(1 个 seed) | 0.2675 | 0.2532 | 0.3549 |
| FAR_G1(NEAR 用调和,FAR 用 G1) | 0.2559 | 0.2262 | 0.3549 |
| +9 只有 RGB,零样本:FAR_DSN_SCALED | 0.2424 | 0.2262 | 0.3519 |
| +9 只有 RGB,零样本:FAR_DSN_G1 | 0.2327 | 0.2262 | 0.3140 |
| +9 只有 RGB,ft_v2:FAR_DSN_G1 | 0.2336 | 0.2262 | 0.3113 |
| +9 只有 RGB,帧序距查询 ≥ 3,零样本:FAR_DSN_G1 | 0.2439 | 0.2262 | 0.3604 |
| +9 带实测深度:FAR_DSN_G1 | 0.2190 | 0.2262 | 0.2390 |
| +9 带实测深度,帧序距查询 ≥ 3:FAR_DSN_G1 | 0.2293 | 0.2262 | 0.2774 |
参照:调和 − FAR_G1 在 FAR 上为 +0.1320 [+0.0377, +0.2452](49/31),在 ALL 上为 +0.0331 [+0.0133, +0.0556](51/29)。
| 变体(EVAL34) | FAR 覆盖率 | 调和 − FAR_DSN_SCALED(FAR) | FAR_G1 − FAR_DSN_G1(FAR) | FAR_G1 − FAR_DSN_G1(ALL) |
|---|---|---|---|---|
| +9 只有 RGB,零样本 | 0.68 | +0.1350 [+0.0447, +0.2532],53/25 | +0.0410 [−0.0252, +0.0964],49/29 | +0.0232 [+0.0109, +0.0364],51/27 |
| +9 只有 RGB,ft_v2 | 0.65 | +0.1349 [+0.0616, +0.2231],57/21 | +0.0437 [−0.0167, +0.0930],54/24 | +0.0223 [+0.0087, +0.0369],52/26 |
| +3 只有 RGB,零样本 | 0.57 | +0.0881 [+0.0138, +0.1719],52/23 | −0.0126 [−0.0838, +0.0470],48/27 | +0.0132 [+0.0025, +0.0242],49/26 |
| +3 只有 RGB,ft_v2 | 0.51 | +0.0769 [+0.0260, +0.1300],59/17 | +0.0021 [−0.0681, +0.0599],54/22 | +0.0107 [−0.0001, +0.0213],53/23 |
| +9 只有 RGB,帧序距查询 ≥ 3,零样本 | 0.54 | +0.0764 [−0.0086, +0.1760],50/28 | −0.0054 [−0.0765, +0.0516],46/32 | +0.0120 [−0.0008, +0.0248],46/32 |
| +9 带实测深度(上限) | 0.63 | +0.2046 [+0.1258, +0.3079],71/5 | +0.1160 [+0.0468, +0.1696],70/6 | +0.0369 [+0.0234, +0.0515],70/6 |
| +9 带实测深度,帧序距查询 ≥ 3 | 0.49 | +0.1519 [+0.0814, +0.2442],67/5 | +0.0775 [+0.0091, +0.1307],62/10 | +0.0266 [+0.0151, +0.0394],63/9 |
额外帧离查询有多近: - 最近的上下文帧离查询的中位数是 1.71 m / 15.2°。 - 9 个额外帧中最近的一个,中位数是 0.75 m / 8.3°;52% 的查询里,相邻帧(帧序差 1)就在额外帧中。 - 只保留帧序距查询 ≥ 3 的帧后,每条记录剩 7 个(4–9 个),最近的一个是 0.95 m / 10.2°。
不经渲染的深度融合(EVAL34,+9 帧,调和 − X,FAR):
| 额外帧深度来源 | FUSE_ANY | FUSE(两视角一致) |
|---|---|---|
| 零样本 DepthSplat 预测 | +0.1118 [+0.0290, +0.2238],46/33 | +0.0638 [+0.0214, +0.1153],52/24 |
| 实测深度 | +0.2096 [+0.1380, +0.3032],73/6 | — |
两种融合都不如渲染的 FAR_DSN_SCALED(+0.1350)。
读法
- 原任务上没有价值。 在原任务(3 个 RGB-D 上下文)上,DepthSplat 不起作用:
- 零样本只用 RGB 时,远差于调和插值;
- 注入实测深度后,与调和插值相同;
- 像素对齐的高斯只能落在观测到的表面上,碰不到 FAR。
- 额外的只有 RGB 的帧:收益主要来自紧邻查询的帧。
- 在 EVAL34 上,FAR 改善很大:相对调和填充 +0.135,与 G1 相当;和 G1 组合后再好 +0.041。
- 但一半的查询里,相邻帧就在额外帧中。去掉帧序距查询 < 3 的帧后,相对 FAR_G1 不再有收益(−0.005)。
- 也就是说,DepthSplat 在这里起的作用大致是"估计一张相邻 RGB 图的深度"。
- 微调改善了单视角深度,但不改变结论。 DEV 上下文深度 AbsRel 从 0.142 降到 0.109,在 EVAL34 上的结果与零样本相同。
- 测量覆盖仍是 FAR 的主导因素。 同样这些帧如果有实测深度,即使去掉相邻帧,相对 FAR_G1 仍好 +0.078 [+0.009, +0.131](62/10)。这与 V24/V25/V27 和 Core B 的结论一致。
- DEV 太小,不足以评价这类方法。 DEV(8 个场景)和 EVAL34 的结论方向不同:DEV 的 FAR 对调和插值容易得多(0.328 对 0.487)。
- 没有做预注册确认。 EVAL_V5、TRAIN_EXT、REPLICA 都没有动用。原因是排除相邻帧之后,没有可以确认的效应。