本文介绍了基于ubuntu20.04下colmap的两种使用方法,新手向,如有不对请指教,因为colmap的安装编译网络上有很多教程,并且很容易操作,这里不再赘述。本博客的大部分内容都是copy其他大佬的,如有侵权,我会立即删除,也请大家指出我逻辑和内容上的错误,我会不断完善本文,争取做到一文搞懂colmap的使用方法
转载于:
三维重建_COLMAP安装、使用和参数说明(翻译自官方文档)_圣右的博客-CSDN博客
colmap的使用简介_m0_49441146的博客-CSDN博客_colmap
这是colmap组织工程的大概结构,这里先大概了解一下有印象即可,images里存储的就是我们要重建的图片
这是建立稠密图一系列操作后的工程结构,也是有个大概印象即可
官方文档地址:Tutorial — COLMAP 3.8 documentation 官方文档很重要,许多内容其实都是源自这里,建议有时间的时候仔细阅读一遍官方文档,比四处找博客有帮助
可以选择两种方式使用colmap,在colmap提供的GUI界面上进行操作,或者通过命令行进行操作,个人推荐第一种(我比较懒)
在运行colmap之前,我们需要准备一下colmap所需的数据集,我们可以从官方文档里下载,地址是:Page Redirection,这里的数据集是colmap官方文档提供的,和colmap论文里用的数据集不一样哦,论文里的数据集(罗马城等)都比较大,不适合新手操作(如果你想稠密重建,太大的数据集会花掉一整天甚至更多的时间)。当然我们也可以自己动手创造数据集,围绕着一个物体拍摄上一组照片,用我们的手机相机即可。网络上还有许多其他的数据集可以选择,室内、室外、小场景、大场景等等,可参考SFM三维重建数据集_知识在于分享的博客-CSDN博客_sfm数据集
依次介绍一下两种操作colmap的方式:
1.首先在命令行输入:
colmap gui
我们会发现打开了colmap的界面:
2.新建项目
首先点击file新建项目“New Project”
,弹出窗口,首先建立database,命名为scan1,后缀的db是它自动带上的,然后在Images中选择存储图像的文件夹
3.特征点提取
之后就可以进行特征点提取,点击processing中的Feature extraction,其中可以什么都不动,使用默认项,也可以自己修改,比如相机模型一般选择针孔模型,也可以换别的。选择Parameters from EXIF:从EXIF中提取相机内参(一般采集到的影像都携带EXIF文件),然后点击Extract进行特征提取
4.特征点匹配
特征提取之后,需要进行特征匹配,点击processing中的Feature matching
,其中可以什么都不动,使用默认项,也可以自己修改,然后点击run
。
这个步骤结束之后会自动生成场景图和匹配矩阵(以不同视图之间同名特征数为权重,以不同视图为图节点的图结构)
5.稀疏点云重建
然后就是稀疏点云重建。这里点击“reconstruction”中的“start reconstruction”进行一键式重建,整个过程将会自动进行增量式重建,我们可以从旁边的log框内查询当前状态
(1)log显示中,可以看出,先进行姿态估计(Pose Refinement Report):
Registering image #39(49):当前正在新增第39个视角
=> Image sees 337 / 503 poin :当前影像可以看到已有点云的337个Pose refinement report :姿态细化信息
Residuals:672
Parameters:8 //参数
Iterations:8 //迭代次数
time:0.0055149
Initial cost:0.62589
Final cost:0.55798
Termination:covergence
Continued observation:3 //继续观察
Added observations:47 //新增观察点(2)再进行BA优化:
Bundle adjustment report :BA优化
Residuals:12142
Parameters:1082 //参数
Iterations:12 //迭代次数
time:0.167065
Initial cost:0.515275
Final cost:0.504027
Termination:covergence
Merged observations:110//合并观察? 整体稀疏点云融合测量点110个
Completed observations:XXX //完成观察
Filtered observation 41 //过滤观察 滤除测量点41个
Changed observation XXX
(3)最后进行三角测量(Retriangulation):新增观测点111个,上述过程结束后,进行迭代全局的BA优化,优化已有相机的姿态和三维稀疏点云坐标。
综上,以第49张图像(39个视角)为例,已有点云576个首先进行姿态估计(Pose Refinement Report)再进行BA优化:整体稀疏点云融合测量点149个,滤除测量点32个再进行三角测量(Retriangulation)最后再进行迭代全局的BA优化,优化已有相机的姿态和三维稀疏点云坐标
6.稠密点云重建
点击“reconstruction”中的“dense reconstruction”,弹出稠密重建窗口,并点击“select”选择生成文件存放的目录,然后对窗口前三个选项一次点击:
Undistortion: 影像去畸变
注意:这里不要选择项目的根目录,拷贝图片的时候会报错路径已存在导致colmap gui闪退的;同时undistortion也只能点一次,第二次同样会因为路径已存在闪退,带有畸变的图像会导致边缘有较大的时差估计误差,因此在深度图估计之前,使用光学一致性和几何一致性联合约束构造代价匹配,dtu数据集和之前配置成针孔模型已经隐含无畸变,如果使用自采集数据集需要更改相机模型为带畸变参数的相机模型
stereo:深度估计
深度估计结束后,可以得到“photometric”和“geometric”下的深度图和法向量图。由之前提及的原理,COLMAP会利用光学一致性(photometric)同时估计视角的深度值和法向量值,并利用几何一致性(geometric)进行深度图优化,因此可以点击“Depth Map”和“Normal Map”,即可得到对应视角的深度图和法向量图。Stereo这一步会消耗大量时间
Fusion:稠密重建
重建后会在dense中生成fused.ply文件,通过meshlab,可以更清晰的看到重建结果,meshlab需要自己安装
7.photometric(光度)与geometric(几何)的Depth map(深度图)、normal map(法线图)
(1)photometric-Depth map 光度深度图
(2)photometric-normal map 光度法线图
(3)geometric-Depth map 几何深度图
(4)geometric-normal map 几何法线图
1.打开工程进行自动重建:
DATASET_PATH=/path/to/project #工程文件夹里必须包含一个叫做images的文件夹,里面放着重建所需要的图片
colmap automatic_reconstructor \
--workspace_path $DATASET_PATH \
--image_path $DATASET_PATH/images
2.单步重建:
(1)路径设置:
DATASET_PATH=/path/to/dataset
注意:工程文件夹里必须包含一个叫做images的文件夹,里面放着重建所需要的图片
(2)提取特征点:
./colmap feature_extractor \
--database_path $DATASET_PATH/database.db \ # 输出:特征点保存至数据库database.db
--image_path $DATASET_PATH/images # 输入:多视图图像
(3)特征点匹配:
./colmap exhaustive_matcher \
--database_path $DATASET_PATH/database.db # 输入输出:数据库文件database.db
(4)稀疏重建:
mkdir $DATASET_PATH/sparse # 新建sparse文件夹
./colmap mapper \
--database_path $DATASET_PATH/database.db \ # 输入:数据库文件database.db
--image_path $DATASET_PATH/images \ # 输入:多视图图像
--output_path $DATASET_PATH/sparse # 输出:`sparse`文件夹
输出结果sparse
文件夹如下所示:
└── sparse # 稀疏重建结果
└── 0
├── cameras.bin # 相机内参
├── images.bin # 相机位姿
├── points3D.bin # 稀疏3D点
└── project.ini
(5)图像去畸变:
mkdir $DATASET_PATH/dense # 新建dense文件夹
./colmap image_undistorter \
--image_path $DATASET_PATH/images \ # 输入:多视图图像
--input_path $DATASET_PATH/sparse/0 \ # 输入:sparse文件夹
--output_path $DATASET_PATH/dense \ # 输出:dense文件夹
--output_type COLMAP \ # 参数:输出格式
--max_image_size 2000 # 参数:最大图像尺寸
输出结果dense
文件夹如下所示:
└── dense
├── images
│ ├── 100_7100.JPG
│ ├── 100_7101.JPG
│ ├── ...
│ └── 100_7110.JPG
├── run-colmap-geometric.sh
├── run-colmap-photometric.sh
├── sparse
│ ├── cameras.bin
│ ├── images.bin
│ └── points3D.bin
└── stereo
├── consistency_graphs
├── depth_maps
├── fusion.cfg
├── normal_maps
└── patch-match.cfg
(6)为稠密建图再匹配:
./colmap patch_match_stereo \
--workspace_path $DATASET_PATH/dense \ # 输入输出:dense文件夹
--workspace_format COLMAP \ # 参数:工作区格式
--PatchMatchStereo.geom_consistency true
稠密重建的结果:为每张图像估计depth_map
和normal_map
└── dense
├── images # resize之后的图像
│ ├── 100_7100.JPG
│ ├── 100_7101.JPG
│ ├── ...
│ └── 100_7110.JPG
├── run-colmap-geometric.sh
├── run-colmap-photometric.sh
├── sparse
│ ├── cameras.bin
│ ├── images.bin
│ └── points3D.bin
└── stereo
├── consistency_graphs
├── depth_maps
│ ├── 100_7100.JPG.geometric.bin
│ ├── 100_7100.JPG.photometric.bin
│ ├── ...
│ ├── ...
│ ├── 100_7110.JPG.geometric.bin
│ └── 100_7110.JPG.photometric.bin
├── fusion.cfg
├── normal_maps
│ ├── 100_7100.JPG.geometric.bin
│ ├── 100_7100.JPG.photometric.bin
│ ├── ...
│ ├── ...
│ ├── 100_7110.JPG.geometric.bin
│ └── 100_7110.JPG.photometric.bin
└── patch-match.cfg
(7)开始建图(融合):
./colmap stereo_fusion \
--workspace_path $DATASET_PATH/dense \ # 输入:dense文件夹
--workspace_format COLMAP \ # 参数:工作区格式
--input_type geometric \ # 参数:输入类型
--output_path $DATASET_PATH/dense/fused.ply # 输出:fused.ply文件
(8)poisson法建网格添加纹理:
colmap poisson_mesher \
--input_path $DATASET_PATH/dense/ \
--output_path $DATASET_PATH/dense/meshed-poisson.ply
(9)delaunay法建网格添加纹理:
colmap delaunay_mesher \
--input_path $DATASET_PATH/dense/fused.ply \
--output_path $DATASET_PATH/dense/meshed-delaunay.ply
在colmap命令行使用过程中如果遇到哪条指令忘记是啥了直接-h就ok了,另所有命令和gui操作在文档里都有,需要的话去直接查就ok了,个人觉得GUI会更直观,也不容易犯错
你的相机参数可以在EXIF中直接提取或者在实验室中先验得到相机参数。建议如果是用的缩放系数相同的同义相机,最好就选择共享相同的参数。
可以去官方文档查阅各个相机模型的差异与用法,文档截图如下,文档地址见博客开头部分:
SIMPLE_PINHOLE,PINHOLE:如果选择的图像先天不失真,就使用这个相机模型。当然,即使在图片未失真的情况下,colmap也会选择尝试用一个相对更复杂的相机模型来改善相机参数。
SIMPLE_RADIAL,RADIAL:如果一个相机参数是未知的并且每张图片都有一个不同的相机标定,比如互联网的上的图片,那么就应该选择这个相机模型。这两个模型分别是OPENCV, FULL_OPENCV的简化模型,这两个模型分别只用一个和两个参数来估计相机的径向畸变效应。
OPENCV,FULL_OPENCV:如果你对每张图片的都有一个先验的相机参数,那么既可以选择使用这个相机模型。当然你也可以选择让多张图片共享同一个相机参数然后colmap来估计该相机参数。当然,如果你每张图片实际上都有一个不同的相机参数的话,自动重建很有可能失败。
SIMPLE_RADIAL_FISHEYE,RADIAL_FISHEYE,OPENCV_FISHEYE,FOV, THIN_PRISM_FISHEYE:鱼眼相机模型使用用这些相机模型。其他的所有相机模型均不能修复鱼眼相机模型的畸变。FOV模型是由Google的 Google Project Tango使用。确保不要将omega初始化为0。
几点注意事项:
可以在gui界面里双击specific images或者在导出的模型里看cameras.txt文件来检查估计的相机参数对不对。
为了得到最佳的重建效果,可以尝试多种不同的相机模型。
通常,如果你估计的焦距值和失真系数严重错误的话,一般是选择了过于复杂的相机模型。相反的,如果colmap使用了太多的本地迭代和相机之间联系的调整,则是选择的相机模型过于简单而不能完全的修复畸变效果。
可以选择在多张图片之中选择共享参数以获得更可信的重建结果:Share intrinsic camera parameters,或者你也可以在重建过程中修正相机参数:Fix intrinsic camera parameters
穷举匹配(Exhaustive Matching):当你的数据集比较小的时候(小于100张),选择这种模式。这种模式匹配速度足够快并且是最好的效果。每张图片都与其他的所有图片进行匹配。最后生成的块大小取决于你载入内存中的图片的数量。
顺序匹配(Sequential Matching):当你拍照的时候是以连续的方式(比如视频)采集图像的话,这种方式是有用的。连续帧具有视觉重叠。每一帧的图像不必和其他所有图像都进行匹配。只有连续帧匹配就OK了。该模式也有内置的循环检测,第N个图像与其视觉上最为相似的图片匹配。但需要事先训练字典树。https://demuc.de/colmap/ 在这里可以下载。此种方法非常适合在视频序列中大量采用的情况,相比于全局匹配模式大大降低了matching时间。
字典树匹配(Vocabulary Tree Matching):在这种匹配模式下,每张图片都与与他视觉上最相近的经过按空间顺序重新排序的邻居匹配。也需要实现训练好字典树,网页地址同上。
空间匹配(Spatial Matching):这种模式下每个图像均与其空间最近邻居进行匹配。可以在数据库中手动设置空间位置。默认情况下colmap还会从EXIF中获取GPS的相关信息并用来寻找空间上最相近的邻居。如果有准确的先验空间位置信息的话,这种是推荐的匹配模式。
传递匹配(Transitive Matching):这种匹配模式使用已经存在的特征匹配的传递关系来完成更完整的匹配图。例如如果图像A匹配B而B也匹配C,那么colmap将尝试直接匹配A到C。
自定义匹配(Custom Matching):这种模式下允许指定的单个图片去匹配其他图片或者导入指定的已匹配的信息。要指定图像对的话,必须提供一个文本文件如下(每行一对一):
其中image1.jpg是图像文件夹的相对路径。有两种方式来导入单个的特征点匹配方法。原始的(未经过几何校验的)和已经经过几何校验的。在这两种选项中,格式是这样的:
其中image1.jpg是图像文件夹在工程中的相对路径,并且数字是各个图像中从零开始的特征的索引。如果给大型图像集导入很多匹配项的话,采用脚本语言更为合适。
模型导出的格式常用的主要是二进制文件格式或者txt文件格式,当然你的需求如果是其他格式的话也是可以的(比如nvm格式),二进制文件格式colmap读取起来更加快速,txt文件格式是人可读的,但colmap读取起来比较慢。如果colmap选择要读取的目录下面既有二进制文件格式又有txt文本格式,colmap会优先选择二进制文件格式。
直接在gui界面里,左上角有一个export model 和export model as text,根据你的需要选择导出目录并导出就OK了。
导出的模型一般包括三个文件:cameras.txt/ cameras.bin, images.txt/ images.bin, points3D.txt/ points3D.bin,这三个文件的作用顾名思义,具体的一些介绍去官方文档看就ok了。