尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

从 80 张照片到水密网格:拆解 COLMAP 稠密重建管线的源码实现

从 80 张照片到水密网格:拆解 COLMAP 稠密重建管线的源码实现 从 80 张照片到水密网格拆解 COLMAP 稠密重建管线的源码实现【免费下载链接】colmapCOLMAP - Structure-from-Motion and Multi-View Stereo项目地址: https://gitcode.com/GitHub_Trending/co/colmap假设你要为一栋待修复的建筑立面子做数字化存档手里只有手机拍的 80 张照片目标是得到能直接导入 3D 引擎的网格模型。COLMAP 的稠密重建管线做的就是这件事前半段用 SfMStructure-from-Motion解算相机位姿与稀疏点云后半段用 PatchMatch 算法逐像素估计深度再把深度图融合成上亿点的稠密点云最后输出网格。本文按源码级别拆穿深度估计、点云融合到网格化的完整链路不覆盖前半段 SfM 的注册细节也不讨论纹理映射。COLMAP 稠密重建管线全流程一图看懂整条链路由四个阶段接力每个阶段都是输入 → 核心动作 → 输出特征匹配原始照片 → 特征提取、匹配、几何验证 → 相机间对应点增量重建对应点 初始对注册 → 图像注册、三角化、光束法平差 → 相机内外参与稀疏点云深度估计稀疏模型 原图 → 逐像素深度假设检验与滤波 → 每张图一份深度图与法线图点云融合与网格化多图深度图 → 重投影与法线投票 → 稠密点云 → 网格。第 3 阶段的工作区目录结构直接写在 src/colmap/mvs/patch_match.h 的文件头注释里值得背下来images/* # 输入图像 sparse/{cameras,images,points3D}.txt # SfM 输出内参、位姿、稀疏点 stereo/depth_maps/* # 每张图的深度图 stereo/normal_maps/* # 每张图的法线图 stereo/consistency_graphs/* # 跨图像可见性一致图 stereo/patch-match.cfg # 指定参考图与源图配对上面六个目录恰好对应稠密重建的全部中间产物下面三个机制拆解也按这个顺序展开。PatchMatch 深度估计原理两个代价函数与一道滤波门槛它解决什么问题参考图像里一个像素的深度无法直接测量只能猜——把候选深度投影进其他图像比较局部块找一致性最高的那个。逐像素全深度范围扫描代价太高PatchMatch 的取巧之处是先给每个像素随机一个初始深度Monte Carlo 采样默认num_samples15个再做坐标下降——每个像素只借邻居的候选深度来试默认num_iterations5轮整张深度图就能收敛。它怎么做的每个深度假设由光度一致性双侧加权 NCC归一化互相关与几何一致性前向-后向重投影误差两项联合打分相对权重固定在 0.3// 摘自 src/colmap/mvs/patch_match_options.h注释为中文 double ncc_sigma 0.6f; // NCC 似然函数的扩散 double geom_consistency_regularizer 0.3f; // 几何项相对光度项的权重 double geom_consistency_max_cost 3.0f; // 几何项上限前向-后向重投影误差像素 int window_radius 5; // NCC 半窗大小即 11×11 局部块 int window_step 1; // 窗内采样步长1 表示每个像素都参与 int num_samples 15; // Monte Carlo 随机深度采样个数一个阈值的影响geom_consistency_max_cost3.0意味着前向-后向重投影误差超过 3 像素的深度假设直接丢弃。把它改成 1.0曲面区域开始大面积失效改成 10几何项等于没开低纹理区域的深度图会放飞自我错误只能留给下游融合去救。如果把几何项整个关掉geom_consistencyfalse剩下的纯光度匹配在白墙、玻璃幕墙这类无纹理区域完全失效——NCC 找不到可靠对应深度图变成随机拼贴这就是后面大多数空洞问题的直接来源。点云融合投票机制max_reproj_error 如何筛掉像素它解决什么问题单张深度图只保证自洽不保证正确——位姿偏一点全图深度就系统性偏一点。系统性误差只有跨视图交叉比对才能暴露。它怎么做的src/colmap/mvs/fusion.h 里的StereoFusion实现空间哈希 多视图投票每个有效深度像素投影到 3D 后写入哈希网格其他图像的深度图也向同一格投票重投影误差、深度差、法线角全部通过且支持数达到min_num_pixels才落点// 摘自 src/colmap/mvs/fusion.h注释为中文 int min_num_pixels 5; // 形成点云所需的最少支持像素数 int max_num_pixels 10000; // 单个点最多合并的像素数保薄结构用 double max_reproj_error 2.0f; // 最大重投影误差像素 double max_depth_error 0.01f; // 最大相对深度差 double max_normal_error 10.0f; // 法线最大夹角差度 int check_num_images 50; // 沿一致图遍历检查的重叠图像数一个阈值的影响max_reproj_error2.0是点云融合的主闸。改到 0.5点云变得极干净但点数掉一半因为深度图本身就带亚像素噪声改到 5.0鬼影面和悬浮噪声全回来。这道闸与 PatchMatch 的geom_consistency_max_cost是同一重投影误差的上下游上游放行 3 像素误差、下游只收 2 像素点云会整体变稀栏杆、屋檐这类薄结构最先消失。从零跑通稠密重建管线6 条命令以下命令走完整条管线输出全部落在ws/工作区里colmap feature_extractor --workspace_path ws --image_path photos你应该看到逐图写入特征点数量80 张 12MP 图像在 CPU 上约 3–5 分钟。colmap sequential_matcher --workspace_path ws colmap incremental_mapper --workspace_path ws你看到的逐图打印注册日志最后输出平均重投影误差低于 1.0 像素说明注册质量合格产物是这张稀疏点云colmap patch_match_stereo --workspace_path ws你看到的stereo/depth_maps/*.png与normal_maps/逐张落盘24GB 级消费级 GPU 跑 80 张 4K 图约 30–60 分钟。没有 CUDA 的构建会在 src/colmap/exe/mvs.cc 直接抛出Dense stereo reconstruction requires CUDA并终止。colmap stereo_fusion --workspace_path ws你应该看到融合点云fused.ply落盘并打印融合点数建筑外立面场景上亿点是正常量级。想要网格而不是点云融合完成后接colmap poisson_mesher --workspace_path ws薄结构多、表面开放的场景改用colmap delaunay_mesher它不要求封闭边界。真正影响质量的 4 个参数及它们的相互作用参数调好后的稠密重建长这样面片连续、没有双壁window_radius默认 5控制 NCC 的块大小。调大到 9光度约束更稳、噪声更少但边缘被抹平薄结构细节丢失调小到 3细节保留但低纹理区对噪声敏感。它和window_step强耦合用window_step2提速时若window_radius仍是 5窗口退化成稀疏格点源码注释明确警告 step 大于 2 会出坏结果——要提速宁可降max_image_size。geom_consistency_max_cost默认 3.0PatchMatch 的几何门槛上文已拆。它与稀疏模型质量耦合如果incremental_mapper的平均重投影误差已经有 1.5 像素说明位姿本身偏了此时 3.0 等于放行垃圾应该先重注册再谈调这个参数。max_reproj_error默认 2.0点云融合主闸。交叉示例如果你为了精度把它设成 1.0而geom_consistency_max_cost还是默认 3.0深度图里会带着最多 3 像素误差的假设过闸后只剩极少数通过——侧面、屋檐大面积出洞还容易被误诊成纹理不足。两道闸要同量级配置3.0/2.0快或 2.0/1.5准不要 3.0/1.0 这种错配。min_num_pixels默认 5控制一个点至少被几个视图支持才存活。设 3 做快速预览点云密但噪点多设 10点云干净但单视角观测的侧面点全被剔除。它与max_num_pixels10000构成一组逃生通道后者允许同一物理点合并最多 10000 个像素栏杆、电线这类薄结构正是靠这条通道活过融合。两组推荐值保守组大场景、快速预览window_radius5、window_step1、geom_consistency_max_cost3.0、max_reproj_error2.0、min_num_pixels3激进组近距离扫描、高精度window_radius9、window_step1、geom_consistency_max_cost2.0、max_reproj_error1.5、min_num_pixels8稠密重建翻车现场与修复现场一低纹理区大面积空洞。现象融合的 PLY 在白墙正中缺一块区域内没有任何点。根因NCC 在无纹理区域找不到可靠对应光度项打分平坦而几何项默认 3.0 太松救不回来。修复先确认该区域图像重叠率是否超过 60%不足则补拍足够则用--patch_match_stereo.window_radius 9 --patch_match_stereo.geom_consistency_max_cost 2.0重跑 PatchMatch再融合。修复后可验证原本空洞的白墙出现连续点云覆盖该区域 PLY 点的平均 nview被多少张图观测到从接近 0 升到 5 以上。现场二双壁与悬浮鬼影面。现象墙面前方 1–2 厘米处浮着一层重复表面。根因通常是稀疏模型重投影偏大导致位姿误差max_reproj_error又太松两种深度都过了闸。修复先看incremental_mapper的Mean reprojection error超过 1.5 像素就先重新注册换初始对或剔除模糊帧否则用--stereo_fusion.max_reproj_error 1.0 --stereo_fusion.max_normal_error 5.0收紧。修复后可验证鬼影层消失同区域剩余点的深度分布收窄到 1% 以内不再出现两个分离的深度簇。现场三4K 图像跑 patch_match_stereo 时 CUDA OOM。现象进程中途崩溃部分图像没有写出深度图。根因cache_size默认 32GB同时把多张高分辨率图像的位图、深度图、法线图压在显存和内存里。修复--patch_match_stereo.max_image_size 4000 --patch_match_stereo.cache_size 8。修复后可验证进程完整跑完80 张图像全部产出深度图被max_image_size裁掉的细节如果必须保留就继续压低cache_size换磁盘缓存用时间换完整。碰到参数解释不了的失败先翻 doc/tutorial.rst 和 doc/faq.rst仍然无解就带着 workspace 目录结构和参数打印去项目仓库提 Issue想改算法本身按 CONTRIBUTING.md 走流程——MVS 模块全部集中在 src/colmap/mvs/读完本文你已经摸过它最核心的两个头文件了。留一个立刻能做的挑战同一组照片用window_radius5 和 9 各跑一遍完整管线记录深度估计耗时与融合 PLY 的 nview 分布把截图贴到 Issue 里看看细节和时间到底换出了什么。【免费下载链接】colmapCOLMAP - Structure-from-Motion and Multi-View Stereo项目地址: https://gitcode.com/GitHub_Trending/co/colmap创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表