粗到精先验驱动稀疏无标定照片级三维重建——Dust to Tower(D2T)论文全解

论文信息

标题:Dust to Tower: Prior-Driven Coarse-to-Fine Photo-Realistic Scene Reconstruction from Sparse Uncalibrated Images
会议:IEEE Transactions on Visualization and Computer Graphics (TVCG, CCF A类顶刊,2026)
单位:中国人民大学、北航人工智能研究院、毫末智行
代码:暂未公开(论文标注代码后续开源)
论文:https://arxiv.org/pdf/2412.19518

一、痛点开篇:手机随手拍几张图,为啥重建3D模型这么难?

生活化案例

你去景区只随手拍3张雕塑照片,想直接生成完整3D模型,现在主流方案会踩两大坑:

  1. 稀疏有标定方案(FSGS、3DGS):必须提前用COLMAP跑SfM算出相机内外参,3张图片特征太少,SfM直接崩掉,完全没法用;
  2. 无标定稠密方案(Nope-NeRF、COGS):要求几十上百张连续图片,只有3张输入会严重过拟合,渲染全是模糊重影,训练还要几小时,普通4090显卡扛不住。

简单说:市面上方法只能二选一——要么图多不用标定,要么图少但必须精准相机参数,没有一套能兼容「少量随手拍、无相机内外参」的快速重建框架,这就是D2T(Dust to Tower)诞生的核心动机。

本文核心思路:先搭粗糙全局几何骨架,再用单目深度+视图形变修复生成全新视角伪图做监督,粗→精两阶段联合优化3D高斯与相机位姿,3/6/12张稀疏无标定图40秒就能出高质量渲染效果。

在这里插入图片描述

图1详细解读

横轴:训练总时长(秒);纵轴:新视角渲染PSNR(越高画质越清晰)

  • 红色五角星Ours(D2T):3视图仅41秒,PSNR23.39,速度+画质双最优,帕累托最优
  • InstantSplat:速度接近,但PSNR低一大截;
  • FSGS:画质尚可,但训练要3分47秒,耗时是D2的5倍;
  • Nope-NeRF:画质最差,还要2小时起步,完全不实用;
    通俗总结:D2T是唯一兼顾稀疏输入、无标定、极快训练、高清渲染的算法。

二、整体三模块框架拆解(原文Figure2)

在这里插入图片描述

整套方法分三大核心模块,两阶段训练:

  1. CCM粗构建模块:输入无标定稀疏图片,用DUSt3R全局对齐点云,初始化相机内参/位姿+初始3D高斯模型;
  2. CAD置信感知深度对齐模块:把粗糙低分辨率深度,和单目DepthAnything V2高精度相对深度做尺度偏移对齐,输出精准深度图,为图像形变提供几何依据;
  3. WIG形变引导修复模块:用对齐后的深度把原图形变到全新视角,修复遮挡空洞,生成高质量伪视图作为额外监督;
  4. 训练流程:粗阶段只用原图训练3D高斯+相机;精阶段加入WIG生成的全新修复视图联合优化,同步修正所有相机位姿。

2.1 CCM粗构建模块(解决无标定初始几何)

核心作用

跳过COLMAP SfM,仅靠少量图片快速得到全局点云(i-W/2、j-H/2)统一相机内参fff、所有图像外参TTT,给3D高斯一个靠谱初始骨架。

核心公式1:焦距求解(原文式1)

f∗=argminf∑i=0W∑j=0HC1,1i,j∥(i−W2,j−H2)−f⋅(X1,1i,j,0,X1,1i,j,1)X1,1i,j,2∥f^{*}=\underset{f}{arg min } \sum_{i=0}^{W} \sum_{j=0}^{H} C_{1,1}^{i, j}\left\| \left(i-\frac{W}{2}, j-\frac{H}{2}\right)-f \cdot \frac{\left(X_{1,1}^{i, j, 0}, X_{1,1}^{i, j, 1}\right)}{X_{1,1}^{i, j, 2}}\right\|f=fargmini=0Wj=0HC1,1i,j (i2W,j2H)fX1,1i,j,2(X1,1i,j,0,X1,1i,j,1)
逐字母通俗解释:

  • f∗f^{*}f:最优统一相机焦距(所有图片共用一套内参);
  • W/HW/HW/H:图片宽、高像素;
  • C1,1i,jC_{1,1}^{i,j}C1,1i,j:DUSt3R输出该像素置信度(置信低的像素不参与计算,避免干扰);
  • X1,1i,j,0/1/2X_{1,1}^{i,j,0/1/2}X1,1i,j,0/1/2:DUSt3R输出该像素3维空间坐标(x,y,z);
  • i−W/2、j−H/2i-W/2、j-H/2iW/2jH/2:像素中心偏移(假设主点在画面正中);
  • ∥⋅∥\|\cdot\|:L2二范数,最小化投影误差;
    通俗人话:只保留模型觉得靠谱的像素,反向求解统一焦距,让3D点投影回2D像素误差最小,不用手动标定相机。

核心公式2:全局点云对齐(原文式2)

χ∗=argminχ,T,σ∑e∈E∑v∈V[e]∑i=1HWCv,ei∥χvi−σeTeXv,ei∥\chi^{*}=\underset{\chi, T, \sigma}{arg min } \sum_{e \in \mathcal{E}} \sum_{v \in \mathcal{V}[e]} \sum_{i=1}^{H W} C_{v, e}^{i}\left\| \chi_{v}^{i}-\sigma_{e} T_{e} X_{v, e}^{i}\right\|χ=χ,T,σargmineEvV[e]i=1HWCv,ei χviσeTeXv,ei
字母释义:

  • χ∗\chi^{*}χ:对齐后的全局统一3D点云;
  • eee:图像配对边(全连接图任意两张图一组);
  • TeT_eTe:配对之间刚体变换矩阵;
  • σe\sigma_eσe:配对尺度缩放因子(DUSt3R单组输出尺度不统一,需要缩放对齐);
  • Cv,eiC_{v,e}^iCv,ei:该点置信权重;
  • Xv,eiX_{v,e}^iXv,ei:单DUSt3R输出局部点云;
    通俗人话:把每一对图片预测的局部3D点,用变换+缩放统一到同一个世界坐标系,解决多图尺度不一致问题,几秒收敛得到全局几何。

拿到全局点云+相机参数后,直接初始化3D高斯集合,进入粗阶段基础训练。

在这里插入图片描述

2.2 CADA置信感知深度对齐模块(原文Figure3)

痛点

CCM输出深度分辨率低(i-W/2、j-H/2)噪声大,直接用来形变图像会出现错位;单目深度只有相对尺度,和粗深度尺度不匹配,没法直接用。CADA用来融合两者优势。

流程分步

  1. 粗深度DcD_cDc双线性上采样到原图尺寸DcupD_c^{up}Dcup
  2. DepthAnything V2生成高精度单目逆深度DcmD_c^mDcm
  3. 用DUSt3R置信图筛选高可靠像素生成掩码MMM,只拿靠谱区域做匹配;
  4. 最小二乘求解尺度aaa(i-W/2、j-H/2)偏移bbb,对齐两组逆深度;

核心公式3 尺度偏移优化(原文式4)

(a,b)=argmin⁡a,b∑i=1Hh∑j=1WhM(i,j)(1Dcup(i,j)−(b+aDcm(i,j)))2 (a, b)=arg \operatorname* {min}_{a, b} \sum _{i=1}^{H_{h}} \sum _{j=1}^{W_{h}} M(i, j)\left(\frac{1}{D_{c}^{u p}(i, j)}-\left(b+a D_{c}^{m}(i, j)\right)\right)^2 (a,b)=arga,bmini=1Hhj=1WhM(i,j)(Dcup(i,j)1(b+aDcm(i,j)))2
字母释义:

  • M(i,j)M(i,j)M(i,j):置信掩码,1代表可靠像素,0直接忽略;
  • 1/Dcup1/D_c^{up}1/Dcup:粗深度取逆(逆深度更利于线性对齐);
  • aaa:单目深度缩放系数,bbb:偏移量;
    对齐后高精度深度:
    Dch=1b+a⋅DcmD_c^{h}=\frac{1}{b+a \cdot D_{c}^{m}}Dch=b+aDcm1
    通俗人话:只用几何靠谱区域拟合缩放偏移,把单目细腻深度映射到全局统一尺度,得到高精度对齐深度,是后续图像形变的核心地基。

2.3 WIG形变引导修复模块(全文最大创新点)

解决问题

稀疏输入只有少数视角,模型极易在遮挡区域过拟合,传统方法只形变原图,空洞直接丢弃,缺少全新视角监督,画质糊成一团。WIG生成完整无空洞全新视角伪图,给模型海量额外监督信号。

完整流程

  1. 视角采样:用B样条采样大量训练集中不存在的全新相机位姿TkpT_k^pTkp
  2. 图像形变:用CADA输出对齐深度DchD_c^hDch,将原图从当前相机TcT_cTc投影到新视角TkpT_k^pTkp
    形变映射公式:
    pj=KTkcK−1Dch(pi)pip_{j}=K T_{k c} K^{-1} D_{c}^{h}\left(p_{i}\right) p_{i}pj=KTkcK1Dch(pi)pi
  • pip_ipi:原图像素坐标;pjp_jpj:新视角对应像素;
  • Tkc=(Tkp)−1TcT_{kc}=(T_k^p)^{-1}T_cTkc=(Tkp)1Tc:两相机之间变换矩阵;
  • KKK:相机内参矩阵;
  1. 掩码清洗Mask Clean:形变后边缘会出现孤立噪点像素,剔除邻域不足一半的异常点,避免修复模型生成错乱内容;
  2. 轻量化图像修复:用LaMa轻量修复模型填充形变产生的遮挡空洞,得到完整(i-W/2、j-H/2)多视角一致伪视图I^kp\hat{I}_k^pI^kp

在这里插入图片描述

图5直观效果:原图形变后中间出现黑色空洞,修复后完整自然,能作为真实监督训练3D高斯。

三、两阶段联合优化损失函数

阶段1:粗阶段损失(仅原图训练)

Lc=Lrgb(I,I~)+λdLdepth(D~,Dm)\mathcal{L}_{c}=\mathcal{L}_{r g b}(I, \tilde{I})+\lambda_{d} \mathcal{L}_{depth }\left(\tilde{D}, D^{m}\right)Lc=Lrgb(I,I~)+λdLdepth(D~,Dm)

  1. Lrgb\mathcal{L}_{rgb}Lrgb:渲染图与原图光度损失,原文式6:
    Lrgb=(1−λ)L1(I,I~)+λLD−SSIM(I,I~)\mathcal{L}_{rgb }=(1-\lambda) \mathcal{L}_{1}(I, \tilde{I})+\lambda \mathcal{L}_{D-S S I M}(I, \tilde{I})Lrgb=(1λ)L1(I,I~)+λLDSSIM(I,I~)
  • III:真实输入图,I~\tilde{I}I~:3D高斯渲染图;
  • L1\mathcal{L}_1L1:L1像素损失,LDSSIM\mathcal{L}_{DSSIM}LDSSIM:结构相似度损失;
  1. Ldepth\mathcal{L}_{depth}Ldepth:深度先验损失(原文式7)
    Ldepth=1−ρ(1D~,Dm),ρ(X,Y)=cov(X,Y)σXσY\mathcal{L}_{depth }=1-\rho\left(\frac{1}{\tilde{D}}, D^{m}\right), \rho(X, Y)=\frac{cov(X, Y)}{\sigma_{X} \sigma_{Y}}Ldepth=1ρ(D~1,Dm),ρ(X,Y)=σXσYcov(X,Y)
  • ρ\rhoρ:皮尔逊相关系数,衡量渲染逆深度与单目深度一致性;
  • covcovcov:协方差,σ\sigmaσ:标准差;
    通俗:约束渲染几何和单目深度匹配,防止几何崩坏。

阶段2:精阶段损失(加入WIG修复伪图)

Lf=Lc+λpseudoLrgb(I^p,I~p)\mathcal{L}_{f}=\mathcal{L}_{c}+\lambda_{pseudo } \mathcal{L}_{r g b}\left(\hat{I}^{p}, \tilde{I}^{p}\right)Lf=Lc+λpseudoLrgb(I^p,I~p)

  • I^p\hat{I}^pI^p:WIG输出修复全新视角图;
  • I~p\tilde{I}^pI~p:当前3D高斯在该视角的渲染图;
  • λpseudo=0.3\lambda_{pseudo}=0.3λpseudo=0.3:伪图损失权重;
    精阶段同时优化3D高斯所有参数+全部相机内外参,彻底修正CCM初始位姿微小误差。

四、核心工程代码(基于PyTorch+gsplat+DepthAnythingV2)

4.1 CCM粗构建模块核心代码(DUSt3R全局对齐)

import torch
from dust3r.model import AsymmetricCroCo3DStereo
from dust3r.global_align import GlobalAligner

def ccm_coarse_init(img_list, device="cuda"):
    # 1. 加载预训练DUSt3R模型
    model = AsymmetricCroCo3DStereo.from_pretrained("DUSt3R_ViTLarge_BaseDecoder_512").to(device)
    # 2. 生成全连接图像配对
    img_pairs = [(img_list[i], img_list[j]) for i in range(len(img_list)) for j in range(len(img_list)) if i!=j]
    # 3. 批量推理输出每对局部点云+置信图
    outputs = model.infer_pairs(img_pairs, batch_size=2)
    # 4. 全局对齐求解统一点云\(i-W/2、j-H/2\)相机位姿\(i-W/2、j-H/2\)焦距
    aligner = GlobalAligner(mode="PointCloudOptimizer")
    scene = aligner.compute_global_alignment(outputs, niter=300)
    # 提取相机内参K\(i-W/2、j-H/2\)外参T\(i-W/2、j-H/2\)全局点云
    K_all = scene.get_intrinsics()
    cam_poses = scene.get_im_poses()
    global_pcd = scene.get_aligned_pcd()
    # 初始化3D高斯中心点
    gauss_xyz = torch.tensor(global_pcd, device=device)
    return K_all, cam_poses, gauss_xyz

4.2 CADA深度对齐代码(最小二乘求a(i-W/2、j-H/2)b)

import torch
import torch.nn.functional as F
from depth_anything_v2.dpt import DepthAnythingV2

def cada_align_depth(raw_coarse_depth, rgb_img, mask_conf):
    # 加载单目深度模型
    depth_model = DepthAnythingV2(**{"encoder":"vitl"}).cuda()
    mono_depth = depth_model.infer_image(rgb_img) # D_c^m 单目相对深度
    # 粗深度上采样
    coarse_up = F.interpolate(raw_coarse_depth.unsqueeze(0), size=rgb_img.shape[:2], mode="bilinear")[0]
    inv_coarse = 1.0 / (coarse_up + 1e-6)
    # 筛选置信有效像素
    valid_mask = mask_conf > 0.5
    inv_c_valid = inv_coarse[valid_mask]
    mono_valid = mono_depth[valid_mask]
    # 最小二乘求解a,b
    X = torch.stack([mono_valid, torch.ones_like(mono_valid)], dim=1)
    ab = torch.linalg.lstsq(X, inv_c_valid.unsqueeze(-1)).solution.squeeze()
    a, b = ab[0], ab[1]
    # 输出对齐高精度深度
    aligned_inv = a * mono_depth + b
    aligned_depth = 1.0 / (aligned_inv + 1e-6)
    return aligned_depth

4.3 WIG图像形变+掩码清洗简化代码

import cv2
import numpy as np

def warp_image_by_depth(rgb, aligned_depth, T_src, T_target, K):
    H, W = rgb.shape[:2]
    # 生成像素网格
    y, x = np.meshgrid(np.arange(H), np.arange(W), indexing="ij")
    pix = np.stack([x, y, np.ones_like(x)], axis=-1).reshape(-1, 3).T
    # 反投影到3D空间
    depth_flat = aligned_depth.reshape(-1,1)
    world_pts = T_src @ np.linalg.inv(K) @ (pix * depth_flat).T
    # 投影到新视角
    proj_pts = K @ np.linalg.inv(T_target) @ world_pts
    proj_pts = proj_pts[:2] / (proj_pts[2:]+1e-6)
    # 生成形变流
    flow = proj_pts.T.reshape(H, W, 2).astype(np.float32)
    warped_img = cv2.remap(rgb, flow[...,0], flow[...,1], cv2.INTER_LINEAR)
    # 生成空洞掩码
    mask = ((proj_pts[0]<0)|(proj_pts[0]>=W)|(proj_pts[1]<0)|(proj_pts[1]>=H)).reshape(H,W)
    return warped_img, mask

def mask_clean(mask, win_size=5):
    # 掩码清洗:剔除邻域不足一半的孤立像素
    kernel = np.ones((win_size, win_size), np.uint8)
    count_nei = cv2.boxFilter(mask.astype(np.float32), -1, (win_size, win_size))
    clean_mask = np.where(count_nei > (win_size*win_size/2), mask, 0).astype(np.uint8)
    return clean_mask

4.4 两阶段训练主循环片段

from gsplat import GaussianModel, render

def train_d2t(rgb_imgs, init_gauss, cam_poses, K, epochs_stage1=300, epochs_stage2=1700):
    gauss = Gaussian(xyz=init_gauss).cuda()
    opt = torch.optim.AdamW(list(gauss.parameters())+list(cam_poses.parameters()), lr=1e-4)
    # 阶段1:仅原图监督
    for _ in range(epochs_stage1):
        total_loss = 0.0
        for idx, img in enumerate(rgb_imgs):
            render_rgb, render_depth = render(gauss, cam_poses[idx], K)
            loss_rgb = l1_loss(render_rgb, img) + 0.1 * dssim_loss(render_rgb, img)
            loss_depth = 1 - pearson_corr(1/(render_depth+1e-6), mono_depth[idx])
            loss_c = loss_rgb + 0.5 * loss_depth
            total_loss += loss_c
        opt.zero_grad()
        total_loss.backward()
        opt.step()
    # 阶段2:WIG伪图联合优化
    for _ in range(epochs_stage2):
        loss_total = 0.0
        # 采样全新视角生成修复伪图
        novel_imgs, novel_poses = generate_wig_pseudo(rgb_imgs, cam_poses, K)
        for pseudo_img, novel_T in zip(novel_imgs, novel_poses):
            render_p, _ = render(gauss, novel_T, K)
            loss_pseudo = l1_loss(render_p, pseudo_img)
            loss_total += loss_c + 0.3 * loss_pseudo
        opt.zero_grad()
        loss_total.backward()
        opt.step()
    return gauss

五、海量实验数据深度解读

5.1 新视角渲染定量指标(Tanks数据集Table1节选)

方法 3视图PSNR↑ 3视图耗时 12视图PSNR↑ 是否无标定
3DGS 16.17 4m16s 22.48 否(需COLMAP)
InstantSplat 21.90 23s 27.33
COGS 18.56 50m8s 25.60
Ours(D2T) 23.39 41s 27.93

解读:

  1. 3张极稀疏无标定输入,D2T的PSNR比InstantSplat高1.49,画质拉开明显差距;
  2. 训练仅41秒,对比COGS五十分钟效率提升数十倍;
  3. 12张图场景依然SOTA,证明多图场景同样优势巨大。

5.2 相机位姿估计Table4(3视图Tanks)

方法 ATE轨迹误差↓ RPE平移误差↓
CF-3DGS 0.237 73.933
COGS 0.017 3.809
InstantSplat 0.025 12.221
Ours(D2T) 0.003 0.807

ATE代表相机整体轨迹全局误差,D2T比第二名COGS低5倍,位姿精度跨量级提升,根源是CADA精准深度对齐+WIG多视角约束,不断修正初始DUSt3R位姿偏差。

图6视觉定性对比解读

从左至右:FSGS / CF-3DGS / InstantSplat / Ours / GT真值

  • FS(i-W/2、j-H/2)CF:遮挡区域大面积模糊(i-W/2、j-H/2)重影;
  • InstantSplat:物体边缘缺失(i-W/2、j-H/2)空洞;
  • D2T:轮廓(i-W/2、j-H/2)纹理和真值高度贴合,遮挡区域完整还原,没有失真;
    场景覆盖室内雕塑(i-W/2、j-H/2)室内家具(i-W/2、j-H/2)小型物体,全部稳定最优。

5.3 消融实验Table5(3视图Tanks)

实验配置 PSNR 关键结论
去掉CADA 22.89 深度不准,形变错位,画质暴跌
去掉WIG模块 22.18 缺少新视角监督,严重过拟合
WIG去掉修复 22.29 空洞无有效监督,提升有限
完整D2T 23.39 所有模块缺一不可

消融清晰证明:CAD精准深度对齐(i-W/2、j-H/2)WIG形变修复两大创新是性能核心来源,少任意一块指标大幅下滑。

在这里插入图片描述

图8耗时饼图解读

总训练41秒拆分:

  1. CCM粗构建:7.71s(仅少量时间完成全局几何初始化);
  2. CADA+WIG生成伪图:1.44s(极轻量化,几乎无额外开销);
  3. 3D高斯联合精调:32.26s;
    亮点:新增两大创新模块总耗时不足10秒,几乎不增加训练负担,性能提升巨大,工程落地友好。

六、方法优缺点与未来拓展

优势

  1. 输入门槛极低:仅3~12张随手无标定手机照片,不用提前跑SfM;
  2. 速度与画质双SOTA,4090显卡几十秒完成重建;
  3. 三层创新耦合:DUSt3R全局粗几何+单目深度对齐+形变修复多视角监督,逻辑闭环;
  4. 同时优化3D模型+全部相机内外参,位姿精度远超同类无标定方案;
  5. 泛化性强:室内物体(i-W/2、j-H/2)大场景走廊(i-W/2、j-H/2)户外雕塑全部适配,零样本迁移真实人形机器人。

现有局限

当前全局点云对齐框架依赖完整图像连通图,几百张超大场景会内存爆炸,无法处理上千帧户外航拍大规模场景。

未来改进方向

  1. 增量式全局点云对齐,分段处理海量图片,适配城市级大场景重建;
  2. 加入时序平滑约束,让连续帧生成的BEV/深度时序更稳定;
  3. 融合激光(i-W/2、j-H/2)IMU传感数据,拓展自动驾驶实景重建赛道;
  4. 轻量化推理版本,适配手机端实时3D重建APP。

七、行业落地价值总结

  1. 消费端:普通人手机拍几张照片,快速生成高清3D手办(i-W/2、j-H/2)雕塑(i-W/2、j-H/2)家具模型,不用专业扫描设备;
  2. 机器人领域:巡检机器人少量视觉帧即可完成自身环境高精度3D重建,无预先标定流程;
  3. VR/AR:室内空间快速实景建模,降低虚拟场景制作成本;
  4. 工业质检:设备局部少量照片重建三维模型,用于尺寸偏差检测。

该方法是目前稀疏无标定3D高斯重建最优工程方案,也是人大王永才课题组TVCG顶刊代表性几何重建工作,和之前MapDream视觉语言导航形成感知-重建完整技术链路。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐