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

3DGS三维重建全流程实战:从数据采集到训练调参

1. 为什么大家都在说3DGS它究竟解决了什么先回答一个很多人刚接触时都会问的基础问题3D Gaussian Splatting下面我直接叫它3DGS到底是什么它能干什么简单说3DGS是一种把真实场景变成“可实时渲染的数字三维模型”的技术。你拿手机或相机绕着某个物体、某个房间、某段街道拍一组照片喂给3DGS的训练程序它就能重建出一个和真实场景几乎一致的三维空间。这个空间可以用鼠标自由旋转、缩放也能输出成视频或网格模型放到Unity、Unreal里继续做开发。它在2023年刚出来的时候最震撼人的一点是重建质量接近甚至超过当时主流的NeRF方案但训练速度快了几十倍渲染速度更是拉到实时普通消费级显卡就能跑30帧以上。我自己的实际感受是NeRF时代你训练一个场景动辄几个小时推理一张图也得几百毫秒基本只能离线出图3DGS把同样的活压缩到十几分钟到半小时推理直接实时。这个量级的差距意味着它从“实验室玩具”变成了“能落地的工具”所以才会在视觉特效、游戏资产制作、建筑扫描、电商展示这些方向迅速火起来。这篇文章我打算从头到尾带你跑通一次完整的3DGS使用流程工具怎么选、环境怎么搭、数据怎么拍、训练怎么调参、结果怎么导出。无论你是第一次接触还是有过NeRF基础想迁移到3DGS按这个顺序走下来基本不会卡壳。2. 跑通之前先想清楚工具链选型与运行环境3DGS不是一个单独的软件它是一整套算法的统称。市面上有好几套开源实现最主流的是原版项目graphdeco-inria/gaussian-splatting另外还有nerfstudio里的splatfacto、taichi生态里的gsplat等。我给新手的第一建议永远是先跑原版不要贪多。2.1 原版仓库为什么是必修课原版仓库是论文作者公开的实现参数命名、训练流程、导出脚本都是“标准答案”。它的主要构成是这样的用PyTorch做神经网络层面的计算自带一个自定义的CUDA光栅化器负责把三维高斯投影成屏幕上的颜色依赖COLMAP做初始化也就是先从照片里估算相机位置和稀疏点云训练完成后可以渲染视频、导出点云或者配合第三方脚本转网格。选择原版的逻辑很简单社区里的教程、提问、衍生工具几乎都围绕它展开你在使用中遇到八成的报错都能搜到解决方案。而nerfstudio的封装做得更友好适合后续做数据管理、模型对比但它把很多细节藏起来了一旦出了问题你很难定位根因。所以我的建议是“原版打基础nerfstudio做生产”。2.2 硬件和软件环境的硬性条件说下我自己的部署环境你对照参考操作系统Windows 11原版仓库对Windows、Linux都支持但Windows需要手动配置更多环境变量后面会细说显卡NVIDIA RTX 3060 12GB显存起步。显存直接决定你最多能训练多复杂的场景12GB玩小物体和室内房间够用室外大场景建议上24GBCPU训练过程中CPU用于数据加载和预处理至少6核影响没那么大内存16GB是底线32GB更稳。COLMAP特征提取阶段偶尔会吃掉不少内存软件方面最核心的是CUDA和PyTorch的版本匹配。原版仓库要求CUDA计算能力在6.0以上实测下来CUDA 11.8配合PyTorch 2.0.0是最稳的组合。如果你装的是CUDA 12.x也能跑但需要手动调整编译参数新手没必要第一关就给自己加难度。有一个非常容易忽略的点安装完仓库后别忘了初始化子模块submodule否则diff-gaussian-rasterization和simple-knn这两个核心组件目录是空的一编译就报错。网上很多人卡在“ModuleNotFoundError: No module named diff_gaussian_rasterization”八成就是子模块没拉下来。# 拉取仓库并初始化子模块 git clone https://github.com/graphdeco-inria/gaussian-splatting.git cd gaussian-splatting git submodule update --init --recursive2.3 COLMAP的安装路径与坑COLMAP是3DGS训练前的必经步骤它的作用是从你的照片中恢复出每张照片的相机位姿同时生成一簇稀疏三维点。这个稀疏点云就是三维高斯的“种子”训练程序会从这些点出发不断生长和修剪。COLMAP的安装方式按系统分Windows直接下载官方预编译的Windows版本解压后把bin目录加到系统PATHLinux用apt或者从源码编译都行源码编译耗时较长建议直接用发行版自带的版本但注意版本别太老至少3.7以上真实使用中COLMAP能不能正确识别你的照片取决于一个细节照片的EXIF信息里有没有焦距数据。手机和相机拍摄的照片通常都有但如果你用的是网图、截图或某些软件导出的图片这一步大概率会失败。解决办法是先用转换工具把图片标准化同时用脚本统一重命名避免中文路径和乱码。还有一点COLMAP对非常多的照片超过500张做特征匹配时内存占用会飙得很高。如果不想换大内存可以在特征提取和匹配阶段适当降低精度或者把输入图片缩小。3. 比训练更影响出片率的第一步数据采集规范很多人第一次跑3DGS训练出来的结果模糊、有漂浮物、视角一转就崩第一反应是调参数实际上八成问题出在数据采集。我强调一句可能不太好听但很真实的话3DGS这技术是“数据决定上限算法决定下限”。同样的训练代码你喂给它高质量覆盖均匀的照片和随便扫一圈的照片最终效果天差地别。3.1 拍摄目标的基本要求如果你想重建单个物体比如一个雕塑、一双鞋、一件产品拍摄时注意以下几点背景尽量干净、简洁纯色背景最好。3DGS会把背景也重建出来背景纹理太复杂会分散训练资源导致主体细节不足物体放在漫反射材质表面不要用镜面反射的桌子。反光会干扰特征点匹配和颜色学习这是很多人踩过坑的地方相机绕着物体转一圈保持同样的高度和同样的距离每隔一个固定角度拍一张相邻两张照片的重叠区域最好在60%以上光线要稳定均匀。不要开闪光灯不要在窗户边拍阳光会随时间变化最好是固定光源下的室内环境如果你要重建的是整个房间或室外小场景规则类似但要多注意一个点不要只绕着外围拍一圈还要从不同高度、不同前进方向拍摄多组轨迹。简单说你需要覆盖目标空间的各个面而不是只拍一个环。3.2 视频抽帧还是连拍我推荐后者3DGS社区常见的做法是“录一段视频然后抽帧”。但根据我的实际对比除非运动控制得特别好否则视频抽帧是下策。原因很简单视频帧率通常是30fps你拿着手机走动拍摄相邻帧之间的位移可能只有几厘米特征匹配时会产生大量的高度相似图像不仅浪费训练时间还可能让优化陷入局部最优。而且手持拍摄必然有抖动轻微运动模糊对特征提取的影响很大。我更推荐的做法是用手持稳定器或直接手持以每秒一张左右的节奏连拍每拍一张略微移动一点位置。这样得到的照片数量在30到100张之间重叠度和视角变化都比较理想。如果只能录视频抽帧间隔至少每隔5帧取1帧并且在抽帧前先做一次去模糊处理。3.3 传感器设置与防范过曝照片的质量指标里最影响3DGS的是曝光和清晰度而不是像素大小。2000万像素的模糊照片远不如1000万像素的清晰照片。我总结了一套比较稳妥的参数模板快门速度不低于1/200秒避免手抖模糊光圈调到f/4到f/8之间保证景深足够大整个物体都在焦内ISO越低越好优先保证画面干净噪点会直接影响后续颜色学习关闭HDR模式。HDR会改变局部的亮度关系多张合成的照片里可能出现不一致的光照训练出来的场景看起来会“发虚”拍照前先把相机的风格模式调到“标准”或“自然”不要用鲜艳模式饱和度太高会让重建出的颜色失真。4. 训练参数的每一步都应该知道在干什么环境搭好、数据拍好之后进入正式的训练环节。原版仓库的训练入口是一个convert.py加一个train.py。convert.py负责调用COLMAP处理你输入的图片目录train.py负责读取处理好的数据开始训练。完整跑一趟的命令大概是这样的# 第一步对图片进行COLMAP重建 python convert.py -s /path/to/your/dataset # 第二步开始训练 python train.py -s /path/to/your/dataset -m /path/to/outputconvert.py跑完之后会在数据集目录下生成一个sparse文件夹里面是COLMAP计算出的相机位姿和稀疏点云。这一步如果报错优先检查图片格式支持jpg/png建议jpg和图片数量不要少于10张。train.py开始训练后你会看到一个进度条默认迭代次数是30000次每100次输出一次当前loss。不同配置的显卡整个训练耗时从10分钟到1小时不等。4.1 iterations、sh_degree 和 loss曲线怎么看iterations总迭代次数。默认30000对于大多数室内室外场景都够用。如果你的目标物体纹理非常简单一面白墙可以降到20000省时间。反过来如果场景特别复杂、照片超过200张可以适当增加迭代次数到40000-50000。但不要盲目加迭代越多对显存和时间的消耗越大而收益在后期几乎是平的sh_degree球谐函数的最大阶数默认是3。球谐函数在这里负责表达高光、反射这类随视角变化的颜色特征。阶数越高表达越精细但计算量和显存占用也越高。我的经验是大多数场景保持默认3就够了。如果你重建的是哑光材质物体改成2反而收敛更快loss曲线训练日志里会输出一个组合loss它由L1颜色损失、SSIM损失和体积正则化损失组成。看曲线趋势比看绝对值重要。正常情况下loss在最初几千次迭代里会急速下降随后进入缓慢下降阶段。如果loss曲线震荡剧烈甚至上升说明学习率可能过大或者数据本身有问题比如图片顺序混乱、位姿估计失败4.2 densify相关参数从稀疏到稠密的核心逻辑3DGS里的三维高斯一开始是很稀疏的训练过程会动态地“分裂”和“克隆”高斯点来适应场景的几何细节。这个过程叫densification它受几个关键参数控制densify_from_iter / densify_until_iter分别在哪个迭代开始和结束稠密化。默认是500开始、15000结束。在500次迭代之前模型只做基础的位姿和外观调整过早开始稠密化会导致高斯点分布混乱densify_grad_threshold触发高斯点分裂的梯度阈值默认0.0002。这个值可以理解成“敏感度”值越小一点微小误差就会触发分裂适合纹理细节特别多的场景值越大整体越稳定但细节可能丢失densification_interval每多少次迭代做一次稠密化默认是100。这个值一般不用动改小了会大幅增加计算量我自己的调参经验是当场景里出现明显的“糊掉”区域比如物体边缘发虚优先降低densify_grad_threshold到0.0001试试而不是盲目增加总迭代次数效果来得更直接。4.3 显存不足时的降级方案训练过程中最常见的报错就是CUDA out of memory尤其是12GB显存跑大场景的时候。几个有效的降级手段降低max_sh_degree参数比如从3降到2球谐的计算是显存大头之一减小训练图像分辨率。convert.py里默认会把图片short side缩放到1024参数是--resize你可以把输出分辨率降到800甚至640对最终效果影响可控显存却能省下来不少如果是在Windows上训练关闭其他占用显存的应用尤其是浏览器里开了大量硬件加速页面会莫名吃掉几百MB显存实在不行还可以用分块训练的思路把场景拆成几个区域分别训练再用后处理工具合并。这个操作复杂度高一些建议先把前两个方案用到位再考虑。5. 效果不理想时如何判断问题出在数据还是超参数训练跑完之后立刻想知道效果好不好有两条路一条是直接看训练日志里loss数字另一条是打开输出目录里的test文件夹看渲染出来的测试视角图片。前者的参考意义有限最重要的是后者——测试集图片是训练时没有见过的相机视角渲染图如果在这上面清晰、稳定说明模型泛化能力没问题。原版仓库在训练过程中会定期保存测试视角的渲染图输出目录的结构大概长这样output/点云文件.ply训练完成后的最终模型文件output/test/iterations_30000/测试视角渲染图output/train/iterations_30000/训练视角渲染图把测试图里每一张和原图并排对比基本能判断出问题类型。5.1 典型伪影A漂浮物打开渲染图如果看到场景周围有一团一团半透明的“烟雾”或细碎亮点术语叫floaters。这是3DGS最典型的失败模式原因通常是相机位姿估计有误或者某些高斯点被放到了本来没有实体的区域靠透明度来“欺骗”loss函数。对应的处理优先级是先检查COLMAP是否成功匹配了所有图片用COLMAP GUI打开project——如果某几张图没有被正确匹配重新补拍或删掉它们如果位姿没问题则考虑调高densify_grad_threshold降低高斯点分裂的频率减少在错误位置生成点。5.2 典型伪影B物体边缘闪烁旋转视角时物体会边缘出现毛刺或闪烁说明高斯基元过大覆盖了多个深度层。最简单的处理是训练结束后对模型做一次后处理减薄pruning把透明度极低的高斯点删掉。原版仓库没有直接提供这个脚本但社区里有很多pruning小工具原理都是遍历.ply文件剔除opacity小于0.1的高斯点。5.3 典型伪影C色彩发灰或过曝区域如果整体颜色看起来灰蒙蒙或高光区域一片死白大概率是拍照阶段曝光参数不合适或者图片里存在高动态范围场景没处理干净。回到数据阶段重拍或者调整曝光比任何参数调优都有效。一个能辅助定位问题的小技巧把convert.py生成的稀疏点云导入到MeshLab里看一眼。如果点云本身已经乱七八糟、密集成团或大范围缺失就不用花时间调训练参数了直接回到采集和COLMAP环节解决。5.4 用PSNR和SSIM做量化对比原版仓库里有一个evaluate.py脚本会在测试集上计算PSNR、SSIM和LPIPS三个指标。PSNR和SSIM越高、LPIPS越低代表渲染质量和原图越接近。但我要泼一盆冷水这三个指标只能作为参考不能完全依赖。PSNR对亮度偏差非常敏感如果你拍的照片和渲染图存在轻微的全局色调差异PSNR会很难看但人眼实际感知可能非常好。所以我建议以肉眼判断为主指标为辅。作为参考一个训练正常的室内场景PSNR大约在27到32之间SSIM在0.85到0.95之间。低于这个区间先查数据高于这个区间说明场景本身比较简单模型做得不错。6. 拿到模型之后渲染导出与其他进阶玩法训练完成后你手里有一个.ply文件它包含了几十万个高斯点的位置、颜色、旋转、缩放、透明度信息。这一步之后你有很多种出路。6.1 用训练好的模型渲染视频原版仓库中有一个render.py脚本它做的事是根据训练时保存的相机轨迹逐帧渲染并输出视频实现“绕物体旋转”或者“穿越场景”的效果。如果你想生成自定义的相机轨迹而不是训练时的轨迹官方脚本支持比较有限可以用社区里的slerp插值脚本在关键帧之间做球面线性插值生成平滑的相机路径。我个人试过用它与原版render.py组合输出一段10秒钟的物体环绕视频效果比官方自带轨迹灵活得多。注意生成的轨迹要保证相机始终朝向场景中心并且没有穿过任何高斯基元否则画面里会出现穿模。6.2 把高斯点云转成传统网格模型高斯点云可以直接用于实时渲染但如果你需要把它导入到Blender、Maya或者游戏引擎里做物理碰撞计算必须先把点云转成网格模型.obj或.fbx。社区方案里比较成熟的有SuGaR它能把3DGS训练的高斯点提取成带纹理的三角网格。SuGaR的使用体验是对简单场景单个物体效果好对复杂场景需要额外调参。你也可以在点云阶段用Poisson重建Open3D里几个函数就能搞定但出来的网格面数较多需要配合简化工具减面。还有一条值得提的路把高斯点云直接导入到基于Web的渲染器比如Three.js的gsplat插件里在网页端做实时交互展示。相比传统网格这种方式省去了网格化的损失画面质量和实时渲染速度都很好很适合电商产品展示和线上展厅类的项目。6.3 稀疏视角重建与连续场景扩展最后聊一个扩展方向。原版3DGS做完一个场景后只能看这一个场景但实际项目里经常需要“大范围连续场景”——比如一条商业街或者一个厂房内部。两个做法把大场景拆成若干个子场景分别重建再用点云配准工具把它们对齐融合。融合的关键是相邻子区域要有30%以上的重叠拍摄区域否则找不到共同特征点用稀疏视角重建的思路只对关键位置拍照结合先验知识让3DGS“脑补”中间内容。这是当前学术界的前沿方向工业落地还有距离但值得关注我自己用3DGS做完一个器物级项目后的最大体会是这技术真正难的不是写代码而是工程化——从数据采集的环境设计到COLMAP中间产物的质量检查再到训练参数的微调每一环都需要耐心试错。但正因为如此一旦你完整跑通一遍再看NeRF或者别的重建方案会觉得世界一下子清晰了不少。如果再让我给一个具体的下一步建议项目跑完后补一组不同光照条件下的测试图片用测试集评估一下你的模型对光照变化的鲁棒性。这个实验会告诉你你的模型离真实落地还有多远。
分享:

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

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