news 2026/9/8 5:42:50

用COLMAP自制3DGS数据集:从照片到可训练场景全流程指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用COLMAP自制3DGS数据集:从照片到可训练场景全流程指南

简介:面向需要自制 3D Gaussian Splatting(3DGS)训练数据的开发者,这份项目源码提供了基于 Colmap 工具从图像采集到数据集生成的全流程实现。资源包含 3 个 Python 脚本(配置、稠密重建、格式转换)、5 张示例图片、说明文档与运行配置,共 12 个文件,压缩包仅 379KB,便于快速上手与二次修改。已有 306 人查看学习,适合入门及进阶用户参考。资源在覆盖稀疏重建、稠密重建、格式转换等核心步骤的同时,针对稀疏重建无相机轨迹、稠密点云孔洞多等问题给出了排错指南,并结合设备与效率优化建议,帮助用户低成本构建适用于多类场景的 3DGS 数据集,为后续训练与应用提供实用基础。 很多朋友第一次接触3DGS(3D Gaussian Splatting,3D高斯泼溅)的时候,都会先拿官方提供的那几个现成场景跑一遍训练。跑通之后问题就来了:我想重建自己的物体、自己的房间,该怎么办?这时候你就绕不开一个叫COLMAP的东西。COLMAP负责从一组普通照片里算出相机位置和稀疏点云,而3DGS的训练恰恰需要这些信息作为初始输入。可以这么说,COLMAP这一步做不好,后面训练再怎么调参都是白搭。

这篇内容我打算把"用COLMAP自制3DGS数据集"这条链路完整讲一遍,从照片怎么拍、COLMAP怎么跑、输出怎么转成3DGS需要的格式,到最终训练效果不好时怎么排查。适合两类人看:一是刚跑通3DGS官方demo、想自己做数据集的新手;二是已经在做三维重建,但被COLMAP的稀疏重建质量和数据组织方式折腾过的人。整个过程我会结合自己实际操作中踩过的坑来讲,不绕弯子。

1. 3DGS的训练管线里,COLMAP为什么是"地基"?

1.1 从一堆照片到可训练数据,中间发生了什么

3DGS的训练本质上是输入一组带相机位姿的图片,通过优化三维高斯分布来拟合场景。但相机位姿不会凭空出现,它必须从照片本身估算出来。这个估算过程就是运动恢复结构(Structure-from-Motion,SfM),而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里那个重建结果。检查三点:

  1. 注册的相机数量:正常应该接近你的输入图片总数。如果只有一半照片被成功注册,说明很多图没找到可靠的匹配关系,重建不完整。
  2. 点云形态:场景的三维点应该呈现清晰可信的物体轮廓,而不是一团乱麻。如果点云有明显弯曲、不闭合或者悬浮颗粒,说明位姿有问题。
  3. 相机轨迹:界面里可以看到蓝色的相机金字塔(或锥体),它们代表每张照片的位置和朝向。一个健康的轨迹应该是平滑连续的,而不是突跳、交叉或者全部挤在一个点上。

我在实际操作中见过最多的失败表现,就是只有开头十几张图被成功注册,后面全部失败。这种基本都是拍摄时相邻帧重叠不足,或者画面出现大量运动模糊导致的。

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.txtimages.txtpoints3D.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.binimages.binpoints3D.bin。注意:3DGS需要的是points3D.ply,所以还要把稀疏点云导成PLY:

colmap 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运行后,注册的图片数量很少,或者稀疏点云稀疏到几乎看不见东西。

排查思路:

  1. 在COLMAP GUI里打开任意一张图,看特征点检测结果。如果一张纹理丰富的图检测出的特征点只有几十个,说明max_num_features设太低了,或者图像本身太模糊。
  2. 检查图片是否过度曝光或欠曝光。过曝的天空、白色区域,特征点几乎为零。
  3. 检查是否是纯旋转拍摄。如果相机原地转动而几乎没有平移,相邻帧之间会存在视差不足的问题,导致三角化失败。

我这边的处理经验是:把相机从"原地转圈"改成"移动着绕圈",哪怕每次只移动一两厘米,重建质量都会有质的提升。另外,拍摄过程中尽量保持相机离物体有一定距离,太近会导致相邻帧重叠区域过小。

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,实测下来整个流程顺畅很多。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/6 6:11:27

机器学习本科毕业设计选题

适用专业:数据科学与大数据技术、人工智能、计算机科学与技术、软件工程、物联网工程 算法涵盖:线性回归、岭回归、Lasso、逻辑回归、决策树、随机森林、SVM、KNN、K-Means、层次聚类、DBSCAN、朴素贝叶斯、AdaBoost、XGBoost、LightGBM、特征工程、降维…

作者头像 李华
网站建设 2026/9/6 8:44:25

Frigate:给家里摄像头装上本地对象检测,30 分钟弄清谁进过院子

Frigate:给家里摄像头装上本地对象检测,30 分钟弄清谁进过院子 【免费下载链接】frigate NVR with realtime local object detection for IP cameras 项目地址: https://gitcode.com/GitHub_Trending/fr/frigate 人出门了,家里发生了什么没人知道。传统摄像头会把一切都…

作者头像 李华
网站建设 2026/9/3 6:51:16

2022联想Android校招复盘:从源码到系统定制的完整面试攻略

2022届校招,我把联想集团Android开发岗作为重点目标之一。当时刷了一圈社媒上的面经,发现这个岗位的面试很少直接考“背答案”,更多是借一个项目、一个现象把问题打到源码级别。整场面试走下来,我最大的感受是:联想校招…

作者头像 李华
网站建设 2026/9/6 8:23:25

如何搭建本地私有AI笔记空间:Open Notebook快速上手指南

如何搭建本地私有AI笔记空间:Open Notebook快速上手指南 【免费下载链接】open-notebook An Open Source implementation of Notebook LM with more flexibility and features 项目地址: https://gitcode.com/GitHub_Trending/op/open-notebook 一堆 PDF 读完…

作者头像 李华
网站建设 2026/9/4 0:31:24

AI制药技术全解析:从分子表示到性质预测

最近医疗创新药板块的表现,确实让很多人的注意力从“大力出奇迹”的半导体、AI 应用,一下子转向了医药赛道。朋友圈里甚至出现了“买科技已经过时”的说法。但作为一个技术作者,我更想提醒大家另一件事:创新药上涨背后&#xff0c…

作者头像 李华