InfiniSplat详解:隐式高斯解码实现大基线单目视图合成
2026/8/28 14:04:02 网站建设 项目流程

之前在调研多视角三维重建方案时,我一直被一个场景问题困扰:当相机之间的基线拉得比较大时,NeRF 和传统 3D Gaussian Splatting(3DGS)的重建质量会明显下滑,甚至出现几何塌陷和视角伪影。后来读到 InfiniSplat 这篇工作,发现它把“隐式高斯解码(Implicit Gaussian Decoding)”的思路引入大基线单目视图合成,一下子把问题从“逐场景过拟合优化”拉到了“跨视角泛化回归”的框架里。

这篇文章会围绕 InfiniSplat 展开,从它解决什么问题、方法如何设计、工程落地时需要哪些环境与依赖,到核心代码思路、训练评估流程、常见踩坑点和最佳实践,做一个相对完整的拆解。适合对 3DGS 有一定了解、想做稀疏视角或大基线重建的同学阅读;如果你是新手,建议先补一下 3DGS 的基础渲染流程,再回来看本文会顺畅很多。

读完本文,你会理解 InfiniSplat 的核心设计逻辑,而不是只停留在论文标题层面。项目实践中,你也能知道怎么准备数据、怎么设计实验验证效果,以及遇到大基线场景重建失败时从哪些维度排查。

1. 背景与核心概念

1.1 从 3D Gaussian Splatting 说起

3D Gaussian Splatting 是近几年神经渲染领域非常热门的表示方法。它的核心思路是:用一堆带属性的三维高斯函数来表示场景,每个高斯点包含中心位置、协方差矩阵(决定椭球形状)、颜色、不透明度等参数,然后通过可微的光栅化过程把三维高斯投影到二维图像平面上,用 alpha blending 得到最终渲染图。

相比 NeRF 的隐式体渲染,3DGS 的优势很明显:

  • 渲染速度快,能够达到实时级别;
  • 显式点云表示,方便编辑和控制;
  • 训练速度相比 NeRF 也有明显提升。

但 3DGS 的传统用法是“逐场景优化”。也就是说,给定一个场景的多张图片和对应相机位姿,从随机初始化的高斯点开始,通过不断渲染、计算损失、反向更新参数,最终得到一个属于这个场景的 3DGS 模型。

这种方式在视角密集、基线较小的场景下效果很好,但有几个隐患:

  • 如果输入视角跨度大,场景重叠区域小,优化过程容易陷入局部最优;
  • 对每个新场景都要重新训练,无法复用;
  • 几何信息不足时,高斯点会“漂移”到错误位置,产生大量飞散点。

1.2 大基线单目视图合成难在哪里

“大基线(Large-Baseline)”指的是相机拍摄位置之间的距离比较大。相邻两帧视角之间的重叠区域小,视图变化剧烈。

大基线单目视图合成的挑战主要来自几何不确定性:

  • 视角差异越大,同一 3D 点在两张图上的投影位置差异越大,特征匹配越困难;
  • 遮挡区域明显增加,很多像素只在部分视角可见;
  • 单目输入本身缺少深度真值,几何推理只能依赖多视图一致性;
  • 如果只用简单回归网络去预测高斯参数,很难保证预测结果在不同视角下一致。

所以,大基线场景需要更强的几何感知能力,而不只是“图像到图像的翻译”。

1.3 InfiniSplat 的核心思路

InfiniSplat 全称是InfiniSplat: Implicit Gaussian Decoding for Large-Baseline Monocular View Synthesis

它要解决的问题很直接:给定一组大基线、稀疏视角的单目图像,如何通过前向网络直接生成 3D 高斯参数,从而合成新视角。

这里的核心是“隐式高斯解码”。传统做法可能是让网络直接输出每个高斯的显式参数,例如直接回归一个 N×C 的参数矩阵;而 InfiniSplat 选择先提取多视图特征,再通过一个隐式解码器(通常是 MLP 或基于特征查询的网络)在三维空间中解码出高斯参数。这样做的优势是:

  • 参数预测更加连续;
  • 对特征表达有更强的容错性;
  • 更容易引入多视角几何约束;
  • 不需要逐场景优化,具备泛化能力。

结合大基线场景,InfiniSplat 还会重点考虑多视角特征如何聚合,以及如何在不连续视角之间形成稳定的三维特征场。

下面我们从方法层面拆解这些设计。

2. 方法原理拆解

2.1 整体 Pipeline

从工程实现的角度看,InfiniSplat 的完整流程大致可以分为五个模块:

  1. 多视图图像特征提取;
  2. 跨视图特征聚合与几何先验构建;
  3. 三维空间中的高斯参数解码;
  4. 可微高斯光栅化渲染;
  5. 损失函数约束与梯度回传。

用一句话概括:输入 N 张图像,输出一组能够渲染出新视角图像的 3D 高斯参数,全程不需要对单个场景做额外优化。

下面逐个模块说明。

2.2 多视图特征提取

特征提取器通常采用卷积神经网络(CNN),例如 ResNet 或 UNet 风格的编码器。每一张输入图像都会被编码成多尺度特征图。

对于大基线场景,单张图像的特征不足以解决遮挡和视角歧义,所以必须把多张图像的特征融合起来。常用的做法包括:

  • 在特征图上计算相关性(correlation);
  • 构建代价体(cost volume);
  • 使用 Transformer 的跨视图注意力机制。

InfiniSplat 强调“隐式解码”,意味着三维空间中的任意查询点都可以通过解码器获得对应的属性。为了让解码器感知全局上下文,跨视图聚合后的特征会作为解码器的条件输入。

2.3 隐式高斯解码器

隐式高斯解码是整篇论文最核心的设计。

它的输入通常包含:

  • 三维查询点的坐标(x, y, z);
  • 多视图聚合得到的特征向量;
  • 可选的视角方向信息。

输出则是该点对应的高斯属性,常见属性包括:

  • 中心位置偏移;
  • 协方差矩阵(或对应的缩放与旋转四元数);
  • 颜色;
  • 不透明度。

之所以叫“隐式”,是因为它不直接维护一个显式的高斯列表,而是通过神经网络在查询时解码出参数。这样做的好处是可以通过 MLP 对连续三维空间建模,网络学习到的是一个“场景函数”,而不是离散的点集。

从工程角度理解,你可以把这一步类比成:用一个 MLP 替代了传统 3DGS 训练中的“可学习参数表”。

2.4 可微渲染与损失约束

得到高斯参数后,渲染过程和 3DGS 保持一致:

按深度排序,对每个像素做 alpha blending 合成颜色,得到预测图像。

损失函数方面,常见的组合是:

  • L1 颜色损失;
  • SSIM 结构相似性损失;
  • 必要时加入深度一致性或特征一致性约束,帮助大基线场景稳住几何。

由于整个链路是可微的,梯度可以一路回传到特征提取和解码器,完成端到端训练。

2.5 InfiniSplat 与普通 3DGS 的差别

对比项普通 3DGSInfiniSplat 思路
生成方式逐场景随机初始化,梯度优化参数前向网络预测高斯参数
是否泛化每个场景单独训练训练后可直接推理新场景
对视角密度的要求密集视角效果更稳定面向大基线、稀疏视角设计
几何建模依赖优化的隐式几何约束通过隐式解码器建模三维分布
输入多视图图像 + 相机位姿多视图图像 + 相机位姿,输出高斯参数

这种从“优化”到“回归”的转变,是近两年 generalizable 3DGS 方向的共性趋势。InfiniSplat 的特色在于,把隐式解码结构和大基线场景难题结合起来,从设计上提升了跨视角泛化能力。

3. 环境准备与工程依赖

3.1 运行环境建议

因为 InfiniSplat 属于 3DGS 技术路线,工程实现通常依赖 PyTorch、CUDA 以及高斯光栅化相关的自定义算子。这里给出一套通用环境建议:

  • 操作系统:Ubuntu 20.04 或 22.04(Windows 也能跑,但编译自定义算子会更费劲)
  • GPU:建议 NVIDIA 显卡,显存 12GB 以上,训练时越大越好
  • Python:3.8 或 3.10
  • CUDA Toolkit:11.x 或 12.x,取决于 PyTorch 版本
  • PyTorch:2.0 以上
  • 其他依赖:numpy、opencv-python、tqdm、tensorboard 等

版本需要根据你的项目实际情况调整。如果你使用的不是论文官方代码,而是第三方复现实现,务必先看仓库的 requirements。

3.2 高斯光栅化算子

3DGS 的核心渲染依赖自定义 CUDA 算子,常见的是diff-gaussian-rasterization子模块。安装时一般需要编译:

git clone --recursive <项目地址> cd <项目目录> pip install -r requirements.txt pip install ./submodules/diff-gaussian-rasterization

实际使用时,仓库结构不同,路径也会变化。这里只演示思路,具体以你克隆的项目 README 为准。

3.3 相机位姿准备

无论是训练还是推理,都需要相机内参和外参。常见方案:

  • 使用 COLMAP 做运动恢复结构(SfM),得到相机参数和稀疏点云;
  • 使用已知的仿真数据集(如 Blender、Unity 渲染生成)直接导出位姿文件;
  • 使用 AR 设备或 SLAM 系统输出位姿。

大基线场景下,位姿精度非常关键。如果相机位姿误差大,后续特征聚合和高斯解码都会受影响。

3.4 示例项目结构

一个典型的项目结构如下:

InfiniSplat-Project/ ├── configs/ │ └── train.yaml ├── data/ │ ├── train/ │ │ ├── images/ │ │ ├── poses/ │ │ └── intrinsics/ │ └── test/ ├── models/ │ ├── encoder.py │ ├── cost_volume.py │ ├── decoder.py │ └── renderer.py ├── scripts/ │ ├── train.py │ └── eval.py ├── requirements.txt └── README.md

这个结构只是参考,实际以官方代码为准。重点是分层清晰:数据、模型、训练、评估分开管理。

4. 核心代码思路(伪代码级讲解)

需要说明的是,目前公开的论文复现版本可能各不相同,这里给出的是“思路级伪代码”,用于帮助你理解模块之间的流转,不能直接复制运行。真正复现时,你需要根据论文内容和具体框架补齐细节。

4.1 特征提取模块

特征提取的目的是从多视图图像中得到统一的特征表达。

import torch import torch.nn as nn class FeatureEncoder(nn.Module): def __init__(self, in_channels=3, out_channels=64): super().__init__() # 实际实现中常用 UNet 风格结构,这里用简单卷积示意 self.conv_block = nn.Sequential( nn.Conv2d(in_channels, 32, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(32, out_channels, kernel_size=3, padding=1), nn.ReLU(inplace=True), ) def forward(self, images): """ images: [B, V, C, H, W] return: [B, V, D, H, W] """ B, V, C, H, W = images.shape images = images.reshape(B * V, C, H, W) features = self.conv_block(images) _, D, Hf, Wf = features.shape features = features.reshape(B, V, D, Hf, Wf) return features

这里把多视角图像统一编码,后续就可以在这个特征基础上做跨视图聚合。

4.2 跨视图特征聚合

大基线场景下,单视图特征不够,需要把多视图信息融合到参考视图中。

class CostVolumeAggregation(nn.Module): def __init__(self, feature_dim=64): super().__init__() self.depth_samples = 128 # 深度采样数量 # 后续 3D 卷积正则化代价体 self.cost_regularizer = nn.Sequential( nn.Conv3d(feature_dim, 32, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.Conv3d(32, 1, kernel_size=3, padding=1), ) def forward(self, ref_feature, src_features, ref_pose, src_poses, intrinsics): """ 根据深度假设,将源视图特征 warp 到参考视图,构建代价体。 只是思路示意,实际需要处理相机投影矩阵。 """ B = ref_feature.shape[0] D = self.depth_samples cost_volume = torch.zeros(B, D, ...) # 需要根据实际特征尺寸填写 for d in range(D): depth = ... # 当前深度假设 warped_features = self.warp_features(src_features, src_poses, intrinsics, depth) cost_volume[:, d] = self.compute_correlation(ref_feature, warped_features) cost_volume = self.cost_regularizer(cost_volume) return cost_volume

这种“基于深度假设的可微 warp + 代价体”的思路,在 MVS 类方法中很常见。InfiniSplat 的隐式解码框架也依赖类似的几何先验,让三维查询点能够感知多视图一致性。

4.3 隐式高斯解码器

这部分是核心中的核心。输入一个三维查询点,输出高斯属性。

class ImplicitGaussianDecoder(nn.Module): def __init__(self, feature_dim=64, hidden_dim=128): super().__init__() self.mlp = nn.Sequential( nn.Linear(3 + feature_dim, hidden_dim), nn.ReLU(inplace=True), nn.Linear(hidden_dim, hidden_dim), nn.ReLU(inplace=True), nn.Linear(hidden_dim, 9), # 3位置偏移 + 4旋转 + 2缩放 ) self.color_head = nn.Sequential( nn.Linear(hidden_dim, hidden_dim), nn.ReLU(inplace=True), nn.Linear(hidden_dim, 3), nn.Sigmoid(), ) self.opacity_head = nn.Sequential( nn.Linear(hidden_dim, hidden_dim), nn.ReLU(inplace=True), nn.Linear(hidden_dim, 1), nn.Sigmoid(), ) def forward(self, points, features): """ points: [N, 3] 三维查询点 features: [N, feature_dim] 从多视图特征中查询到的聚合特征 return: gaussian_params, color, opacity """ x = torch.cat([points, features], dim=-1) base = self.mlp(x) offset = base[..., :3] quaternion = base[..., 3:7] scale = torch.exp(base[..., 7:9]) color = self.color_head(base.detach()) # 实际实现中不建议 detach,这里仅为示意 opacity = self.opacity_head(base) return offset, quaternion, scale, color, opacity

这段代码主要帮助理解“隐式解码”是什么意思:网络不是直接存一组高斯参数,而是根据三维坐标和聚合特征动态预测参数。

4.4 训练流程主循环

训练主循环可以按下面这个思路组织:

# 伪代码,仅展示训练流程 for batch in dataloader: # batch 包含:多视角图像、相机位姿、目标视角图像 images = batch["images"] # [B, V, C, H, W] poses = batch["poses"] # [B, V, 4, 4] intrinsics = batch["intrinsics"] # [B, V, 3, 3] target_image = batch["target_image"] # [B, C, H, W] features = encoder(images) # 多视图特征 cost_volume = aggregation(features, poses, intrinsics) # 几何先验 points = sample_3d_points() # 生成三维查询点 gaussians = decoder(points, cost_volume_features) # 解码高斯参数 rendered_image = rasterizer(gaussians, target_pose, intrinsics) # 渲染 loss = l1_loss(rendered_image, target_image) + ssim_loss(rendered_image, target_image) optimizer.zero_grad() loss.backward() optimizer.step()

实际复现时,还需要处理高斯点的数量控制、协方差矩阵的约束、可见性裁剪等工程细节。

5. 训练与评估流程

5.1 数据组织方式

建议把数据按以下方式组织:

data/ ├── train/ │ ├── scene_001/ │ │ ├── images/ │ │ │ ├── 000000.png │ │ │ └── 000001.png │ │ ├── poses/ │ │ │ └── poses.txt │ │ └── intrinsics/ │ │ └── intrinsics.txt

每张图像对应一个相机位姿,训练时随机采样一个参考视角和若干源视角,目标视角可以是其中一个源视角,也可以是独立的新视角。

5.2 训练命令示例

假设你正在使用某个包含train.py的项目,训练命令通常长这样:

python train.py \ --config configs/train.yaml \ --data_path data/train \ --log_dir logs/experiment_001 \ --batch_size 1 \ --num_workers 4 \ --max_epochs 100

强烈建议训练前先跑通一个 sample 数据,确认数据读取、前向传播、反向传播都没有问题,再启动完整训练。

5.3 评估指标

视图合成任务通常用以下指标评估:

  • PSNR:峰值信噪比,越高越好;
  • SSIM:结构相似性,越高越好;
  • LPIPS:感知相似度,越低越好。

大基线场景下,除了平均指标,还要关注边缘视角的表现。很多方法在中间视角指标好看,一到边缘视角就崩,所以评估时要分视角区间统计。

5.4 与基线方法对比

实验阶段,建议至少和以下方法做对比:

  • NeRF 系列:可以体现连续优化类方法的不足;
  • 普通 3DGS:可以体现逐场景优化的局限;
  • 其他 generalizable 3DGS 方法:比如基于 cost volume 或 transformer 聚合的同类工作。

对比时重点观察:

  • 新视角合成质量;
  • 几何一致性;
  • 推理速度;
  • 是否需要测试时优化(test-time optimization)。

从工程角度看,如果某个方法推理前还要在新场景上微调,那它就不是真正的“泛化方法”,在实际应用中会有很多限制。

6. 常见问题与排查思路

6.1 常见问题速查表

问题现象常见原因解决思路
自定义光栅化算子编译失败CUDA 版本与 PyTorch 不匹配检查nvcc --versiontorch.version.cuda,统一 CUDA 环境
显存不足三维查询点过多或特征图分辨率过高降低批量大小,减少深度采样数,使用混合精度训练
渲染结果出现大量彩色飞点高斯协方差未约束或几何不稳定检查协方差初始化,必要时加入正则化项
大基线训练不收敛位姿误差大、特征聚合弱优先校正位姿;增加跨视图特征聚合模块的表达能力
训练集指标很好,测试集很差过拟合场景偏向增加训练场景数量,调整数据增强策略
新场景推理效果差训练分布与新场景差异大检查数据分布、图像分辨率、光照差异

6.2 渲染出现空洞

空洞通常意味着三维空间中缺少高斯点覆盖。可能原因:

  • 查询点采样密度不够;
  • 几何先验把概率质量分配到了错误位置;
  • 遮挡区域的可见性判断不准确。

排查思路:

  1. 可视化三维点位置,确认分布是否合理;
  2. 检查遮挡区域是否被采样;
  3. 增大采样密度,观察空洞是否改善。

6.3 训练 loss 下降但渲染不清晰

这种情况下,通常是几何信息没有有效进入解码器。模型可能只是通过颜色信息“硬背”了训练视角。需要:

  • 增加多视图一致性约束;
  • 增大特征聚合的视野;
  • 加入几何正则项,如深度平滑或左右视角重投影误差。

6.4 大基线视角伪影严重

大基线场景下,视角变化剧烈,容易出现拖影、重影、几何错位。建议按顺序排查:

  1. 相机位姿是否准确;
  2. 输入图像是否畸变校正;
  3. 特征聚合是否覆盖到了所有源视角;
  4. 解码器是否对三维坐标敏感;
  5. 是否存在遮挡导致的信息冲突。

实际项目中,位姿问题是最常见的“隐形杀手”。

7. 最佳实践与工程建议

7.1 先跑通最小示例,再上完整方案

不管官方代码还是复现代码,第一件事一定是跑通一个最小示例,比如一个场景、几个视角、几步迭代。不要一开始就追求完整训练。最小示例能最快暴露环境问题、数据格式问题、代码路径问题。

7.2 相机位姿宁可保守,不要将就

大基线方法对位姿非常敏感。如果你的输入是手机拍摄或机器人采集的视频帧,建议先用 COLMAP 做完整的 SfM 流程,检查重投影误差。位姿误差过大的数据,直接过滤掉,不要指望网络“自己学出来”。

7.3 监控三维高斯分布

训练时只盯着 tensorboard 的 PSNR 不够,强烈建议定期输出高斯点云的可视化结果。你可以在训练循环中把高斯中心位置保存成 PLY 文件,用 CloudCompare 或 MeshLab 查看。

如果高斯点云出现大量飞散点、长条状异常椭球,说明几何约束已经失效,需要回调超参数或增加正则项。

7.4 显存优化

大基线场景往往需要处理多张高分辨率图像,显存压力非常大。工程上常用的手段:

  • 使用混合精度训练(AMP);
  • 降低输入图像分辨率;
  • 减少源视角数量,例如从 5 个视角降到 3 个;
  • 分块渲染测试图像,再拼接结果;
  • 使用梯度检查点(gradient checkpointing)减少中间激活显存。

7.5 数据多样性比模型复杂度更重要

如果你的目标是训练一个泛化的大基线视图合成模型,数据多样性远比堆参数重要。多收集不同场景类型、不同光照条件、不同相机轨迹的数据,比单纯调大模型更有效。

从实验安排上,建议:

  • 训练集和测试集场景完全隔离;
  • 测试时直接推理,不允许 test-time optimization;
  • 每个场景固定随机种子,保证可复现。

7.6 代码与实验管理

建议用配置文件管理所有超参数,不要每次改参数都改代码。一个简单的 YAML 配置文件如下:

model: encoder_out_channels: 64 decoder_hidden_dim: 128 depth_samples: 128 data: image_size: [512, 512] num_source_views: 4 training: batch_size: 1 learning_rate: 0.0001 max_epochs: 100 mixed_precision: true logging: log_dir: "logs/exp_001" save_every: 5

这样每次实验只要复制一份配置文件,改两个参数,就能对比不同设置的效果。

7.7 安全与合规提示

如果要在真实场景数据上训练,务必确认数据来源合规,尤其是涉及人脸、车牌、私密空间、商业场所的数据。个人项目尽量使用公开数据集或自己渲染的合成数据,避免隐私和法律风险。涉及他人数据时,遵循最小必要原则,并在发布内容前做脱敏处理。

8. 总结与学习路线

这篇内容从大基线视图合成的问题出发,梳理了 InfiniSplat 的核心设计思路:多视图特征提取、跨视图特征聚合、隐式高斯解码、可微渲染与端到端训练。希望读者能理解,这类方法的价值在于“从逐场景优化转向前向泛化推理”,而隐式解码器的设计则是让网络具备连续三维建模能力的关键。

如果你打算深入研究这个方向,建议按下面路线推进:

  1. 先彻底搞懂 3D Gaussian Splatting 的基础渲染流程,包括高斯参数的含义、投影公式、alpha blending 原理;
  2. 再研究多视图几何中的代价体构建和可微 warp,这是提升大基线几何感知的基础;
  3. 然后阅读近两年 generalizable 3DGS 方向的类似工作,例如基于 cross-attention 或 cost volume 的稀疏视图重建方法,对比它们在不同输入数量、不同基线长度下的表现;
  4. 最后回到 InfiniSplat 论文原文,逐段对照本文提到的模块,补充公式级细节。

实际做项目时,优先级排序建议是:数据质量大于模型设计,位姿精度大于网络深度,稳定复现大于指标刷点。先跑通一条完整链路,再逐步增加模块和调优,过程中一定要重视可视化——不管是渲染图还是三维高斯点,可视化能帮你快速定位问题,远比盯着 loss 曲线猜问题高效。

如果这篇文章对你有帮助,可以收藏备用。后续我会继续写 3DGS 相关的工程落地笔记,欢迎交流你在复现过程中遇到的问题。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询