19fd610a958f9.png

01. 为什么 DUSt3R 值得关注

DUSt3R 的全称是 Dense and Unconstrained Stereo 3D Reconstruction。它的核心目标可以概括为一句话:

从两张或多张普通图片中,直接预测稠密三维点图,并进一步对齐成完整三维场景。

传统三维视觉通常依赖一条较长的工程管线:特征提取、特征匹配、位姿估计、三角化、Bundle Adjustment、多视图立体、点云融合等。每个环节都很成熟,但也都有自己的失败边界。DUSt3R 的前沿性在于,它把“图像对之间的三维几何关系”尽可能前移到神经网络中学习,并用全局对齐优化把成对预测整合为多视图结果。

这意味着它不仅是一个三维重建工具,更代表了一类新的趋势:用大规模视觉预训练模型承接传统几何视觉中最困难、最脆弱的部分,再用几何优化保证全局一致性。

02. 项目整体架构

本地代码的关键模块如下:

模块 作用 典型文件
模型主体 双图编码、非对称解码、预测三维点图与置信度 dust3r/model.py
推理流程 图像对批处理、模型前向推理、结果聚合 dust3r/inference.py
图像对构建 complete / sliding window / one reference 等场景图策略 dust3r/image_pairs.py
全局对齐 将成对 pointmap 统一到全局场景 dust3r/cloud_opt/
损失函数 3D 回归损失、置信度加权损失、尺度/平移不变约束 dust3r/losses.py
Demo 与部署 Gradio 交互界面、GLB 导出、Docker 配置 demo.py, dust3r/demo.py, docker/

DUSt3R 的端到端流程可以简化为:

19fd61a37b19f.png

03. 核心技术一:直接预测稠密三维点图

DUSt3R 与许多传统双目方法最大的不同,是它不是只预测视差或深度,而是直接预测每个像素对应的三维点坐标。

在 dust3r/model.py 中,模型类的注释已经清楚说明了这一点:

class AsymmetricCroCo3DStereo (
    CroCoNet,
    huggingface_hub.PyTorchModelHubMixin,
    library_name="dust3r",
    repo_url="https://github.com/naver/dust3r",
    tags=["image-to-3d"],
):
    """ Two siamese encoders, followed by two decoders.
    The goal is to output 3d points directly, both images in view1's frame
    (hence the asymmetry).   
    """

这里有两个非常关键的设计:

1. Two siamese encoders:两张图像先经过共享结构的编码器,得到各自的视觉 token 表示。

2. Two decoders + asymmetry:模型输出时以 view1 为参考坐标系,让 view2 的点也表达在 view1 坐标系中。

这种设计让模型天然适合处理图像对之间的相对几何关系。它不要求一开始就知道相机内参、外参,也不要求输入一定来自严格标定的双目相机。

04. 核心技术二:非对称双解码器建模跨视图关系

model.py 中的 _decoder 是理解 DUSt3R 的关键代码之一:

def _decoder(self, f1, pos1, f2, pos2):
    final_output = [(f1, f2)]  # before projection

    # project to decoder dim
    f1 = self.decoder_embed(f1)
    f2 = self.decoder_embed(f2)

    final_output.append((f1, f2))
    for blk1, blk2 in zip(self.dec_blocks, self.dec_blocks2):
        # img1 side
        f1, _ = blk1(*final_output[-1][::+1], pos1, pos2)
        # img2 side
        f2, _ = blk2(*final_output[-1][::-1], pos2, pos1)
        # store the result
        final_output.append((f1, f2))

    final_output[-1] = tuple(map(self.dec_norm, final_output[-1]))
    return zip(*final_output)

这段实现体现了 DUSt3R 的“对称输入、非对称输出”思想:

  • f1 的解码使用 (f1, f2),强调从图 1 看图 2。
  • f2 的解码使用 (f2, f1),强调从图 2 看图 1。
  • 两个方向共享整体结构,但输出最终会被组织到 view1 的参考坐标中。

在 forward 中,这个设计被进一步落实:

def forward(self, view1, view2):
    (shape1, shape2), (feat1, feat2), (pos1, pos2) = self._encode_symmetrized(view1, view2)

    dec1, dec2 = self._decoder(feat1, pos1, feat2, pos2)

    with torch.cuda.amp.autocast(enabled=False):
        res1 = self._downstream_head(1, [tok.float() for tok in dec1], shape1)
        res2 = self._downstream_head(2, [tok.float() for tok in dec2], shape2)

    res2['pts3d_in_other_view'] = res2.pop('pts3d')
    return res1, res2

res2['pts3d_in_other_view'] 是一个非常重要的字段:它表示第二张图中的点已经被预测到第一张图的坐标框架下。这使得后续成对匹配、点云融合和全局优化更直接。

05. 核心技术三:Pointmap 与 Confidence 的联合输出

预测头的后处理逻辑位于 dust3r/heads/postprocess.py:

def postprocess(out, depth_mode, conf_mode):
    """
    extract 3D points/confidence from prediction head output
    """
    fmap = out.permute(0, 2, 3, 1)  # B,H,W,3
    res = dict(pts3d=reg_dense_depth(fmap[:, :, :, 0:3], mode=depth_mode))

    if conf_mode is not None:
        res['conf'] = reg_dense_conf(fmap[:, :, :, 3], mode=conf_mode)
    return res

这里输出的并不是稀疏关键点,而是每个像素位置的三维点。与此同时,模型还输出置信度 conf。这对实际部署非常重要,因为三维重建常常会遇到天空、玻璃、反光表面、重复纹理、动态物体等不稳定区域。

置信度后处理如下:

def reg_dense_conf(x, mode):
    mode, vmin, vmax = mode
    if mode == 'exp':
        return vmin + x.exp().clip(max=vmax-vmin)
    if mode == 'sigmoid':
        return (vmax - vmin) * torch.sigmoid(x) + vmin
    raise ValueError(f'bad {mode=}')

从工程角度看,confidence 不只是可视化指标,更是后续点云过滤、全局优化加权、结果质量控制的核心依据。

06. 核心技术四:灵活的图像对场景图构建

多视图重建并不一定要对所有图片两两匹配。DUSt3R 在 dust3r/image_pairs.py 中提供了多种图像对构建方式:

def make_pairs(imgs, scene_graph='complete', prefilter=None, symmetrize=True):
    pairs = []
    if scene_graph == 'complete':  # complete graph
        for i in range(len(imgs)):
            for j in range(i):
                pairs.append((imgs[i], imgs[j]))
    elif scene_graph.startswith('swin'):
        iscyclic = not scene_graph.endswith('noncyclic')
        winsize = int(scene_graph.split('-')[1])
        ...
    elif scene_graph.startswith('oneref'):
        refid = int(scene_graph.split('-')[1]) if '-' in scene_graph else 0
        for j in range(len(imgs)):
            if j != refid:
                pairs.append((imgs[refid], imgs[j]))
    if symmetrize:
        pairs += [(img2, img1) for img1, img2 in pairs]
    return pairs

这部分看似简单,但对部署成本影响很大:

场景图策略 适用场景 优点 风险
complete 图片数量较少、需要高质量重建 覆盖充分、鲁棒性较好 图片多时计算量约为 O(N²)
swin 视频帧、连续采集图片 成本可控,适合时序场景 大跨度回环可能不足
oneref 以一张参考图对齐其他图片 简洁快速 参考图质量决定上限

实际应用中,建议根据图像数量、重叠度和实时性要求选择策略,而不是盲目使用 complete。

07. 核心技术五:从成对预测到全局三维场景

DUSt3R 推理输出的是一组图像对结果。若输入超过两张图,项目会使用 global_aligner 把这些局部关系合并为全局一致场景。

dust3r/cloud_opt/__init__.py 中的封装如下:

class GlobalAlignerMode(Enum):
    PointCloudOptimizer = "PointCloudOptimizer"
    ModularPointCloudOptimizer = "ModularPointCloudOptimizer"
    PairViewer = "PairViewer"

def global_aligner(dust3r_output, device, mode=GlobalAlignerMode.PointCloudOptimizer, **optim_kw):
    view1, view2, pred1, pred2 = [dust3r_output[k] for k in 'view1 view2 pred1 pred2'.split()]
    if mode == GlobalAlignerMode.PointCloudOptimizer:
        net = PointCloudOptimizer(view1, view2, pred1, pred2, **optim_kw).to(device)
    elif mode == GlobalAlignerMode.PairViewer:
        net = PairViewer(view1, view2, pred1, pred2, **optim_kw).to(device)
    return net

核心优化器 PointCloudOptimizer 会同时优化深度图、相机位姿、焦距和主点:

self.im_depthmaps = nn.ParameterList(torch.randn(H, W)/10-3 for H, W in self.imshapes)  # log(depth)
self.im_poses = nn.ParameterList(self.rand_pose(self.POSE_DIM) for _ in range(self.n_imgs))  # camera poses
self.im_focals = nn.ParameterList(torch.FloatTensor(
    [self.focal_break*np.log(max(H, W))]) for H, W in self.imshapes)  # camera intrinsics
self.im_pp = nn.ParameterList(torch.zeros((2,)) for _ in range(self.n_imgs))  # camera intrinsics

在优化目标中,它会把每条边上的 pairwise prediction 变换到全局坐标,并与当前全局点云估计做加权距离:

def forward(self):
    pw_poses = self.get_pw_poses()  # cam-to-world
    pw_adapt = self.get_adaptors().unsqueeze(1)
    proj_pts3d = self.get_pts3d(raw=True)

    aligned_pred_i = geotrf(pw_poses, pw_adapt * self._stacked_pred_i)
    aligned_pred_j = geotrf(pw_poses, pw_adapt * self._stacked_pred_j)

    li = self.dist(proj_pts3d[self._ei], aligned_pred_i, weight=self._weight_i).sum() / self.total_area_i
    lj = self.dist(proj_pts3d[self._ej], aligned_pred_j, weight=self._weight_j).sum() / self.total_area_j

    return li + lj

这也是 DUSt3R 与传统深度估计模型的明显区别:它不仅输出单张图的深度线索,还把跨图像的几何一致性纳入后处理优化。

08. 核心技术六:置信度加权的三维监督

训练损失位于 dust3r/losses.py。其中 Regr3D 关注三维点的几何误差:

class Regr3D (Criterion, MultiLoss):
    """ Ensure that all 3D points are correct.
        Asymmetric loss: view1 is supposed to be the anchor.
    """

    def compute_loss(self, gt1, gt2, pred1, pred2, **kw):
        gt_pts1, gt_pts2, pred_pts1, pred_pts2, mask1, mask2, monitoring = 
            self.get_all_pts3d(gt1, gt2, pred1, pred2, **kw)
        l1 = self.criterion(pred_pts1[mask1], gt_pts1[mask1])
        l2 = self.criterion(pred_pts2[mask2], gt_pts2[mask2])
        return Sum((l1, mask1), (l2, mask2)), monitoring

同时,ConfLoss 使用预测置信度对像素级误差进行加权:

conf1, log_conf1 = self.get_conf_log(pred1['conf'][msk1])
conf2, log_conf2 = self.get_conf_log(pred2['conf'][msk2])
conf_loss1 = loss1 * conf1 - self.alpha * log_conf1
conf_loss2 = loss2 * conf2 - self.alpha * log_conf2

这类设计非常适合真实世界输入。因为真实图像中的每个像素并不等价:纹理丰富的墙角、桌面边缘、建筑立面通常更可靠;天空、玻璃、运动物体则更可能带来错误估计。让模型同时学习“预测结果”和“预测可信度”,能显著增强系统的工程可控性。

09. 推理与 Demo:从图片到 GLB 文件

项目的 README 给出了标准调用方式,核心流程如下:

from dust3r.inference import inference
from dust3r.model import AsymmetricCroCo3DStereo
from dust3r.utils.image import load_images
from dust3r.image_pairs import make_pairs
from dust3r.cloud_opt import global_aligner, GlobalAlignerMode

device = 'cuda'
model_name = "naver/DUSt3R_ViTLarge_BaseDecoder_512_dpt"
model = AsymmetricCroCo3DStereo.from_pretrained(model_name).to(device)

images = load_images(['image1.png', 'image2.png'], size=512)
pairs = make_pairs(images, scene_graph='complete', prefilter=None, symmetrize=True)
output = inference(pairs, model, device, batch_size=1)

scene = global_aligner(output, device=device, mode=GlobalAlignerMode.PointCloudOptimizer)
loss = scene.compute_global_alignment(init="mst", niter=300, schedule="cosine", lr=0.01)

pts3d = scene.get_pts3d()
poses = scene.get_im_poses()
focals = scene.get_focals()
confidence_masks = scene.get_masks()

交互式 Demo 则进一步封装了上传图片、调整参数、导出三维文件的流程。在 dust3r/demo.py 中,最终会把结果导出为 .glb:

outfile = os.path.join(outdir, 'scene.glb')
scene.export(file_obj=outfile)
return outfile

对于业务集成,这一点很友好:.glb 可以直接进入 Web 3D、Unity、Unreal、Blender 或数字孪生平台。

10. 技术应用领域与前景 🌍

19fd61ce0eb0e.png

1. 机器人与具身智能

DUSt3R 能从普通 RGB 图像中恢复空间结构,对机器人抓取、导航、避障、场景记忆有直接价值。尤其在没有深度相机、没有标定双目、只有移动相机输入的场景中,它可以作为几何感知模块的候选方案。

2. AR / VR 与空间计算

AR 设备需要快速理解环境几何。DUSt3R 的 pointmap 输出可以为平面检测、遮挡关系、空间锚点、物体放置提供几何基础。未来如果与轻量化模型、实时 SLAM、IMU 融合,应用空间会更大。

3. 数字孪生与三维内容生产

在工业巡检、建筑测绘、室内建模、文旅资产数字化中,大量场景只有图片或视频资料。DUSt3R 能降低三维重建的输入门槛,帮助非专业采集设备快速生成可浏览的三维资产。

4. 视觉定位与地图构建

项目中还包含 dust3r_visloc 模块,说明 DUSt3R 不只面向重建,也可服务于视觉定位。稠密三维点图可以辅助 2D-3D 匹配、PnP 和位姿估计。

5. 自动驾驶与移动测绘

对车载视频、街景图片等场景,DUSt3R 可用于补充几何理解能力。但这类场景对尺度一致性、动态物体处理、远距离结构精度要求更高,部署时需要与传统 SLAM、传感器融合和质量评估模块配合。

11. 部署应用建议

1. 环境与依赖

项目基础依赖较清晰:

torch
torchvision
roma
gradio
opencv-python
scipy
einops
trimesh
huggingface-hub[torch]>=0.22

建议优先使用 Python 3.11 + CUDA GPU 环境。README 中给出的环境创建方式如下:

conda create -n dust3r python=3.11 cmake=3.14.0
conda activate dust3r
conda install pytorch torchvision pytorch-cuda=12.1 -c pytorch -c nvidia
pip install -r requirements.txt
pip install -r requirements_optional.txt

如果部署在 NVIDIA GPU 上,建议编译 RoPE CUDA kernel:

cd croco/models/curope/
python setup.py build_ext --inplace
cd ../../../

2. 模型选择建议

模型 适用情况 建议
DUSt3R_ViTLarge_BaseDecoder_224_linear 快速验证、资源有限 速度更友好,但细节有限
DUSt3R_ViTLarge_BaseDecoder_512_linear 较平衡的重建任务 适合作为工程基线
DUSt3R_ViTLarge_BaseDecoder_512_dpt 追求更好空间细节 推荐用于正式效果评估

3. 多图输入策略

  • 图片数量少于 10 张:可以优先尝试 complete,获得更充分的跨图约束。
  • 视频帧或连续拍摄图片:建议使用 swin,通过滑动窗口降低计算量。
  • 有明确主视角或基准图:可尝试 oneref,但要确保参考图清晰、视野覆盖充分。
  • 输入超过几十张:建议先做图像筛选、关键帧抽取、模糊过滤,再进入 DUSt3R。

4. 推理服务化建议

如果要封装为后端服务,推荐拆成四层:

API 层:接收图片、参数、任务 ID
预处理层:图片解码、缩放、EXIF 方向修正、质量过滤
推理层:make_pairs -> inference -> global_aligner
产物层:导出 GLB / 点云 / 深度图 / 置信度图 / 日志

工程上需要特别关注:

  • GPU 显存:512 分辨率与 complete graph 会快速增加显存压力。
  • 任务队列:三维重建通常是秒级到分钟级任务,适合异步处理。
  • 结果缓存:同一组图片和参数应缓存结果,避免重复推理。
  • 质量阈值:使用 min_conf_thr 过滤低置信区域,避免把明显错误点云交给下游。
  • 失败回退:当重建质量不足时,提示用户补充更多角度或重新拍摄,而不是静默输出低质量模型。

5. Docker 部署建议

项目已经提供 Docker 配置。GPU 版本可参考:

cd docker
bash run.sh --with-cuda --model_name="DUSt3R_ViTLarge_BaseDecoder_512_dpt"

Dockerfile 中使用 NVIDIA PyTorch 镜像,并安装依赖、编译 RoPE kernel:

FROM nvcr.io/nvidia/pytorch:24.01-py3

RUN pip install -r requirements.txt
RUN pip install -r requirements_optional.txt

WORKDIR /dust3r/croco/models/curope/
RUN python setup.py build_ext --inplace

生产部署时建议进一步补充:

  • 固定模型权重版本与 checksum。
  • 将权重挂载为只读 volume,避免容器重建时重复下载。
  • 对上传图片设置大小、格式、数量限制。
  • 为每个任务保存参数、日志、耗时、显存占用和导出产物路径。
  • 如果对外提供服务,增加鉴权、限流和任务过期清理。

12. 质量评估与常见问题

19fd61e809e5b.png
问题 可能原因 建议
点云破碎 图片重叠不足、视角跨度过大 增加中间视角,使用连续拍摄
结构扭曲 全局对齐约束不足 增加图片数量,尝试 complete 或更合理的 swin
大片噪声点 低纹理、天空、反光、动态物体 提高 min_conf_thr,启用清理策略
速度慢 图片数量多、complete graph 边数过大 关键帧抽取,改用 sliding window
尺度不稳定 单目/无标定输入天然存在尺度歧义 接入已知焦距、已知尺度物、IMU 或外部位姿先验

13. 与传统 SfM / MVS 的关系

DUSt3R 并不是简单替代传统 SfM / MVS,而是提供了一条新的路线:

维度 传统 SfM / MVS DUSt3R
输入要求 通常依赖可匹配纹理、相机模型、较稳健特征 更强调从数据中学习跨视图几何
输出形式 稀疏点云、相机位姿、深度/稠密点云 稠密 pointmap、confidence、全局点云
优势 理论成熟、可解释性强、精度上限高 输入门槛低、端到端能力强、适合复杂视觉先验
风险 弱纹理/重复纹理易失败 大模型成本、尺度/泛化/动态物体仍需处理

更现实的工程方向是二者融合:用 DUSt3R 提供强几何先验,用 SfM / SLAM / BA 做一致性约束和精修。

14. 合规与使用边界

项目代码声明使用 CC BY-NC-SA 4.0,并特别标注为非商业用途许可。因此:

  • 内部研究、学习、技术预研通常较适合。
  • 商业产品集成前必须审查许可证,并确认模型权重、训练数据、依赖库的许可边界。
  • 如果用于客户交付、在线服务、商业 SaaS 或硬件产品,需要进行法律与合规评估。

同时,DUSt3R 的输出不应被视为测绘级精度结果。若应用于工程测量、安全巡检、机器人执行等高风险场景,应加入人工复核、传感器冗余和误差评估。

15. 小结:DUSt3R 的真正价值

DUSt3R 的价值不只在于“能从图片生成三维点云”,而在于它展示了三维视觉技术的一种重要转向:

从手工拼接的几何管线,走向由视觉基础模型承担几何理解,再由优化模块保证全局一致性的混合范式。

这类技术会持续影响机器人、AR、数字孪生、视觉定位和三维内容生产。短期看,它适合作为三维重建和空间理解的强力预研工具;中期看,它很可能成为更多空间智能系统中的几何感知底座之一。

温和但务实地说:DUSt3R 还不是“拿来即用的万能三维引擎”,但它已经足够说明,未来的三维视觉系统会越来越少依赖固定相机假设,越来越多依赖模型对真实世界几何结构的学习与推理。✨

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注