拓冰建站拓冰建站
首页 / 资讯中心 / 正文

3D Gaussian Splatting实战:从原理到实践,手把手创建数字资产

在实际三维重建和数字内容创作领域传统的光栅化渲染与基于神经辐射场NeRF的方法各有优劣。前者实时性强但细节不足后者渲染质量高却计算缓慢。近年来3D Gaussian Splatting3DGS作为一种新兴的显式三维表示方法凭借其高质量的渲染效果和接近实时的渲染速度迅速成为研究与应用的热点。它特别适合从多视角图像中重建出高质量、可实时交互的三维模型。本文将以一个具体的实践项目——“数字奶龙”的诞生为例手把手带你完成一次完整的3DGS建模流程。无论你是计算机视觉的研究者、三维内容创作者还是对新技术充满好奇的开发者只要具备基础的Python编程知识和一台配备主流GPU如RTX 3050及以上的电脑就能跟随本文从环境搭建、数据准备、模型训练到最终渲染完整地走通3DGS的建模管线。你将不仅理解3DGS的核心原理更能掌握一套可复现的工程方法用于创建你自己的三维数字资产。1. 理解3D Gaussian Splatting的核心机制在开始动手之前必须先理解3DGS与传统方法如点云、网格、NeRF的根本区别。这决定了后续所有步骤的设计逻辑。1.1 从NeRF到3DGS渲染范式的转变NeRF神经辐射场是一种隐式表示方法。它将场景编码在一个庞大的多层感知机MLP中对于空间中的任意一个点(x, y, z)和观察方向(θ, φ)网络会预测该点的颜色(r, g, b)和体密度σ。渲染时需要对相机光线上的大量采样点进行查询和积分计算量巨大导致渲染速度极慢通常需要数秒甚至数分钟生成一帧。3DGS则采用了一种完全不同的、显式的表示方法。它将场景表示为数十万到数百万个带有各向异性协方差的三维高斯椭球。每个高斯椭球拥有以下属性位置 (Position): 三维空间坐标(x, y, z)。协方差矩阵 (Covariance Matrix): 定义了椭球的形状缩放和方向旋转。为了优化方便通常用缩放向量S和旋转四元数R来表示。不透明度 (Opacity):α控制该高斯对最终像素颜色的贡献程度。球谐函数系数 (Spherical Harmonics Coefficients): 用于表示视角相关的颜色。低阶系数表示基础色高阶系数表示光泽、高光等复杂反射。1.2 可微分的 Splatting 渲染流程“Splatting”抛雪球法是3DGS渲染的核心。其流程可以概括为投影 (Projection): 将三维空间中的高斯椭球投影到二维图像平面。由于高斯函数在仿射变换下仍保持高斯特性投影后得到一个二维高斯分布。排序与混合 (Sorting Blending): 对于图像平面上的每个像素将所有投影到该像素附近的二维高斯按其深度到相机的距离进行排序。Alpha 合成 (Alpha Compositing): 按照从后往前的顺序使用标准的体渲染Alpha合成公式混合这些二维高斯所贡献的颜色计算出该像素的最终颜色。C Σ (c_i * α_i * ∏ (1 - α_j)) i ji其中c_i是第i个高斯的颜色由球谐函数和视角计算得出α_i是其投影后的不透明度。整个渲染过程是完全可微分的这意味着我们可以通过计算渲染结果与真实照片之间的损失如L1损失、SSIM损失并通过反向传播来优化所有高斯椭球的属性位置、协方差、不透明度、颜色。1.3 自适应密度控制从SfM点云开始3DGS的初始化通常依赖于运动恢复结构Structure from Motion, SfM算法如COLMAP产生的稀疏点云。这些点云为高斯椭球提供了初始位置。在训练过程中模型会执行自适应密度控制克隆 (Clone): 对于位置梯度表示高斯应该移动的方向过大的高斯如果其尺度很小则在其梯度方向“克隆”一个新的高斯以覆盖尚未被很好建模的区域。分裂 (Split): 对于尺度过大的高斯将其分裂成两个更小的高斯以增加局部区域的细节表达能力。修剪 (Prune): 定期移除不透明度极低对渲染贡献极小的高斯以优化存储和计算效率。这套机制使得3DGS能够从粗糙的初始点云开始自适应地生长出足够密集和精细的高斯集合从而精准地表达复杂的几何与外观。2. 环境准备与依赖配置要成功运行3DGS一个配置正确的环境至关重要。下面将详细说明从操作系统到Python包的全过程。2.1 硬件与系统要求GPU: 这是最重要的部分。3DGS训练对显存和算力有较高要求。最低要求: NVIDIA GPU支持CUDA显存至少4GB如GTX 1650。可用于学习和小规模数据。推荐配置: NVIDIA RTX 3060 (12GB) 或更高。显存越大能处理的分辨率越高场景越复杂。高性能配置: NVIDIA RTX 4090 (24GB) RTX 3090/4090 (24GB)或专业卡如Titan系列。对于本文的“数字奶龙”项目一块RTX 3050 (6GB) 可以完成但可能需要降低图像分辨率或使用更激进的修剪策略。系统: Ubuntu 20.04/22.04 LTS 或 Windows 10/11。本文示例基于Windows 11。CUDA: 需要安装与GPU驱动匹配的CUDA工具包。推荐CUDA 11.7或11.8。可通过nvidia-smi命令查看驱动支持的CUDA最高版本。2.2 基础软件安装安装Python: 推荐使用Python 3.8 或 3.9。可以从 Python官网 下载安装包安装时务必勾选“Add Python to PATH”。安装Git: 用于克隆代码仓库。安装CUDA和cuDNN(如果系统没有):前往 NVIDIA CUDA Toolkit Archive 下载对应版本。前往 NVIDIA cuDNN Archive 下载匹配CUDA版本的cuDNN并按指南安装。安装Visual Studio Build Tools(Windows用户): 在安装某些Python包如submodules/diff-gaussian-rasterization时需要C编译环境。安装Visual Studio 2022并在工作负载中勾选“使用C的桌面开发”。2.3 创建并配置Python虚拟环境使用虚拟环境可以避免包依赖冲突。# 打开命令行CMD或PowerShell # 创建一个名为‘3dgs’的虚拟环境 python -m venv 3dgs_env # 激活虚拟环境 # Windows (CMD) 3dgs_env\Scripts\activate.bat # Windows (PowerShell) .\3dgs_env\Scripts\Activate.ps1 # Linux/macOS source 3dgs_env/bin/activate # 激活后命令行提示符前应显示 (3dgs_env)2.4 克隆官方仓库并安装核心依赖我们将使用3DGS的官方实现。# 克隆仓库 git clone https://github.com/graphdeco-inria/diff-gaussian-rasterization.git cd diff-gaussian-rasterization # 升级pip和安装工具 pip install --upgrade pip setuptools wheel安装核心依赖是一个关键且容易出错的步骤。需要严格按照顺序和指定版本。# 1. 首先安装PyTorch请根据你的CUDA版本去PyTorch官网获取对应命令 # 例如对于CUDA 11.8 pip install torch2.0.1 torchvision0.15.2 torchaudio2.0.2 --index-url https://download.pytorch.org/whl/cu118 # 2. 安装其他依赖 pip install tqdm scikit-image opencv-python configargparse lpips imageio plyfile # 3. 安装可微分的栅格化器这是核心C/CUDA扩展 # 进入子模块目录 cd submodules/diff-gaussian-rasterization # 编译并安装 pip install . cd ../..注意编译diff-gaussian-rasterization时如果报错最常见的原因是CUDA环境不对确认nvcc --version与安装的PyTorch CUDA版本一致。缺少C编译器Windows用户确保已安装Visual Studio Build Tools。路径问题确保在submodules/diff-gaussian-rasterization目录下执行pip install .。2.5 安装COLMAP用于数据预处理3DGS需要COLMAP从多视角图像中计算相机参数和稀疏点云。Windows: 从 COLMAP官网 下载Windows预编译版本解压后将colmap.bat所在目录添加到系统PATH环境变量。Linux: 可以通过包管理器安装如sudo apt install colmap。验证安装在命令行输入colmap -h应显示帮助信息。至此核心环境搭建完成。接下来进入数据准备阶段。3. 数据准备从“奶龙”图像到SfM点云3DGS的输入是一组从不同视角拍摄的同一物体的图像以及每张图像对应的相机参数内参和外参。我们将使用“奶龙”玩偶的照片作为示例。3.1 图像采集要求数量: 建议50-200张。太少会导致重建不完整太多会增加计算负担。覆盖度: 围绕物体拍摄一圈并补充顶部和底部的照片。确保相邻照片之间有足够重叠70%以上。光照: 光照条件尽量一致避免强烈的阴影变化和反光。背景: 尽量简单、静态。复杂的背景会增加SfM匹配的难度和噪声。焦距: 拍摄时最好使用固定焦距不要变焦。假设我们已经拍摄了约100张“奶龙”的照片存放在D:\digital_milk_dragon\images_raw文件夹中。3.2 使用COLMAP进行运动恢复结构SfMCOLMAP会自动从图像中提取特征点、匹配、三角化最终生成稀疏点云和相机参数。官方仓库提供了自动化脚本但理解其步骤对排查问题至关重要。手动流程如下创建项目结构D:\digital_milk_dragon\ ├── images\ # 将原始图片拷贝到这里 ├── sparse\ # COLMAP输出的稀疏模型 └── database.db # COLMAP生成的数据库文件运行COLMAP特征提取与匹配# 在项目根目录下执行 colmap feature_extractor --database_path database.db --image_path images colmap exhaustive_matcher --database_path database.db这一步会在database.db中存储特征点和匹配关系。稀疏重建mkdir sparse colmap mapper --database_path database.db --image_path images --output_path sparse成功后sparse文件夹通常是sparse/0里会生成cameras.bin,images.bin,points3D.bin文件。将模型转换为文本格式可选方便查看colmap model_converter --input_path sparse/0 --output_path sparse/0 --output_type TXT3.3 数据格式转换为3DGS准备输入3DGS的官方训练脚本需要特定格式的数据。我们需要将COLMAP的输出转换为transforms.json。官方仓库的convert.py脚本可以完成这个工作。假设我们的代码仓库在C:\3dgs\diff-gaussian-rasterization。# 进入仓库的scripts目录 cd C:\3dgs\diff-gaussian-rasterization\scripts # 运行转换脚本 python convert.py -s D:\digital_milk_dragon --resize # -s 指定源数据目录包含images和sparse子目录 # --resize 会自动将图像缩放到合理大小如1k分辨率加速处理运行成功后会在D:\digital_milk_dragon目录下生成一个transforms_train.json文件以及一个images_4或images_2文件夹存放缩放后的图像。这个json文件包含了所有图像的路径、相机内参、外参世界到相机矩阵和图像边界。至此数据预处理完成。我们得到了3DGS训练所需的标准化数据。4. 训练3D Gaussian Splatting模型有了准备好的数据我们就可以开始训练让模型从稀疏点云“生长”出代表“奶龙”的数十万个高斯椭球。4.1 理解训练脚本的关键参数进入官方仓库根目录主要训练脚本是train.py。在运行前需要理解几个关键参数python train.py -s path_to_dataset [options]-s, --source_path:必需。指向包含transforms_train.json的数据集目录。-m, --model_path: 模型输出目录。默认为./output/dataset_name。-i, --iterations: 训练迭代次数。默认为30000。对于中等复杂度的物体通常需要7000-30000次迭代。--resolution: 训练时使用的图像缩放比例。-1表示使用原始分辨率-2表示缩小到一半。在显存不足时可以设置为-2或-4。--data_device: 数据加载设备。cuda更快占显存或cpu。--densification_interval: 执行自适应密度控制克隆/分裂的间隔迭代数。默认为100。--opacity_reset_interval: 重置不透明度的间隔迭代数用于修剪无效高斯。默认为3000。--densify_from_iter/--densify_until_iter: 在哪个迭代区间内进行密度控制。例如150 500。4.2 启动训练针对我们的“奶龙”数据集一个基础的训练命令如下# 假设在仓库根目录且虚拟环境已激活 python train.py -s D:\digital_milk_dragon \ -m ./output/milk_dragon \ --iterations 15000 \ --resolution -2 \ --data_device cuda命令解释-s D:\digital_milk_dragon: 指定我们的数据路径。-m ./output/milk_dragon: 所有输出检查点、点云、日志将保存在这个目录。--iterations 15000: 训练15000步。对于约100张图片这通常足够。--resolution -2: 使用半分辨率图像训练节省显存适合RTX 3050 6GB。--data_device cuda: 将数据预加载到GPU加速训练。执行命令后终端会开始输出日志显示当前迭代次数、损失值、PSNR峰值信噪比等指标。训练过程会持续数小时取决于GPU、迭代次数和图像分辨率。4.3 监控训练过程与输出在训练过程中可以关注以下信息终端日志观察损失Loss和PSNR是否在稳步下降/上升。输出目录结构./output/milk_dragon/ ├── cfg_args # 训练配置参数 ├── cameras.json # 相机参数 ├── input.ply # 初始的SfM点云 ├── point_cloud/ # 迭代过程中的点云快照 │ ├── iteration_1000.ply │ ├── iteration_3000.ply │ └── ... ├── fusions.txt # 密度控制日志 └── timestamp/ # 以时间戳命名的最终模型目录 ├── checkpoint.pth # PyTorch模型检查点 ├── point_cloud.ply # **最终的高斯点云文件** └── ...使用可视化工具可以使用MeshLab或CloudCompare打开point_cloud/目录下的.ply文件观察高斯点云随着训练是如何从稀疏变密集并逐渐形成“奶龙”形状的。训练完成后最重要的输出文件是timestamp/point_cloud.ply。这个PLY文件不仅包含点的位置还编码了每个高斯椭球的协方差缩放和旋转、不透明度和球谐系数。它就是我们的“数字奶龙”模型。5. 渲染与可视化让“奶龙”动起来训练得到的.ply文件是一个静态的3D表示。我们需要使用配套的渲染器才能从任意视角查看它。5.1 使用官方查看器进行交互式浏览官方仓库提供了一个基于SIBR的实时查看器。这是最简单的可视化方式。编译查看器(如果尚未编译):cd C:\3dgs\diff-gaussian-rasterization\SIBR_viewers cmake -B build -DCMAKE_BUILD_TYPERelease . cd build cmake --build . --target install --config Release这会在SIBR_viewers\install\bin下生成可执行文件。运行查看器:# 在Windows上 cd install\bin .\viewers.exe -m D:\digital_milk_dragon\output\milk_dragon\timestamp # -m 参数指向包含point_cloud.ply的模型目录运行后会打开一个图形窗口。你可以用鼠标拖拽旋转视角用滚轮缩放用WASD键移动。这验证了模型可以在实时帧率下被渲染。5.2 渲染特定视角的图像序列视频我们可能想渲染一个环绕“奶龙”的视频。这需要准备一个相机轨迹并使用render.py脚本。生成相机轨迹: 我们可以使用interpolate.py脚本基于训练数据中的相机位姿插值生成平滑的路径。python interpolate.py -m ./output/milk_dragon/timestamp --skip_train这会在模型目录下生成一个camera_path.json文件。渲染视频:python render.py -m ./output/milk_dragon/timestamp \ --skip_train \ --name milk_dragon_orbit \ --render_path--skip_train: 不渲染训练视角。--name: 输出子目录的名称。--render_path: 按照camera_path.json的路径渲染。 渲染出的图像序列会保存在./output/milk_dragon/timestamp/milk_dragon_orbit/中。合成视频: 使用FFmpeg将图像序列合成为视频。ffmpeg -framerate 30 -i ./output/milk_dragon/timestamp/milk_dragon_orbit/%04d.png \ -c:v libx264 -pix_fmt yuv420p \ ./output/milk_dragon/milk_dragon_orbit.mp45.3 导出为其他格式如网格虽然3DGS的核心是点云但有时我们需要网格模型用于其他3D软件。可以使用convert.py脚本的--convert_mesh选项进行泊松表面重建。python convert.py -s ./output/milk_dragon/timestamp --convert_mesh这会在模型目录下生成一个.ply网格文件。请注意从离散的高斯点云转换到连续的网格会损失一些细节并且可能产生孔洞或多余的面片通常需要后续在Blender或MeshLab中进行清理和修复。6. 常见问题排查与性能调优在实际操作中你可能会遇到各种问题。下面列出一些典型问题及其解决方案。6.1 训练阶段问题问题现象可能原因检查与解决方案CUDA out of memory1. 图像分辨率太高。2. 初始点云太密集。3. 高斯数量增长过快。1. 使用--resolution -2或-4降低训练分辨率。2. 在COLMAP阶段尝试生成更稀疏的点云。3. 调整--densification_interval(增大) 和--densify_until_iter(提前结束)。训练Loss不下降PSNR很低1. 相机参数错误。2. 图像与相机参数不匹配。3. 数据质量差模糊、遮挡、光照变化大。1. 检查transforms_train.json文件是否正确生成。用查看器加载看初始点云是否大致对齐。2. 重新运行COLMAP确保特征匹配成功率高。3. 重新采集数据确保光照稳定、覆盖全面。重建模型有大量漂浮物或空洞1. 背景复杂SfM点云包含背景噪声。2. 自适应密度控制过于激进。3. 训练迭代不足。1. 拍摄时使用纯色背景布或在训练前用背景分割工具如RemBG预处理图像。2. 调整--densify_grad_threshold(提高) 和--densification_interval(增大)。3. 增加--iterations。模型颜色暗淡或失真1. 球谐函数阶数设置问题。2. 训练数据存在色差或白平衡不一致。1. 默认使用3阶球谐函数通常足够。除非场景光照极其复杂否则不建议修改。2. 在拍摄时锁定相机白平衡或使用图像处理软件进行色彩校正。6.2 渲染与可视化问题问题现象可能原因检查与解决方案查看器黑屏或崩溃1. 模型路径错误。2. 点云文件 (point_cloud.ply) 损坏或格式不对。3. GPU驱动或图形API问题。1. 确认-m参数指向包含point_cloud.ply的目录。2. 尝试用MeshLab打开该PLY文件看是否能正常加载。3. 更新GPU驱动或尝试在软件渲染模式下运行。渲染视频时图像全黑/全白1. 相机路径 (camera_path.json) 不存在或为空。2. 渲染脚本的参数错误。1. 确认已成功运行interpolate.py生成路径文件。2. 检查render.py命令确保-m路径正确并使用了--render_path参数。渲染速度很慢1. 高斯数量过多超过300万。2. 渲染分辨率太高。1. 在训练时通过调整密度控制参数控制最终高斯数量。对于RTX 3050建议控制在50-100万以内。2. 在render.py中使用--resolution参数降低输出分辨率。6.3 性能调优建议针对小显存GPU (如RTX 3050 6GB):数据端: 使用--resolution -4进行训练使用--data_device cpu。模型端: 设置--densify_until_iter 1000让密度控制尽早停止防止高斯数量爆炸。将--densification_interval设为200或更大。渲染端: 在查看器中降低视口分辨率。渲染视频时使用720p而非1080p。针对追求质量的场景:使用原始分辨率或--resolution -1训练。增加--iterations到30000以上。确保输入图像是高质量的数量充足150张。考虑使用更高阶的球谐函数修改源代码但会显著增加存储和计算量。7. 生产环境最佳实践与扩展方向将3DGS从实验项目推向实际应用需要考虑更多工程化因素。7.1 模型优化与压缩原始的.ply文件可能很大数百万高斯点可达数百MB。可以考虑修剪: 在训练后手动设置一个更高的不透明度阈值移除对渲染贡献极小的高斯。量化: 对球谐系数、位置、旋转等属性进行量化如从float32到uint16可以大幅减少模型体积对视觉质量影响很小。专用格式: 研究社区已有一些压缩和加速方案如使用更紧凑的数据结构存储高斯参数。7.2 集成到应用管线要将“数字奶龙”集成到游戏、AR/VR或Web应用中需要选择渲染器: 官方查看器基于OpenGL。可以将其核心渲染代码移植到其他图形API如Vulkan, WebGL或引擎Unity, Unreal Engine中。社区已有一些Unity和Web的实验性移植。数据流: 设计高效的模型加载和流式传输方案特别是对于大型场景。交互: 实现光照、阴影、与其他物体的碰撞等交互功能这仍然是当前3DGS研究的难点。7.3 与其他工具链结合Blender: 可以将3DGS渲染的图像序列作为纹理映射到一个粗略的网格上在Blender中进行后期动画制作。NeRF/网格对比: 对于需要精确几何的任务如3D打印3DGS转换的网格可能不如传统多视图立体MVS或NeRF表面重建方法精确。需要根据下游任务选择输出格式。动态场景: 原始的3DGS不支持动态场景。可以关注其扩展工作如4D Gaussian Splatting用于处理动态物体或场景。从拍摄一组“奶龙”照片到生成一个可以实时旋转、浏览的3D数字模型3D Gaussian Splatting提供了一条相对高效且高质量的路径。整个过程的核心在于理解其显式表示和可微分渲染的原理并耐心完成数据准备、环境配置和参数调试。对于RTX 3050这类入门级GPU通过合理的降分辨率训练和参数控制完全能够跑通流程并得到可观的结果。下一步你可以尝试拍摄更复杂的物体、室内小场景甚至探索如何将生成的模型用于简单的AR展示这将是巩固学习成果并激发新想法的最佳方式。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门