全新多视角三维重建DUSt3R的原理详解与成果展示

DUSt3R(Dense and Unconstrained Stereo 3D Reconstruction)提出了一种全新的多视角三维重建范式,无需预先设定相机位姿和内参。

三维重建是计算机视觉领域中最引人入胜却又极具挑战性的问题之一。其应用范围极为广泛,从交互式数字孪生到机器人感知等场景均有涉及。多年来,三维重建方法已从传统的、面向特定任务的几何方法,逐步演进为现代基于深度学习的方法。尽管深度学习展现出巨大潜力,但大多数现有算法速度极慢、计算开销巨大,使得实时应用几乎不可行。

如果你曾使用过NeRF或高斯泼溅渲染(Gaussian Splatting),你一定深知从视觉场景中提取特征并生成稠密三维重建结果是多么耗时且耗费资源,尤其是在相机位姿未知、内参缺失,或图像来自真实复杂环境(“in the wild”)的情况下。但试想一下:如果仅用不到15张图像,在短短几分钟内,无需任何相机内参,就能获得高质量的初始点云地图用于你的高斯泼溅渲染,那会怎样?

这正是DUSt3R(Dense and Unconstrained Stereo 3D Reconstruction)所带来的突破。该模型由Naver Labs开发,也是更强大的MASt3R模型的前身。MASt3R属于新一代基础模型家族,致力于实现“统一的三维视觉模型”这一目标,能够同时处理多种下游任务,并显著降低系统复杂性。

全新多视角三维重建DUSt3R的原理详解与成果展示

本文讨论的关键概念概述如下:

现有方法的局限性

DUSt3R 如何为传统 SfM(运动恢复结构)和 MVS(多视角立体匹配)提供一种极具吸引力的替代方案

DUSt3R 与 COLMAP 稠密重建的推理结果及对比

现有三维重建方法概述

从根本上说,大多数三维重建系统都依赖于通过三角测量(triangulation)来估计二维像素与三维点之间的对应关系。传统的运动恢复结构(Structure-from-Motion, SfM)/ 视觉 SLAM 以及多视角立体匹配(Multi-View Stereo, MVS)方法,会利用从不同相机视角拍摄的一组二维图像,在考虑相机内参的前提下,重建出场景的三维结构。此外,也存在其他方法,例如单目深度估计器,它们可以借助几何先验知识对三维场景进行近似重建。

下图更清晰地展示了三维重建中涉及的不同方法,这些方法可支持多种下游任务。

全新多视角三维重建DUSt3R的原理详解与成果展示

SfM 与 MVS

传统的 SfM(运动恢复结构)和 MVS(多视角立体匹配)流程,例如在广泛使用的事实标准工具(如 COLMAP)中所实现的,通常包含多个级联的处理阶段:

1.基于 SfM 的稀疏重建:

全新多视角三维重建DUSt3R的原理详解与成果展示

特征提取与特征匹配
首先使用如 SIFT 或 ORB 等方法进行关键点检测和描述子提取,然后在两个视角之间匹配对应的关键点。这通常通过对图像对进行穷举搜索,构建一个对应关系图(correspondence graph)来实现。

三角测量(Triangulation)
初始阶段利用两幅图像估算相机位姿,随后通过三角测量计算出三维点。在此基础上,逐步引入更多视角,对三维点进行增量式优化。

全局光束法平差(Global Bundle Adjustment)
通过全局光束法平差对相机位姿和三维点进行联合优化,最小化观测关键点与其从三维模型重投影位置之间的重投影误差,从而获得更优的收敛结果。

鲁棒性提升
为提高鲁棒性,使用 RANSAC 算法滤除错误匹配(即离群点)。

虽然 SfM 生成的稀疏重建结果是一个良好的起点,但其缺乏表面细节。为弥补这一不足,COLMAP 流程还包含多视角立体匹配(MVS),可在稀疏重建的基础上进一步实现稠密重建。

然而,在现代方法中,通常仍使用 COLMAP 完成至光束法平差的步骤,而将 MVS 替换为 NeRF 或高斯泼溅(Gaussian Splatting),因为后者能提供更具照片真实感的场景渲染效果。


2. 基于 MVS 的稠密重建

在 COLMAP 的 SfM 流程中,若图像缺少 EXIF 元数据(如焦距、主点坐标),会启发式地估算针孔相机内参,或直接使用默认值。然而,在 MVS 阶段,相机的内参和外参必须已知。

全新多视角三维重建DUSt3R的原理详解与成果展示

MVS(多视角立体匹配)采用立体匹配技术,通过不同视角间的视差(disparity)计算深度。在 SfM 生成的稀疏地图基础上,MVS 沿对极线(epipolar line)采样更多点,从而生成稠密点云。COLMAP 的 MVS 模块通过以下方式估计深度:

基于对极几何(epipolar geometry)的几何结构

基于像素值的光度深度(photometric depth)

随后,各个视角生成的深度图被融合为统一的三维结构。不符合对极几何约束的深度值会被滤除。通过几何一致性校验(Geometric Ramification),可剔除不一致的匹配,从而确保对应关系的准确性(即多个视角中观察到同一三维点的像素)。


现有三维重建方法的不足

依赖完整的相机参数

:SfM 和 MVS 要求所有相机内参和外参均已知,才能准确生成稠密点云。

对图像数量和视角重叠要求高

:如前所述,大多数方法依赖多视角图像,通常需要大量图像且视角间重叠率较高(例如稠密重建常需约 60% 的重叠)。然而,真实世界的数据往往视角稀疏、视角有限,并包含遮挡物体,导致难以建立可靠的像素对应关系。

计算开销大

:全局光束法平差(Global Bundle Adjustment)具有立方级时间复杂度,计算成本高昂,难以扩展到大规模场景。

单目深度估计的局限性

:虽然单目深度估计算法实现简单,但其深度预测仅为近似值;若在缺乏相机内参的情况下将其投影到三维空间,精度较低。此外,该方法在处理无纹理表面、透明或反光表面时表现不佳,导致特征匹配极少。

NeRF 与高斯泼溅的场景特异性

:最新的方法如 3D 高斯泼溅(3D Gaussian Splatting)和 NeRF 在三维场景重建和新视角合成方面表现出色,但它们通常是针对特定场景进行优化(即存在过拟合),需要为每个场景单独训练,难以泛化到未见过的环境。

理解 DUSt3R:一种统一的三维视觉模型

如前所述,COLMAP 流程包含一系列复杂的串行阶段,不仅计算密集,而且耗时。由于涉及多个相互依赖的模块,这类传统流程容易引入噪声和误差,进而影响重建质量。

但试想一下:如果我们能够跳过或绕开所有这些中间步骤呢?如果有一个模型可以直接建立二维图像像素坐标与三维点之间的对应关系,会怎样?

这正是 DUSt3R 所实现的突破——它通过一种称为场景坐标回归(Scene Coordinate Regression, SCR)匹配的机制,构建出一种名为点图(Pointmap) 的表示形式。

点图(Pointmap)表示

点图与输入图像具有相同的尺寸,但它不存储 RGB 颜色值,而是为每个像素编码对应的三维空间坐标 ((x, y, z)),从而直接表示一个三维点云。通过对点图进行网络训练,模型能够学习到:

场景的几何先验知识

,从而推断出三维结构;

直接的 2D–3D 对应关系

,完全无需三角测量。

点图表示在保留以下关键特性的同时,对三维场景几何进行编码:

多视角下的二维像素一致性(相对位姿)

:避免因视角变化导致的几何扭曲;

直接的 2D 到 3D 空间映射

:每个像素都明确关联到一个三维点;

完整的三维场景几何(点云)

:维持点与点之间的空间拓扑关系。

全新多视角三维重建DUSt3R的原理详解与成果展示

由于点图建立了直接的 2D–3D 关联,仅凭点图即可轻松恢复出所有场景参数,包括:

相机内参(Camera Intrinsics)

深度估计(Depth Estimation)

像素对应关系(Pixel Correspondences)

相机位姿估计([R | t] 矩阵)

稠密三维重建(Dense 3D Reconstruction)

与传统方法将流程拆分为多个独立阶段不同,DUSt3R 在一个统一的端到端模型中联合学习从 2D 图像模式到 3D 形状的映射。这种方式无需显式进行三角测量,使其天然具备强大的几何结构和形状先验知识,从而显著降低噪声。因此,DUSt3R 成为一个通用、鲁棒且端到端的统一基础模型,尤其适用于相机位姿未知的三维重建任务。

DUSt3R 与 MASt3R 均基于一种名为 CroCo(Cross-View Completion,跨视角补全) 的共同预训练策略——这是由同一团队早期提出的一项基础性研究。CroCo 构成了这些模型的核心组件,使其成为几何视觉任务的强大基础架构。DUSt3R 采用了一种 非对称 CroCo(Asymmetric CroCo),这是原始 CroCo v1 框架的一个轻微变体。不过,在深入探讨非对称 CroCo 之前,我们先回顾一下原始的 CroCo 策略,这有助于更好地理解该方法的演进过程。

在深入剖析 DUSt3R 的技术细节之前,让我们先简要看看 DUSt3R 究竟能做到什么:

全新多视角三维重建DUSt3R的原理详解与成果展示

什么是 CroCo 预训练策略?

假设我们采用一种基于单视角的自补全(autocompletion)作为预训练任务,传统的掩码图像建模(Masked Image Modeling, MIM)会根据图像内部的空间信息来填充被遮盖区域的缺失像素。MIM 在高层次语义任务(如图像分类和目标检测)上表现优异,但它难以捕捉场景的底层几何结构。

这一局限性的根源在于:三维重建本质上是一个多视角问题。仅使用单张图像进行训练是不够的,因为单视角缺乏推断有意义三维表示所必需的几何上下文和空间一致性。因此,将 MIM 这类预训练任务迁移到深度估计、相对位姿估计、光流估计等底层下游任务时,会面临巨大挑战。

全新多视角三维重建DUSt3R的原理详解与成果展示

那么,CroCo 的策略是什么呢?

受 MIM(掩码图像建模)设计理念的启发,CroCo 框架引入了来自不同视角的第二张图像作为参考。这一额外视角用于引导重建过程:在对一张图像进行掩码建模的同时,以另一张视角的图像为条件进行补全。这种方法被证明在底层下游任务中非常有效(而非高层语义任务),因为它在被掩码视图与参考视图之间提供了出色的几何空间关系和上下文线索。

即使在高达 90% 的大比例掩码情况下,CroCo 在 2D 或 3D 回归任务(如深度估计、位姿回归等)上依然表现优异。

全新多视角三维重建DUSt3R的原理详解与成果展示

从数学形式上看,CroCo 可以表示为:

(1)

全新多视角三维重建DUSt3R的原理详解与成果展示

具体流程如下:

首先,选取大量具有充分重叠区域的多样化图像对,并将每张图像划分为大小相等、互不重叠的图像块(patches)。与掩码图像建模(MIM)类似,第一张图像会被随机掩码。随后,掩码视图和参考视图通过一个权重共享的标准 ViT(Vision Transformer)编码器分别编码为潜在表示。

该编码器以孪生(siamese)结构独立处理掩码视图(也称为查询图像 (

全新多视角三维重建DUSt3R的原理详解与成果展示

)和参考视图 (p_2),并对数据增强具有不变性,从而生成各自的潜在特征。为了增强空间理解能力,第一张图像中未被掩码的图像块编码会通过交叉注意力(cross-attention)机制,关注参考图像的图像块编码。

最后,CroCo 的 ViT 解码器 (D_phi) 的目标是通过跨视角补全(Cross-View Completion)来预测被掩码的图像块。它以参考视图的编码为条件,对掩码视图的编码进行解码,并使用 L2 回归损失重建目标图像 (p_1),即预测被掩码区域的缺失像素值。

全新多视角三维重建DUSt3R的原理详解与成果展示

跨视角补全(Cross-View Completion):

让我们更仔细地关注解码器中实现跨视角补全的注意力模块。编码器输出的潜在编码会与正弦位置嵌入(sinusoidal positional embeddings)相加。这些位置嵌入的作用与常规 Transformer 中一致:保留空间上下文信息,并标识在展平后的序列中哪些图像块(patches)是被掩码的。

随后,这些编码依次通过解码器中的一系列 Transformer 块,每个块包含多头自注意力(Multi-Head Self-Attention, MHA)和 MLP 层。作者实验了两种不同类型的解码器块:

CrossBlock:首先对第一个输入(即查询图像中未被掩码的 token)执行多头自注意力,然后与参考图像的 token 进行交叉注意力(cross-attention)。这种设计在模型表达能力和计算效率之间取得了良好平衡。

CatBlock:将来自两个视图的 token 拼接(concatenate)在一起,并加入额外的可学习图像嵌入(image embeddings),再送入标准的 Transformer 解码器进行处理。

最终,解码器为每个图像块中的每个像素输出三个值(RGB),从而生成一个大小为 
patch_size × patch_size × 3
 的重建结果。例如,对于 16×16 的图像块,每个块的输出维度为 (16 imes 16 imes 3 = 768) 个数值。

全新多视角三维重建DUSt3R的原理详解与成果展示

CroCo 预训练模型的特性:

具备出色的几何理解与场景理解能力。

已被证明能够学习三维视觉任务中的关键基础组件(“重要积木”)。

架构通用,易于适配各种下游任务。

达到当时最先进的性能(SOTA),甚至超越了许多专为特定任务设计的模型。

在 CroCo 发布时,作者通过为每个下游任务分别微调不同的模型检查点来取得成果。尽管如此,这项工作为统一模型架构奠定了基础。随后,他们成功开发出了目标中的统一模型——DUSt3R;次年,又推出了其进一步演进版本 MASt3R,该模型不仅能预测像素对应关系,还能提取局部特征,标志着他们在该方向上的又一次飞跃。


DUSt3R 的预训练数据集

DUSt3R 在一个大规模混合数据集上进行预训练,其中合成数据与真实数据各占一半:合成数据提供完美的几何先验,而真实数据则使模型适应现实世界的分布。数据集涵盖室内与室外场景,总计包含 850 万对图像(8.5M image pairs)。

数据集(Dataset)

类型(Type)

图像对数量(N Pairs)

Habitat

室内 / 合成

100k

CO3Dv2

以物体为中心

941k

ScanNet++

室内 / 真实

224k

ARKitScenes

室内 / 真实

2,040k

Static Thing 3D

物体 / 合成

337k

MegaDepth

室外 / 真实

1,761k

BlendedMVS

室外 / 合成

1,062k

Waymo

室外 / 真实

1,100k


DUSt3R 的训练策略

与采用自监督策略的 CroCo 不同,DUSt3R 采用全监督方式训练,使用在同一规范参考坐标系(canonical reference frame)下对齐的图像对及其真实标签(ground truth)。

为保证各类数据均衡,从每个数据集中随机采样图像对,维持整体数据分布的平衡。

训练分两个阶段进行:

首先在 224×224 分辨率的图像上进行预训练;

然后提升至 512×512 分辨率,以获得更高精度的重建结果。

为处理不同长宽比的输入图像,所有图像均经过裁剪和缩放,确保其最大边长不超过 512 像素。

此外,DUSt3R 并非从零开始训练,而是直接利用现成的 CroCo 预训练模型作为初始化,继承其已学习到的丰富特征表示能力,从而加速收敛并提升性能。

损失函数(Loss Functions):

DUSt3R 采用一种尺度不变的回归损失(scale-invariant regression loss)进行训练,以避免归一化后的真值点图与预测点图之间因尺度差异而产生的歧义。

整个训练过程由两个关键损失函数共同引导:

3D 回归损失

如前所述,点图回归本质上是一个三维回归问题。该损失通过计算预测点图与真实点图之间在有效像素上的欧氏距离(Euclidean distance),来保持三维结构的一致性。

全新多视角三维重建DUSt3R的原理详解与成果展示

全新多视角三维重建DUSt3R的原理详解与成果展示

2. 置信度感知损失

在现实世界的场景中,由于透明度、反射或遮挡等因素,某些像素难以准确预测。为了减少这些区域的误差,网络还学习为每个像素输出一个置信度分数。这意味着模型不仅尝试预测每个像素的深度值,还会评估自己预测的可信度,从而在处理那些因上述因素而难以预测的像素时,能够通过降低这些像素的权重来减轻潜在错误对整体性能的影响。这种方法提高了模型对于复杂和挑战性场景的适应性和鲁棒性。

全新多视角三维重建DUSt3R的原理详解与成果展示

最终的训练目标是在所有有效像素上应用的一种置信度加权的回归损失

全新多视角三维重建DUSt3R的原理详解与成果展示

全新多视角三维重建DUSt3R的原理详解与成果展示

该方法通过让模型对不确定区域(如透明、反射或无纹理表面,例如天空或玻璃)分配较低置信度,从而有效处理定义不明确的像素点,保证三维表示的准确性。

优化策略——全局对齐(Global Alignment)

与传统的运动恢复结构(SfM)不同,DUSt3R 并未采用光束法平差(Bundle Adjustment, BA)来最小化二维重投影误差。相反,它提出了一种首创的全局对齐策略,直接在三维空间中最小化误差,通过联合优化相机位姿和场景几何结构来实现更精确的重建。

当输入图像数量超过两张时,DUSt3R 会执行以下操作:

计算两两之间的相对位姿估计,并构建一个两两连接图(pairwise connectivity graph),通过设定阈值筛选出置信度得分总和较高的图像对,从而找到最优的匹配组合。

迭代优化所有两两点图(pointmaps),将它们逐步对齐到一个统一的参考坐标系中。这一过程在理念上类似于光束法平差(Bundle Adjustment, BA),但速度更快、效率更高,即使仅使用少量图像也能迅速收敛。

全新多视角三维重建DUSt3R的原理详解与成果展示

全新多视角三维重建DUSt3R的原理详解与成果展示

DUSt3R:模型架构

全新多视角三维重建DUSt3R的原理详解与成果展示

DUSt3R 的架构与 CroCo v1 相似,但做了一处细微调整,采用了非对称设计。这种非对称性体现在:DUSt3R 使用了两个独立的解码器,而不是像 CroCo 那样采用共享的解码器。

全新多视角三维重建DUSt3R的原理详解与成果展示

DUSt3R:模型架构详解

图像块编码(Patch Encodings)

DUSt3R 的编码器接收一组 RGB 图像作为输入,首先将图像划分为图像块(patchified),并添加旋转位置嵌入(rotary positional embeddings)。在编码器部分,其设计与 CroCo 非常相似:随机掩码部分图像块,并将第一视图和第二视图的嵌入分别送入两个解码器。

编码器由 24 个编码块(encoder blocks) 组成,每个块包含自注意力(self-attention)层和 MLP 层,最终输出的嵌入维度为 1024


AsymmetricCroCo3DStereo(
  (patch_embed): PatchEmbedDust3R(
    (proj): Conv2d(3, 1024, kernel_size=(16, 16), stride=(16, 16))
    (norm): Identity()
  )
  (mask_generator): RandomMask()
  (rope): cuRoPE2D()
  (enc_blocks): ModuleList(
    (0-23): 24 x Block(
      (norm1): LayerNorm((1024,), eps=1e-06, elementwise_affine=True)
      (attn): Attention(...)
      (mlp): Mlp(
        ...
        (fc2): Linear(in_features=4096, out_features=1024, bias=True)
      )
    )
  )
)


非对称 CroCo v2 立体解码器(Asymmetric CroCo v2 Stereo Decoder)

DUSt3R 引入了第二个独立的解码器,专用于处理第二视图的 token。两个解码器结构相同,但参数不共享。第一视图和第二视图的特征通过交叉注意力(cross-attention) 相互交互。

每个解码器包含 12 个 CrossBlock,每个 CrossBlock 包含自注意力、交叉注意力和 MLP 层,每块输出维度为 768。两个解码器之间持续交换信息,以引导模型输出空间对齐一致的点图(pointmaps)。


(decoder_embed): Linear(in_features=1024, out_features=768, bias=True)
# 解码器 1
(dec_blocks): ModuleList(
  (0-11): 12 x DecoderBlock(
    (norm1): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
    (attn): Attention(...)
    (cross_attn): CrossAttention(...)
    (mlp): Mlp(
      ...
      (fc2): Linear(in_features=3072, out_features=768, bias=True)
    )
  )
)
# 解码器 2
(dec_blocks2): ModuleList(
  (0-11): 12 x DecoderBlock(
    (norm1): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
    (attn): Attention(...)
    (cross_attn): CrossAttention(...)
    (mlp): Mlp(
      ...
      (fc2): Linear(in_features=3072, out_features=768, bias=True)
    )
  )
)

解码器 1:

负责重建第一张图像的点图,生成该视角下的三维点云。

输出红色点图 ((X^{1,1}, C^{1,1})),其坐标系以相机 1 为中心,并沿 z 轴方向定义(即相机 1 位于原点,朝向正前方)。

解码器 2:

利用交叉注意力,将第二张图像的点图对齐到第一张图像的公共参考坐标系中,从而隐式估计跨视角的相机位姿。

输出蓝色点图 ((X^{2,1}, C^{2,1})),其中所有点均表达在相机 1 的坐标系下

相机 2 的位置和姿态是相对于相机 1 的坐标系进行估计的,确保两个点云处于同一三维坐标系中。


用于深度图的下游预测头(Downstream Head for DepthMap)

最后,模型附加了两个下游 DPT(Dense Prediction Transformer)回归头。每个回归头输出 4 个通道,分别用于:

从深度图推导出三维点云的坐标 ((x, y, z));

以及每个像素对应的置信度分数

需要注意的是,输出的点图是尺度不确定的(up to an unknown scale),即深度值是相对深度,而非具有真实物理单位的度量深度(metric depth)。

尽管如此,所生成的点图在几何上仍高度符合物理上合理的相机模型,为后续的三维重建、位姿估计等任务提供了可靠的基础。

全新多视角三维重建DUSt3R的原理详解与成果展示


## HEAD 1 - First view
(downstream_head1): PixelwiseTaskWithDPT(
   (dpt): DPTOutputAdapter_fix(. . .)
     (head): Sequential(
       (0): Conv2d(256, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    . . .
       (4): Conv2d(128, 4, kernel_size=(1, 1), stride=(1, 1))
     )
     (act_postprocess): ModuleList( . . . )
# HEAD 2 - Second view
(downstream_head2): PixelwiseTaskWithDPT(
   (dpt): DPTOutputAdapter_fix(. . .)
     (head): Sequential(
       (0): Conv2d(256, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    . . .
       (4): Conv2d(128, 4, kernel_size=(1, 1), stride=(1, 1))
     )
     (act_postprocess): ModuleList( . . . )

DUSt3R 能够从一对图像中预测出点图(point maps),并从中恢复相机参数。对于单目重建,可以通过将同一输入图像重复输入两次,来获得一个可以估计焦距(focal length)的点图。

全新多视角三维重建DUSt3R的原理详解与成果展示

1.点匹配或像素对应关系(Point Matching or Pixel Correspondences)

全新多视角三维重建DUSt3R的原理详解与成果展示

全新多视角三维重建DUSt3R的原理详解与成果展示

2.视觉定位(Visual Localization)

全新多视角三维重建DUSt3R的原理详解与成果展示

3.多视角位姿估计(Multi-view Pose Estimation)

基于这些对应关系,DUSt3R 采用诸如 PnP(Perspective-n-Point,透视 n 点)算法并结合 RANSAC(随机抽样一致性)来鲁棒地估计相对相机位姿。

全新多视角三维重建DUSt3R的原理详解与成果展示

4.单目深度估计(相对值)

点云地图与深度图通过相机内参建立如下关系:

全新多视角三维重建DUSt3R的原理详解与成果展示

其中 X表示其所在相机坐标系下的点云坐标。若需将坐标转换至其他相机坐标系:

全新多视角三维重建DUSt3R的原理详解与成果展示

全新多视角三维重建DUSt3R的原理详解与成果展示

5.多视角深度估计与三维重建(Multi-view Depth and 3D Reconstruction)

全新多视角三维重建DUSt3R的原理详解与成果展示

6.恢复相机内参

X 以其自身的相机坐标系表示。

全新多视角三维重建DUSt3R的原理详解与成果展示

DUSt3R 的性能指标

DUSt3R 在多视角相机位姿估计和深度预测任务上表现尤为出色,无需针对特定任务进行微调即可达到当前最先进的性能(SOTA)。它能够在零样本(zero-shot)设置下运行,并对未见过的查询图像实现良好泛化。在其他相关任务中,其性能不仅显著优于自监督基线方法,甚至能达到与有监督模型相媲美的水平。

然而,尽管 DUSt3R 具有极强的鲁棒性,但由于其采用的是基于回归的重建方法,在绝对精度方面仍略逊于当前最先进的多视角立体视觉(MVS)基线方法。

到目前为止,我们已经从理论角度深入理解了 DUSt3R 内部工作机制的所有细节。现在,是时候更仔细地审视 DUSt3R 流水线的具体实现细节了。

为此,我们将主要基于官方源码中的推理脚本 
dust3r/dust3r/demo.py
 进行讲解。不过,我们建议您点击“下载代码”按钮并填写相关信息,以获取推理部分所展示的全部数据集文件和点云输出结果。


DUSt3R 推理流水线代码详解

要在本地运行 DUSt3R,只需克隆其代码仓库。由于 DUSt3R 依赖于 CroCo 仓库中的模块,请务必递归安装所有子模块


git clone --recursive https://github.com/naver/dust3r
cd dust3r
# 如果你已克隆过 dust3r:
# git submodule update --init --recursive

接着安装必要的依赖项:

pip install -r requirements.txt


可选:你也可以安装额外的包以支持以下功能:

HEIC 图像格式支持

pyrender(用于某些数据集预处理中的深度图渲染)

visloc.py 所需的依赖项


pip install -r requirements_optional.txt


DUSt3R 使用 RoPE(旋转位置编码),你可以选择性地编译 CUDA 内核以加速运行:


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

模型检查点

在运行时,你可以直接通过参数指定模型类型,
demo.py
 会自动下载对应的模型。你也可以手动下载并将其放入工作目录下的 
checkpoints/
 文件夹中:


mkdir -p checkpoints/
wget https://download.europe.naverlabs.com/ComputerVision/DUSt3R/DUSt3R_ViTLarge_BaseDecoder_512_dpt.pth -P checkpoints/

DUSt3R 提供三种模型变体,区别在于输入分辨率(如 224×224 或 512×512)以及预测头类型(Linear 或 DPT):

模型名称

训练分辨率

预测头

编码器

解码器


DUSt3R_ViTLarge_BaseDecoder_224_linear.pth

224×224

Linear

ViT-L

ViT-B


DUSt3R_ViTLarge_BaseDecoder_512_linear.pth

512×384, 512×336, 512×288, 512×256, 512×160

Linear

ViT-L

ViT-B


DUSt3R_ViTLarge_BaseDecoder_512_dpt.pth

512×384, 512×336, 512×288, 512×256, 512×160

DPT

ViT-L

ViT-B

本文中展示的所有推理结果均使用 
DUSt3R_ViTLarge_BaseDecoder_512_dpt
 检查点,在配备 i7 第13代 CPU 和 RTX 3080 Ti(12GB 显存)的系统上生成。实际显存需求会根据输入图像数量和所选的全局对齐方法有所不同,我们稍后会进一步讨论这一点。


导入依赖


import argparse
import math
import builtins
import datetime
import gradio
import os
import torch
import numpy as np
import functools
import trimesh
import copy
from dust3r.utils.device import to_numpy
import matplotlib.pyplot as pl

demo.py 脚本提供了一个 Gradio 界面用于测试 DUSt3R,支持多种与模型分辨率及 Gradio 配置相关的参数。


参数说明:

参数

描述


--model_name

可选模型:
• 
DUSt3R_ViTLarge_BaseDecoder_512_dpt
(默认)
• 
DUSt3R_ViTLarge_BaseDecoder_512_linear

• 
DUSt3R_ViTLarge_BaseDecoder_224_linear


--weights

模型权重路径,例如:

checkpoints/DUSt3R_ViTLarge_BaseDecoder_512_dpt.pth


--image_size

模型支持的分辨率:
[512, 224]

默认值:512


--device

指定设备:
"cpu"

"cuda"
 或 
"mps"

默认为 
"cuda"


def get_args_parser():
    parser = argparse.ArgumentParser()
    parser_url = parser.add_mutually_exclusive_group()
    parser_url.add_argument("--local_network", action='store_true', default=False,
                            help="使应用可在本地网络访问:地址将设为 0.0.0.0")
    parser_url.add_argument("--server_name", type=str, default=None, help="服务器 URL,默认为 127.0.0.1")
    parser.add_argument("--image_size", type=int, default=512, choices=[512, 224], help="图像尺寸")
    parser.add_argument("--server_port", type=int, help=("将在该端口启动 Gradio 应用(若可用)。"
                                                         "若未指定,则从 7860 开始寻找可用端口。"),
                        default=None)
    parser_weights = parser.add_mutually_exclusive_group(required=True)
    parser_weights.add_argument("--weights", type=str, help="模型权重路径", default=None)
    parser_weights.add_argument("--model_name", type=str, help="模型权重名称",
                                choices=["DUSt3R_ViTLarge_BaseDecoder_512_dpt",
                                         "DUSt3R_ViTLarge_BaseDecoder_512_linear",
                                         "DUSt3R_ViTLarge_BaseDecoder_224_linear"])
    parser.add_argument("--device", type=str, default='cuda', help="PyTorch 设备")
    parser.add_argument("--tmp_dir", type=str, default=None, help="临时目录路径")
    parser.add_argument("--silent", action='store_true', default=False,
                        help="静默日志输出")
    return parser


运行 Gradio 演示


python3 demo.py --model_name DUSt3R_ViTLarge_BaseDecoder_512_dpt
# 使用 --weights 从本地加载检查点,例如:
# --weights checkpoints/DUSt3R_ViTLarge_BaseDecoder_512_dpt.pth
# 使用 --image_size 指定分辨率:512(默认)或 224
# 使用 --local_network 使服务在局域网可访问,或用 --server_name 手动指定 URL
# 使用 --server_port 指定端口(默认从 7860 开始自动查找)
# 使用 --device 指定设备,默认为 "cuda"

运行后,DUSt3R 的 Gradio 推理界面将如下所示:

数据集示例:Tanks&Temples / Family

https://www.tanksandtemples.org/download/

为了去除噪声,我们将基于置信度值应用 
mask_sky
(天空掩码),并相应调整置信度阈值。

全新多视角三维重建DUSt3R的原理详解与成果展示

如果你在上面的演示中注意到了,我们选择了 “one-ref” 作为场景图(scenegraph)配置。那么,这到底是什么?我们又为何专门选择它呢?


理解 DUSt3R 的场景图策略与图像配对方式

DUSt3R 流水线通过 
image_pairs.py
 提供了一种结构化的方式来准备用于多视角三维重建的输入图像对。其核心思想是构建一个连通性图(connectivity graph),其中:

边(Edges)

 表示当前的锚点图像(anchor image);

关系(Relations)

 表示所有与之匹配的图像,共同构成一个成对图(pairwise graph)。

所选的场景图策略会直接影响全局对齐的收敛性计算效率。成对图中的每一条边都通过共享的视觉内容为整体重建提供信息,并利用已知或估计的相机位姿、主点(principal points)和焦距,迭代优化相机的内参(intrinsics)与外参(extrinsics)。

目前支持以下几种场景图配对策略:


1. 完全配对(Complete Pairing, “complete”)

每张图像与序列中所有之前的图像进行配对。

示例:对于图像序列 
[A, B, C, D]
,生成的配对为:

(B, A), (C, A), (C, B), (D, A), (D, B), (D, C)

优点

:有助于模型理解全局上下文。

缺点

:计算开销大,内存消耗高。

适用场景

:小型数据集(例如 < 15 张图像),内存受限时慎用。

社区反馈

:多位用户报告,在 A100(80GB 显存)上处理超过 120 张图像时,“complete” 配对会导致显存溢出(OOM)。


2. 滑动窗口配对(Sliding Window Pairing, “swin”)

每张图像仅与其在指定窗口大小内的相邻图像配对。

示例:
winsize = 2
,图像序列为 
[A, B, C, D]
,生成的配对为:

(A, B), (A, C), (B, C), (B, D), (C, D)

窗口大小如何确定?

实际窗口大小由输入图像总数决定,通常设为 
⌈(N−1)/2⌉

优点

对连续帧(如 360° 视频)非常高效;

通过限制配对范围,仅保留高度匹配的特征,显著降低计算量。

适用场景

:具有时间或空间连续性的图像序列。


3. 单参考配对(Single Reference Pairing, “oneref”)

固定一张图像作为参考视图(anchor),与其他所有图像配对。

参考图像 ID 可在 
0
 到 
len(images)−1
 之间任意选择,默认为 
0

示例:
ref_id = 0
,图像序列为 
[A, B, C, D]
,生成的配对为:

(A, B), (A, C), (A, D)

优点

内存占用远低于 “complete” 和 “swin”;

适合大规模数据集。

适用场景

:图像数量较多、显存有限的情况。


界面中的 
scene_graph_options
 工具可动态切换上述配对策略:


from dust3r.image_pairs import make_pairs
def set_scenegraph_options(inputfiles, winsize, refid, scenegraph_type):
    num_files = len(inputfiles) if inputfiles is not None else 1
    max_winsize = max(1, math.ceil((num_files - 1) / 2))
    if scenegraph_type == "swin":
        winsize = gradio.Slider(label="Scene Graph: Window Size", value=max_winsize,
                                minimum=1, maximum=max_winsize, step=1, visible=True)
        refid = gradio.Slider(label="Scene Graph: Id", value=0, minimum=0,
                              maximum=num_files - 1, step=1, visible=False)
    elif scenegraph_type == "oneref":
        winsize = gradio.Slider(label="Scene Graph: Window Size", value=max_winsize,
                                minimum=1, maximum=max_winsize, step=1, visible=False)
        refid = gradio.Slider(label="Scene Graph: Id", value=0, minimum=0,
                              maximum=num_files - 1, step=1, visible=True)
    else:  # complete
        winsize = gradio.Slider(visible=False)
        refid = gradio.Slider(visible=False)
    return winsize, refid

当图像上传至界面后,
get_reconstructed_scene
 函数将返回重建的 3D 场景。首先,RGB 图像被加载到内存中;随后,根据所选的配对策略生成图像对,并执行后续步骤:


def get_reconstructed_scene(outdir, model, device, silent, image_size, filelist, 
                           schedule, niter, min_conf_thr, as_pointcloud, mask_sky, 
                           clean_depth, transparent_cams, cam_size,
                           scenegraph_type, winsize, refid):
    """
    从图像列表出发,运行 DUSt3R 推理与全局对齐,
    然后调用 get_3D_model_from_scene 生成 3D 模型。
    """
    from dust3r.utils.image import load_images
    imgs = load_images(filelist, size=image_size, verbose=not silent)
    # 单图情况:复制一份用于单目重建
    if len(imgs) == 1:
        imgs = [imgs[0], copy.deepcopy(imgs[0])]
        imgs[1]['idx'] = 1
    # 构建场景图字符串
    if scenegraph_type == "swin":
        scenegraph_type = f"swin-{winsize}"
    elif scenegraph_type == "oneref":
        scenegraph_type = f"oneref-{refid}"
    # 生成图像对
    pairs = make_pairs(imgs, scene_graph=scenegraph_type, prefilter=None, symmetrize=True)


预测与全局对齐

输入图像被送入 
inference(...)
 函数,作为两个不同视角(“view 1” 和 “view 2”)进行处理。

1. 前向传播(AsymmetricCroCo3DStereo 模型,
dust3r/model.py

模型输出 
pred1
 和 
pred2
,每个预测包含:

深度图(depth)

:模型估计的逐像素深度值;

3D 点图(pts3d)

:基于模型估计的伪焦距,从深度图反投影得到的 View 1 的世界坐标 
(x, y, z)

跨视图对应点(pts3d_in_other_view)

:View 2 的 3D 点转换到 View 1 的参考坐标系下;

相机位姿(camera_pose)

:用于 3D 对齐的位置与旋转矩阵。

这种方式实现了直接的 2D 到 3D 映射,无需显式三角测量。

2. 全局对齐(Global Alignment)

在 CroCo 模型预测出深度与点图后,系统执行全局优化,调整以下参数:


'Pw_poses'
:成对相对位姿;
'im_depthmaps'
:每张图像的深度估计;
'im_poses'
:各图像在世界坐标系中的相机位置与朝向;
'im_focals'
:每张图像的伪焦距。

导出 3D 场景为 GLB 格式

最终,重建的 3D 场景会被保存为 
.glb
 文件,并可在界面中以网格(mesh)或稠密点云形式查看。

点云可视化

更流畅、资源消耗更低;

为提升清晰度,可减小相机视锥体大小(
cam_size
),甚至将其滑块调至最小值(如 0.001)以完全隐藏。


main_demo(...)
 函数整合了整个流程,通过 Gradio 界面统一处理推理与可视化。


训练说明

作者也公开了 DUSt3R 的训练脚本与超参数:

训练从 
CroCo_V2_ViTLarge_BaseDecoder.pth
(224 分辨率)开始;

后续在 512 分辨率下继续训练,并加载前一阶段的检查点;

更多细节请参阅仓库的 
README


实验经验分享

在我们的实验中(12GB 显存系统):

当输入图像超过 30 张并使用 “complete” 配对时,出现 OOM 错误

此时切换至 “one-ref” 或 “swin” 可在给定算力下成功运行;

有趣的是

,我们未观察到不同策略在重建质量上有显著差异(仍需进一步验证)。

如果你有更深入的见解或不同观点,欢迎在评论区分享!我们很乐意向你学习。


DUSt3R 与 COLMAP MVS 结果对比

我们的比较基于运行时间重建保真度(通过人工视觉评估和预测结果解读)。
测试数据集包括:Meta CO3DTanksAndTemples 以及我们自行采集的场景。

如前所述,输入图像会被缩放至 512×384 或 384×512(保持宽高比,最大边为 512)。为简化可视化,相机视锥体大小设为最小。

对比案例 1:

数据集:Meta CO3D_motorcycle – 
motorcycle/427_59906_115672

DUSt3R

DUSt3R 配置

:One-Reference 配对,共 204 个图像对

性能表现

在 RTX 3080 Ti 上耗时 1 分 10 秒

显存占用 11.7GB

因显存限制,采用 “one-ref” 策略。

在最后一节中,我们将展示 DUSt3R 与 COLMAP MVS 的重建结果对比——结果将不言自明,充分展现 DUSt3R 在稠密重建任务中的强大能力。

全新多视角三维重建DUSt3R的原理详解与成果展示

全新多视角三维重建DUSt3R的原理详解与成果展示

COLMAP MVS(使用 CUDA 构建)

稠密多视角立体重建(MVS)耗时超过 50 分钟;

在 MVS 阶段占用显存不到 1GB。

全新多视角三维重建DUSt3R的原理详解与成果展示

当图像数量较少(约 10–16 张)时,COLMAP 很难生成有意义的结果,因为大部分特征匹配会被过滤掉。

针对上述摩托车数据子集,我们精心挑选了 16 个视角差异较大、重叠区域最小的视图,并使用 COLMAP 进行处理。最终仅有两个视角成功进入稠密重建阶段,且由于缺乏足够的对应点,仅生成了稀疏、零散的点云“团块”。

相比之下,DUSt3R 如预期一样,成功生成了高质量的点云地图。


对比案例 2:

该数据集由我们将一台 DSLR 相机固定在桌面上,围绕场景移动拍摄所有可能视角而采集得到。

DUSt3R 表现


使用 “one-ref” 策略处理 102 张图像(共 204 个图像对),仅耗时 51 秒

全新多视角三维重建DUSt3R的原理详解与成果展示

全新多视角三维重建DUSt3R的原理详解与成果展示

COLMAP:处理 102 张图像耗时超过 50 分钟。

全新多视角三维重建DUSt3R的原理详解与成果展示

对比案例 3:

该数据集来自 Meta CO3D_teddybear 数据集的一个子集 —— 
teddybear/34_1479_4753

DUSt3R 表现

:使用 “one-ref” 策略处理 56 张图像,仅耗时 38 秒

全新多视角三维重建DUSt3R的原理详解与成果展示

全新多视角三维重建DUSt3R的原理详解与成果展示

COLMAP:使用相同的 56 张图像子集时,重建结果质量远不如下图所示。因此,我们转而处理原始数据集中全部的 202 张图像,以获得更优的稠密重建效果,整个过程耗时约 1 小时。使用全部数据集重建的结果不如上图。

全新多视角三维重建DUSt3R的原理详解与成果展示

在所有测试案例中,DUSt3R 无论在重建质量还是处理速度上均显著优于 COLMAP,使其在我们的稠密重建对比中成为当之无愧的胜者。不过,我们尚未将其与其他稠密重建方法进行对比测试。


在困难场景下测试 DUSt3R

为了充分挖掘 DUSt3R 的潜力,并评估其对复杂场景的“理解”(grok)能力,作者在一系列具有挑战性的条件下对其进行了测试。他们还讨论了一些结果出人意料地出色的场景,下面我们选取其中几个进行介绍。

案例 1:对向视角匹配(Opposite View Matching)

给定同一物体的两个完全相对的视角,DUSt3R 依然能生成结构完整、无明显形变或空洞的重建结果。这充分展现了 DUSt3R 即使在视角极其稀疏的情况下,也能对场景实现卓越的理解与建模能力。

全新多视角三维重建DUSt3R的原理详解与成果展示

案例 2:不可能匹配——无重叠区域

在此例中,我们针对建筑物场景拍摄了两张图像,其相机视角几乎完全没有重叠,类似于论文中讨论的示例。如果此时再增加一张与红色相机视角存在一定重叠的同一场景图像,DUSt3R 就能利用这一额外视角优化其点云地图预测,从而获得更完善的重建效果。

然而,即便仅使用这两张毫无重叠的图像,重建结果依然相当真实且令人印象深刻,不是吗?

全新多视角三维重建DUSt3R的原理详解与成果展示

案例三:大规模场景重建

最后,我们在TanksAndTemples数据集的教堂场景上测试DUSt3R,以验证其在大规模场景中的重建效果。预测结果完整保留了建筑结构与几何形态的精细细节,DUSt3R在保持极高保真度的同时将形变控制在最小范围。为实现此效果,我们精心筛选了前50帧具有显著差异性的图像序列进行测试。

全新多视角三维重建DUSt3R的原理详解与成果展示

DUSt3R 的局限性

尽管 DUSt3R 具有鲁棒性,但由于它是基于回归的方法,因此在精度上有所欠缺。在 DTU 的 MVS 基准测试中,不使用任何相机参数(GT)的情况下,整体距离误差(Cher 距离,单位为毫米)达到了 1.741 毫米,这与当前最先进的技术(SOTA)相比还有较大差距(数值越小越好,SOTA 为 0.295 毫米)。

对于需要比例因子的用户来说,DUSt3R 是尺度不变的,这意味着它无法保证重建结果的比例准确性。而通过 MASt3R,则可以获得度量单目深度和度量双目点云预测。

DUSt3R 主要用于稠密重建,并不适合新视角合成,因此它无法像 NeRFs 那样填补缺失的部分。

在处理具有强烈光照变化的表面时,与高斯点(Gaussian splats)相比,DUSt3R 可能会遇到挑战。

并非所有精确的重建都能带来准确的视觉定位,因为 DUSt3R 并未专门针对匹配进行训练,这影响了其定位精度。这是 MASt3R 带来的一个关键改进。

当存在过多重叠的相机姿态时,DUSt3R 的重建结构可能会崩溃,导致结果不佳。

当图像数量较多(例如超过 120 张)时,即使采用 one-ref 图像配对策略,DUSt3R 推理也需要超过 16GB 的显存。

对于希望将 DUSt3R 集成到工作流程和项目中的个人或企业而言,需要注意的是,它是在非商业许可(CC BY-NC-SA 4.0)下发布的。

关键要点

DUSt3R 开创了一种新的三维重建范式,其统一模型能够解决下游任务。虽然 DUSt3R 的重建网格看起来相当逼真,但仍然缺乏 Gaussian Splat 所能提供的照片级真实感。为了弥补这一点,社区推出了 InstantSplat,它集成了 MASt3R,能够在高速运行的同时提供令人印象深刻的结果。

回顾过去,在捕捉自定义场景时,建议围绕主体移动相机,而不是保持相机固定并旋转场景。固定的背景会导致较差的重建效果,可能是因为模型难以提取多样的特征。此外,相机姿态变化过小也会对结果产生负面影响。

结论

我们详细探讨了 DUSt3R 的模型架构及其训练策略,并将其与使用 COLMAP 进行的多视图立体密集重建进行了比较。DUSt3R 是一项了不起的研究成果,解决了 Naver Labs 现有方法所面临的实际挑战。感谢团队的努力!

如果您对高斯泼溅感兴趣,可以查看我这篇关于高斯泼溅的文章

3D高斯泼溅(3D Gaussian Splatting)介绍–论文解析及使用以及在自定义数据集上的训练

想学习3D视觉可以看这个视频

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...