
简介面向需要自制 3D Gaussian Splatting3DGS训练数据的开发者这份项目源码提供了基于 Colmap 工具从图像采集到数据集生成的全流程实现。资源包含 3 个 Python 脚本配置、稠密重建、格式转换、5 张示例图片、说明文档与运行配置共 12 个文件压缩包仅 379KB便于快速上手与二次修改。已有 306 人查看学习适合入门及进阶用户参考。资源在覆盖稀疏重建、稠密重建、格式转换等核心步骤的同时针对稀疏重建无相机轨迹、稠密点云孔洞多等问题给出了排错指南并结合设备与效率优化建议帮助用户低成本构建适用于多类场景的 3DGS 数据集为后续训练与应用提供实用基础。 很多朋友第一次接触3DGS3D Gaussian Splatting3D高斯泼溅的时候都会先拿官方提供的那几个现成场景跑一遍训练。跑通之后问题就来了我想重建自己的物体、自己的房间该怎么办这时候你就绕不开一个叫COLMAP的东西。COLMAP负责从一组普通照片里算出相机位置和稀疏点云而3DGS的训练恰恰需要这些信息作为初始输入。可以这么说COLMAP这一步做不好后面训练再怎么调参都是白搭。这篇内容我打算把用COLMAP自制3DGS数据集这条链路完整讲一遍从照片怎么拍、COLMAP怎么跑、输出怎么转成3DGS需要的格式到最终训练效果不好时怎么排查。适合两类人看一是刚跑通3DGS官方demo、想自己做数据集的新手二是已经在做三维重建但被COLMAP的稀疏重建质量和数据组织方式折腾过的人。整个过程我会结合自己实际操作中踩过的坑来讲不绕弯子。1. 3DGS的训练管线里COLMAP为什么是地基1.1 从一堆照片到可训练数据中间发生了什么3DGS的训练本质上是输入一组带相机位姿的图片通过优化三维高斯分布来拟合场景。但相机位姿不会凭空出现它必须从照片本身估算出来。这个估算过程就是运动恢复结构Structure-from-MotionSfM而COLMAP是目前最常用的开源工具。COLMAP会做三件核心事情检测每张图里的特征点比如角点、纹理边缘在不同图片之间匹配这些特征点找出这两张图拍的是同一个位置的对应关系根据这些对应关系用光束法平差Bundle Adjustment同时优化相机内外参数和三维点坐标最终输出每张图的位姿矩阵、相机内参以及一个稀疏点云。这些输出对3DGS来说就是训练数据的地基。没有准确的相机位姿三维高斯根本不可能在正确的位置上收敛渲染出来的画面会是一片糊或者直接崩掉。1.2 官方源码的输入格式要求3DGS的官方源码graphdeco-inria/gaussian-splatting对数据集目录结构是有明确要求的。一个标准的可训练场景目录大概长这样data/xxx/ ├── images/ # 原始图片或经过处理后的图片 ├── sparse/0/ # COLMAP 输出的相机位姿和稀疏点云 │ ├── cameras.bin │ ├── images.bin │ └── points3D.ply └── ...images放图sparse/0放COLMAP重建结果。训练脚本加载时会从cameras.bin里读相机内参从images.bin里读每张图的位姿从points3D.ply里读初始点云然后开始训练。所以整个流程可以概括成一句话拍摄图片 → COLMAP稀疏重建 → 整理成官方格式 → train.py开始训练。后面所有内容都是围绕这句话展开的。2. 拍摄照片的实操要领数据质量决定训练上限我自己第一次做数据集的时候觉得拍照嘛围着物体转一圈不就行了结果跑了COLMAP之后发现重建的稀疏点云稀稀拉拉相机位姿歪七扭八训练出来的效果惨不忍睹。后来才意识到COLMAP和3DGS的很多问题根子不在工具而在照片本身。2.1 场景选择和重叠率先说场景。COLMAP的特征匹配依赖纹理所以场景里最好有比较丰富的纹理细节。纯白墙面、光滑桌面这类大面积低纹理区域特征点很少匹配很难建立重建很容易失败。再说重叠率。相邻两张照片之间要有足够的共同视野一般建议重叠率在60%到80%之间。通俗地说你拍完一张照片下一张至少要能看到上一张里一半以上的内容。如果两张图之间的重叠太少COLMAP找不到足够多的匹配点位姿估计就会飘。那怎么控制重叠率最简单的办法是移动幅度小一点。拍摄时让相机每次移动的距离短一些让视角变化控制在15度以内这样相邻帧之间的匹配会非常稳定。2.2 拍摄轨迹、光照与运动模糊这里我特别想强调一个容易犯的错围绕物体拍摄时不要只在一个高度上原地转一圈。这种纯旋转式的拍摄会让相机之间的基线baseline太小导致三角化出来的三维点深度不确定位姿容易退化。最好采用多圈、多高度、多角度的轨迹比如螺旋上升式地绕着物体拍或者在不同距离上各拍一圈。光照方面最理想的是均匀的散射光比如阴天或室内柔光灯环境。强光直射会造成明显的阴影和高光而高光区域的像素在不同视角下变化剧烈会让特征匹配很难做。拍摄时尽量固定白平衡和曝光参数不要让画面忽亮忽暗。如果做不到宁可后期统一做一次颜色校正也不要让相机自动曝光在各个角度跳来跳去。运动模糊是另一个杀手。手持拍摄时快门速度不够画面糊了特征点检测会失败。建议快门速度不低于1/100秒条件允许的上三脚架。一个很实用的检查方法是拍完后在电脑上把照片放大看如果细节纹理处有拖影赶紧重拍别浪费时间跑COLMAP。2.3 图片规模和硬件取舍图片数量不是越多越好。COLMAP的特征匹配是两两组合的图片多到一定程度匹配时间会爆炸式增长。以我的实测经验单个场景控制在80到300张是比较合理的区间。如果场景特别大比如一个完整的房间可以分区块拍摄最后再合并重建而不是一口气拍上千张丢给COLMAP。图片分辨率也要考虑。COLMAP的内部默认会限制最大图像尺寸max_image_size过大的图会先被缩放。我习惯把输入图片控制在3000像素以内既能保留足够的特征细节又不至于让特征提取和匹配慢到无法接受。如果你用的是官方convert.py脚本里面也默认做了类似的缩放处理。3. COLMAP稀疏重建从特征点到相机位姿的完整执行3.1 环境准备与命令行参数COLMAP的安装方式官网写得很清楚Windows有预编译的图形界面版本Linux和macOS可以用conda、apt或源码编译。我建议新手先用图形界面COLMAP GUI熟悉一下流程但真正要批量处理、固定复现的时候命令行会高效得多。一个典型的两步走流程如下。第一步特征提取colmap feature_extractor \ --database_path project.db \ --image_path images/ \ --ImageReader.single_camera 1 \ --SiftExtraction.max_image_size 3200 \ --SiftExtraction.max_num_features 32768--ImageReader.single_camera 1表示所有照片来自同一个相机内参共享一套。如果你用同一台手机或相机拍完整套图这项一定要开能明显提高重建稳定性。--SiftExtraction.max_image_size 3200控制输入图缩放上限。--SiftExtraction.max_num_features 32768提高每张图允许提取的最大特征点数。纹理多的图默认值可能不够用。第二步执行特征匹配和稀疏重建colmap exhaustive_matcher \ --database_path project.db \ --SiftMatching.guided_matching 1 mkdir -p sparse/0 colmap mapper \ --database_path project.db \ --image_path images/ \ --output_path sparse/0 \ --Mapper.ba_global_function_tolerance 0.000001这里解释两个关键点。exhaustive_matcher对图片数量不多比如几百张的场景是够用的它会把所有图片两两匹配最稳但最慢。如果图片量很大建议改用sequential_matcher按顺序相邻匹配或者spatial_matcher根据GPS先验加速但对普通场景来说exhaustive仍然是最省心的选择。guided_matching打开之后COLMAP会利用已知的几何约束去搜索更多匹配点能显著提高弱纹理区域的匹配数量代价是耗时多一点。我一般都会开。mapper会先从一个图像对开始增量重建然后不断加入新图像。ba_global_function_tolerance是全局光束法平差的收敛阈值默认值有时会在位姿还没收敛时就提前停止调小这个值能得到更精细的位姿优化结果。3.2 如何判断重建是否成功跑完mapper之后sparse/0目录下会生成一堆以数字命名的子文件夹每个文件夹对应一个重建模型。这时候要做质量检查。打开COLMAP GUI选择 File → Import model from disk 加载sparse/0里那个重建结果。检查三点注册的相机数量正常应该接近你的输入图片总数。如果只有一半照片被成功注册说明很多图没找到可靠的匹配关系重建不完整。点云形态场景的三维点应该呈现清晰可信的物体轮廓而不是一团乱麻。如果点云有明显弯曲、不闭合或者悬浮颗粒说明位姿有问题。相机轨迹界面里可以看到蓝色的相机金字塔或锥体它们代表每张照片的位置和朝向。一个健康的轨迹应该是平滑连续的而不是突跳、交叉或者全部挤在一个点上。我在实际操作中见过最多的失败表现就是只有开头十几张图被成功注册后面全部失败。这种基本都是拍摄时相邻帧重叠不足或者画面出现大量运动模糊导致的。3.3 使用官方convert.py还是手动跑官方3DGS仓库里提供了一个convert.py它内部就是调用COLMAP来跑特征提取、匹配和稀疏重建然后自动把结果处理成3DGS需要的格式。所以很多人会直接python convert.py -s data/xxx --colmap_executable colmap这个脚本做的事情包括生成images/和sparse/0/把COLMAP的文本格式转成二进制生成降畸变后的图片和点云最终输出一份经过缩放处理的训练集。用脚本的好处是省事、格式不会错。但它也隐藏了一些参数比如它会默认把图片缩放并且会执行图片的畸变矫正undistortion。如果你用的是建模拍摄、全景照片或者特殊的相机模型脚本的默认行为不一定符合需求。所以建议理解它的内部逻辑而不是只会无脑执行。后面第4章我会拆解它到底做了什么。4. 把COLMAP输出转成3DGS可用的数据集格式4.1 目录结构长什么样训练前数据目录最终要整理成这样的结构data/my_scene/ ├── images/ # 去畸变后的图片名字形如 00000.png ├── sparse/0/ │ ├── cameras.bin # 相机内参二进制 │ ├── images.bin # 图像位姿信息二进制 │ └── points3D.ply # 稀疏点云PLY格式 └── ...convert.py会把COLMAP生成的文本模型转成二进制模型再把点云转成PLY格式。3DGS训练时读取的就是这些二进制文件所以如果你的COLMAP输出是文本格式cameras.txt、images.txt、points3D.txt要么用colmap model_converter转成.bin要么直接用官方脚本处理。二进制和文本格式之间存在一个常见坑COLMAP默认输出可能是文本格式而3DGS读取代码硬编码了.bin。你如果不转换直接丢给训练脚本会出现找不到文件或者解析错误。4.2 官方的模型转换命令如果你打算手动转换可以用这条命令colmap model_converter \ --input_path sparse/0 \ --output_path sparse/0 \ --output_type BIN它会读取sparse/0下的文本模型原地转成cameras.bin、images.bin、points3D.bin。注意3DGS需要的是points3D.ply所以还要把稀疏点云导成PLYcolmap model_converter \ --input_path sparse/0 \ --output_path sparse/0/points3D.ply \ --output_type PLY这里有个容易踩的坑points3D.bin是COLMAP的二进制点云格式而3DGS读取的是PLY格式两者不能混淆。如果你发现训练脚本报错说找不到points3D.ply多半是导出PLY那步没做。4.3 从COLMAP到3DGS训练数据还要注意什么convert.py里还有一个关键操作对图像做去畸变处理。因为COLMAP估出来的相机内参包含径向畸变参数而3DGS训练时用的是针孔相机模型不做去畸变的话图像的像素坐标和相机模型对不上训练出来的效果会虚。处理逻辑大致是读COLMAP标定的畸变参数对所有图像重投影到无畸变平面生成新的images/目录同时更新相机内参。这也意味着如果图像被缩放或裁剪过内参必须同步更新否则相机位姿和图像内容就不匹配了。官方脚本处理好了这些细节所以对大多数人来说直接用它转是最稳妥的路径。那什么时候必须手动代替脚本我遇到过的几种情况你的COLMAP重建失败了但你想手动修复模型比如删除错误位姿的图片你需要人为添加mask比如把背景去掉而mask要以图片名对应场景太大一次性跑不完需要分块重建再合并。这些情况脚本都不方便介入需要自己维护数据目录。5. 重建效果差怎么办完整排查链路5.1 特征点太少、匹配不上最直接的现象是COLMAP运行后注册的图片数量很少或者稀疏点云稀疏到几乎看不见东西。排查思路在COLMAP GUI里打开任意一张图看特征点检测结果。如果一张纹理丰富的图检测出的特征点只有几十个说明max_num_features设太低了或者图像本身太模糊。检查图片是否过度曝光或欠曝光。过曝的天空、白色区域特征点几乎为零。检查是否是纯旋转拍摄。如果相机原地转动而几乎没有平移相邻帧之间会存在视差不足的问题导致三角化失败。我这边的处理经验是把相机从原地转圈改成移动着绕圈哪怕每次只移动一两厘米重建质量都会有质的提升。另外拍摄过程中尽量保持相机离物体有一定距离太近会导致相邻帧重叠区域过小。5.2 相机位姿漂移或场景坍塌重建结果看起来有模有样但训练出来的3DGS场景里某些部分重影严重或者出现飘浮的飞絮那大概率是位姿精度不够。一个典型情况是COLMAP把一些视角差异很大的照片错误配准了。比如拍摄时光照变化太大导致特征点匹配被误导或者物体表面是镜面反光材质不同角度下高光点位置不同造成错误对应。排查方法是在COLMAP GUI里逐张查看匹配关系。选中一个三维点看它投影到各图片上的位置是否真的对应同一个物理点。如果发现某些图像的匹配明显不对就从重建里删除这些图像重新做一次全局优化或者直接剔除后重新运行mapper --resume继续增量优化。另外Mapper.ba_global_function_tolerance调小然后配合多次迭代很多时候能救回轻微的位姿漂移。重建完成后还可以用colmap bundle_adjuster对全局模型再做一次精修。5.3 低纹理、高光、反射面的处理大面积白墙、玻璃、水面是COLMAP的天敌。它们要么没有特征点要么特征点在多视角下不稳定。处理办法有几种在纹理确实太弱的区域可以放置一些有明显图案的标定板、报纸、或者临时贴纸重建完成后再移除。这不只是方便特征匹配还能给3DGS提供更可靠的几何约束。玻璃和水面这类透明或反光材质它们在不同视角下看起来完全是不同的东西COLMAP很难正确处理。如果实在拍不好要么放弃这部分场景要么拍摄前想办法让表面变得哑光比如给玻璃打蜡、喷临时可去除的涂层。对高光严重的物体尽量用散射光源而不是直射灯也可以加偏光镜消除部分反光。5.4 用训练结果反推数据集问题如果你已经拿到了3DGS训练结果但效果不理想可以反向定位问题背景清楚、物体模糊多半是物体部分的图片位姿不准或者拍摄时对物体的重叠率不够。从某个特定角度看全是噪点这个角度附近的源图像数量不足尽可能补拍一些该角度的照片然后重新跑COLMAP和训练。整体画质糊但点云是对的检查是不是图像分辨率太低或者训练迭代次数不足。官方默认是30000次迭代如果数据集比较难收敛可以把迭代次数提高到50000甚至70000配合每2000次保存一个checkpoint挑验证集上效果最好的那版。渲染结果有大量长条状伪影这是3DGS训练优化不充分的表现可以尝试调低学习率或者给场景加上更合理的初始化点云。初始化点云越干净训练收敛越快。训练命令参考python train.py \ -s data/my_scene \ -m output/my_scene \ --iterations 30000 \ --test_iterations 7000 30000如果你只有CPU能跑加--data_device cpu。GPU显存紧张时把输入图片分辨率再缩小一些或者减少每次训练采样的图片数量都能缓解。写在最后自制3DGS数据集这件事最耗时间的其实不是训练而是数据采集和COLMAP重建。我个人的体会是拍摄时花一小时认真规划轨迹远比重建失败后花一整天排查问题要划算。每次拿到一个新场景我都会先快速拍一组小样比如20张用COLMAP跑一遍验证一下特征匹配和位姿是否稳定确认没问题再正式多拍。这个小习惯帮我避开了大量返工。最后再分享一个小技巧COLMAP在Windows下偶尔会遇到GPU内存不足导致特征提取直接崩溃这时候在命令行里加--SiftExtraction.use_gpu 0改用CPU提取特征虽然慢一点但胜在稳定。等匹配和重建阶段再切回GPU实测下来整个流程顺畅很多。本文还有配套的精品资源点击获取