当前位置: 首页 > news >正文

MVS 学习

目标:理解 MVS 如何在已知相机位姿下恢复稠密几何,能使用 COLMAP/OpenMVS 完成稠密重建,能用 OpenCV 做双目视差实验,并能回答常见面试问题。

目录

  • 1. MVS 是什么
  • 2. MVS 解决什么问题
  • 3. MVS 和 SfM、SLAM、NeRF、3DGS 的关系
  • 4. MVS 基本输入和输出
  • 5. MVS 核心原理
  • 6. 极线约束和深度搜索
  • 7. 代价体 Cost Volume
  • 8. PatchMatch MVS
  • 9. 深度图、法线图和融合
  • 10. MVS 常见方法分类
  • 11. 数据采集建议
  • 12. 实操一:COLMAP 稠密重建
  • 13. 实操二:OpenMVS 稠密重建和网格纹理
  • 14. 实操三:OpenCV 双目视差和点云
  • 15. 实操四:检查 MVS 输出质量
  • 16. MVS 在 3DGS/NeRF 工作流中的定位
  • 17. 常用参数和调参经验
  • 18. 常见问题排查
  • 19. 面试常问问题
  • 20. 练习任务
  • 21. 参考资料

1. MVS 是什么

MVS,全称 Multi-View Stereo,多视图立体。

它的目标是:

在已知多张图像的相机内外参后,恢复场景的稠密三维几何。

一句话理解:

SfM 先告诉我们相机在哪里,MVS 再利用这些相机视角,把场景表面恢复得更密。

典型输入:

  • 多张有重叠的图片。
  • 每张图片的相机内参。
  • 每张图片的相机外参。
  • 可选稀疏点云。

典型输出:

  • 每张图片的深度图。
  • 每张图片的法线图。
  • 稠密点云。
  • Mesh。
  • 带纹理 Mesh。

2. MVS 解决什么问题

SfM 输出通常是稀疏点云,只有少量特征点位置。

MVS 想进一步恢复:

每个可见表面位置在哪里? 每个像素对应的深度是多少? 如何把多视图深度融合成稠密点云或 mesh?

应用:

  • 三维重建。
  • 建筑和文物数字化。
  • 无人机测绘。
  • 工业检测。
  • 机器人环境建模。
  • 3D 数据集生成。
  • Mesh 纹理重建。

3. MVS 和 SfM、SLAM、NeRF、3DGS 的关系

3.1 MVS 和 SfM

关系最直接:

SfM: 恢复相机位姿 + 稀疏点云 MVS: 使用 SfM 位姿恢复稠密几何

典型流程:

图片 -> SfM -> 相机参数 + 稀疏点云 -> MVS -> 深度图 + 稠密点云 + Mesh

3.2 MVS 和 SLAM

SLAM 偏实时定位和建图,MVS 多用于离线高质量稠密重建。

3.3 MVS 和 NeRF/3DGS

NeRF/3DGS 主要用于新视角合成,不一定直接输出干净 mesh。

MVS 主要追求显式几何:

depth maps dense point cloud mesh

3DGS 常用 COLMAP 的 SfM 结果,不一定需要 MVS。但如果要 mesh、稠密点云或几何监督,MVS 会很有用。

4. MVS 基本输入和输出

4.1 输入

MVS 输入通常要求:

  • 图像之间有足够重叠。
  • 相机位姿准确。
  • 相机内参准确。
  • 图像清晰。
  • 场景尽量静态。

如果位姿错,MVS 很难恢复正确深度。

4.2 输出

常见输出:

depth map: 每张参考图上每个像素的深度 normal map: 每个像素对应表面的法线方向 dense point cloud: 多张深度图融合后的稠密点云 mesh: 从点云或深度图重建的表面 textured mesh: 带纹理的 mesh

5. MVS 核心原理

MVS 的核心假设:

同一个三维表面点,在不同视角中应该有一致的外观。

这叫 photo-consistency,光度一致性。

对于参考图像中的一个像素,MVS 会在不同深度假设下,把该 3D 点投影到其他视角,比较颜色或特征是否一致。

流程:

选参考图像 -> 对每个像素假设多个深度 -> 投影到邻近视角 -> 计算匹配代价 -> 选择代价最小的深度 -> 空间正则化和一致性检查

6. 极线约束和深度搜索

对于两张已知相机位姿的图像,一个像素在另一张图中的匹配点不需要全图搜索,而是在极线上搜索。

双目校正后,极线通常变成水平线,此时匹配问题变成视差搜索:

disparity = x_left - x_right depth = fx * baseline / disparity

多视图情况下,深度假设会投影到多个源视图,综合多个视图的匹配代价。

7. 代价体 Cost Volume

深度估计常构建 cost volume:

height x width x depth_candidates

每个位置表示:

某个像素在某个深度假设下的匹配代价。

传统方法可能使用:

  • NCC。
  • SAD/SSD。
  • Census transform。
  • Patch matching。

深度学习方法可能使用:

  • 特征提取网络。
  • 多视图特征 warping。
  • 3D CNN 正则化 cost volume。

8. PatchMatch MVS

PatchMatch 是 COLMAP MVS 中非常重要的思想。

核心思想:

随机初始化深度和法线假设, 通过邻域传播和随机搜索,不断改进每个像素的深度/法线。

为什么有效:

  • 相邻像素通常在同一表面上,深度和法线相近。
  • 好的假设可以从邻居传播过来。
  • 随机搜索避免陷入局部差结果。

COLMAP 的patch_match_stereo会为每张图估计深度图和法线图。

9. 深度图、法线图和融合

9.1 深度图

深度图表示每个像素到相机的距离或 z 深度。

9.2 法线图

法线图表示每个像素对应表面的方向。

法线有助于:

  • PatchMatch 平面假设。
  • 几何一致性。
  • 后续融合和网格重建。

9.3 深度融合

每张图都可以生成一张深度图。融合时需要把这些深度图反投影到世界坐标,并做一致性检查。

融合要解决:

  • 同一个表面点被多个视角看到。
  • 深度噪声。
  • 遮挡。
  • 离群点。
  • 重复点。

COLMAP 使用stereo_fusion生成稠密点云。

10. MVS 常见方法分类

10.1 Voxel-based MVS

把空间划成体素,判断哪些体素属于表面。

优点:

  • 几何直观。

缺点:

  • 内存消耗大。
  • 分辨率受体素大小限制。

10.2 Depth-map-based MVS

为每个参考视角估计深度图,再融合。

优点:

  • 工程常用。
  • 可扩展性好。
  • 与图像分辨率对应自然。

COLMAP、OpenMVS 常见流程都和 depth-map-based 思路相关。

10.3 Patch-based MVS

用小面片表示场景表面,例如 PMVS。

10.4 Learning-based MVS

代表:

  • MVSNet。
  • R-MVSNet。
  • CasMVSNet。
  • PatchmatchNet。

特点:

  • 用神经网络学习特征和代价聚合。
  • 对弱纹理和复杂场景可能更鲁棒。
  • 需要训练数据,泛化和显存开销要关注。

11. 数据采集建议

MVS 比 SfM 更依赖密集纹理和稳定光照。

建议:

  • 相邻图片重叠率 70% 左右。
  • 避免运动模糊。
  • 避免强反光、玻璃、水面。
  • 曝光和白平衡稳定。
  • 不要频繁变焦。
  • 尽量拍摄有纹理表面。
  • 对薄结构、多孔结构多拍角度。
  • 避免动态人车。

不利场景:

  • 白墙。
  • 黑色无纹理物体。
  • 透明物体。
  • 镜面金属。
  • 重复纹理。
  • 草、树叶、水面等细碎动态区域。

12. 实操一:COLMAP 稠密重建

这个流程从已完成 SfM 的 COLMAP sparse 模型开始。

目录假设:

project/ images/ workspace/ database.db sparse/ 0/ cameras.bin images.bin points3D.bin

12.1 图像去畸变

colmap image_undistorter\--image_pathimages\--input_pathworkspace/sparse/0\--output_pathworkspace/dense\--output_typeCOLMAP

输出:

workspace/dense/ images/ sparse/ stereo/

12.2 PatchMatch Stereo

colmap patch_match_stereo\--workspace_pathworkspace/dense\--workspace_formatCOLMAP\--PatchMatchStereo.geom_consistencytrue

如果没有 GPU:

colmap patch_match_stereo\--workspace_pathworkspace/dense\--workspace_formatCOLMAP\--PatchMatchStereo.geom_consistencytrue\--PatchMatchStereo.gpu_index-1

12.3 深度融合

colmap stereo_fusion\--workspace_pathworkspace/dense\--workspace_formatCOLMAP\--input_typegeometric\--output_pathworkspace/dense/fused.ply

12.4 Mesh 重建

Poisson:

colmap poisson_mesher\--input_pathworkspace/dense/fused.ply\--output_pathworkspace/dense/meshed-poisson.ply

Delaunay:

colmap delaunay_mesher\--input_pathworkspace/dense\--output_pathworkspace/dense/meshed-delaunay.ply

12.5 查看结果

可以使用:

  • COLMAP GUI。
  • MeshLab。
  • CloudCompare。
  • Blender。

查看:

workspace/dense/fused.ply workspace/dense/meshed-poisson.ply workspace/dense/meshed-delaunay.ply

13. 实操二:OpenMVS 稠密重建和网格纹理

OpenMVS 常用于从 COLMAP 结果继续做稠密点云、mesh 和纹理。

13.1 从 COLMAP 转 OpenMVS

OpenMVS 提供接口工具,例如InterfaceCOLMAP。具体命令随安装方式略有差异,常见思路:

InterfaceCOLMAP\-iworkspace/dense\-oscene.mvs

如果你的 OpenMVS 工具路径不同,请查看:

InterfaceCOLMAP--help

13.2 稠密点云

DensifyPointCloud scene.mvs

输出常见:

scene_dense.mvs scene_dense.ply

13.3 重建 Mesh

ReconstructMesh scene_dense.mvs

输出常见:

scene_dense_mesh.mvs scene_dense_mesh.ply

13.4 优化 Mesh

RefineMesh scene_dense_mesh.mvs

13.5 纹理贴图

TextureMesh scene_dense_mesh_refine.mvs

输出带纹理的 mesh,常见格式包括:

obj mtl texture images

注意:

  • OpenMVS 命令和文件名会随版本和参数变化。
  • 实操时先用--help看当前安装版本的命令参数。

14. 实操三:OpenCV 双目视差和点云

这个实验是双目 stereo,不是完整多视图 MVS,但有助于理解视差、深度和点云。

安装:

pipinstallopencv-python numpy open3d

准备:

left.png right.png

要求:

  • 两张图已经双目校正。
  • 极线大致水平。
  • 已知fx和 baseline。

保存为stereo_depth_demo.py

importcv2ascvimportnumpyasnpimportopen3daso3ddefmain():left=cv.imread("left.png",cv.IMREAD_GRAYSCALE)right=cv.imread("right.png",cv.IMREAD_GRAYSCALE)color=cv.imread("left.png",cv.IMREAD_COLOR)ifleftisNoneorrightisNoneorcolorisNone:raiseRuntimeError("Please provide left.png and right.png.")stereo=cv.StereoSGBM_create(minDisparity=0,numDisparities=128,blockSize=5,P1=8*1*5*5,P2=32*1*5*5,mode=cv.STEREO_SGBM_MODE_SGBM_3WAY,)disparity=stereo.compute(left,right).astype(np.float32)/16.0fx=700.0baseline=0.10cx=left.shape[1]/2.0cy=left.shape[0]/2.0valid=disparity>1.0depth=np.zeros_like(disparity,dtype=np.float32)depth[valid]=fx*baseline/disparity[valid]ys,xs=np.where(valid)z=depth[ys,xs]x=(xs-cx)*z/fx y=(ys-cy)*z/fx points=np.stack([x,y,z],axis=1)colors=color[ys,xs][:,::-1]/255.0pcd=o3d.geometry.PointCloud()pcd.points=o3d.utility.Vector3dVector(points)pcd.colors=o3d.utility.Vector3dVector(colors)o3d.io.write_point_cloud("stereo_points.ply",pcd)print("saved stereo_points.ply")if__name__=="__main__":main()

重点公式:

depth = fx * baseline / disparity

如果 disparity 很小,深度会很大,噪声也会被放大。

15. 实操四:检查 MVS 输出质量

15.1 看稠密点云

用 CloudCompare 或 MeshLab 打开:

fused.ply

重点看:

  • 是否有大片飞点。
  • 主要物体是否完整。
  • 表面是否过厚。
  • 点云密度是否均匀。
  • 是否有明显断裂和空洞。

15.2 看 Mesh

检查:

  • 是否有破洞。
  • 是否有错误连接。
  • 薄结构是否丢失。
  • 反光/透明区域是否异常。
  • 纹理是否错位。

15.3 看深度图

COLMAP dense 目录中会保存 stereo 结果。不同版本文件格式不同,可以用 COLMAP GUI 或工具脚本查看深度图。

深度图异常表现:

  • 大片无效。
  • 边缘毛刺。
  • 平面波浪。
  • 前景背景混合。

16. MVS 在 3DGS/NeRF 工作流中的定位

16.1 3DGS 是否需要 MVS

原始 3DGS 常见流程只需要 SfM 的 sparse 输出:

cameras images points3D

不一定需要 MVS 的 dense 点云。

但 MVS 可以用于:

  • 生成更稠密的几何参考。
  • 检查 SfM 位姿是否可靠。
  • 给其他方法提供深度监督。
  • 提取 mesh 做传统资产。
  • 和 3DGS 结果做几何对比。

16.2 NeRF 是否需要 MVS

NeRF 训练通常需要相机位姿,不一定需要 MVS。MVS 深度可以作为监督或先验,用于加速或约束几何。

16.3 MVS 和 3DGS 的输出差异

对比MVS3DGS
主要输出深度图、稠密点云、mesh高斯点模型、新视角渲染
目标显式几何高质量实时渲染
对纹理依赖高,但优化方式不同
对动态物体敏感也敏感
是否直接 mesh可以默认不是

17. 常用参数和调参经验

17.1 COLMAP PatchMatch 参数

常见关注:

PatchMatchStereo.geom_consistency PatchMatchStereo.window_radius PatchMatchStereo.num_samples PatchMatchStereo.num_iterations PatchMatchStereo.gpu_index

建议:

  • 初学优先使用默认参数。
  • 开启 geometric consistency 通常能减少错误深度。
  • 显存不足时降低图片分辨率或减少并行。

17.2 stereo_fusion 参数

关注:

StereoFusion.min_num_pixels StereoFusion.max_reproj_error StereoFusion.max_depth_error StereoFusion.max_normal_error

直觉:

  • 参数严格:点云更干净,但可能更稀疏。
  • 参数宽松:点云更密,但飞点更多。

具体参数名和默认值建议用:

colmap stereo_fusion-h

查看当前版本。

17.3 图片分辨率

图片越大:

  • 细节更多。
  • 计算更慢。
  • 显存占用更高。

如果只是学习流程,可以先缩小图片。

17.4 视角选择

MVS 不一定用所有图像做源视角。源视角要:

  • 和参考图有足够重叠。
  • 有合适基线。
  • 不要太近,也不要太远。
  • 光照差异不要太大。

18. 常见问题排查

18.1 稠密点云很稀疏

可能原因:

  • SfM 位姿不准。
  • 图片纹理少。
  • 图片重叠不足。
  • PatchMatch 参数太严格。
  • 图像分辨率太低。

处理:

  • 提高图片质量。
  • 增加视角。
  • 检查 SfM 结果。
  • 适当放宽 fusion 参数。

18.2 飞点很多

可能原因:

  • 弱纹理。
  • 反光/透明区域。
  • 动态物体。
  • 位姿误差。
  • fusion 参数太宽松。

处理:

  • 开启几何一致性。
  • 收紧 fusion 参数。
  • 清理动态图片。
  • 删除反光严重区域。

18.3 Mesh 破洞多

可能原因:

  • 点云本身缺失。
  • 视角覆盖不足。
  • 表面弱纹理。
  • 过滤太严格。

处理:

  • 补拍。
  • 放宽融合参数。
  • 使用 Poisson 重建尝试补洞。
  • 用后处理工具修复 mesh。

18.4 纹理错位

可能原因:

  • 相机位姿不准。
  • mesh 几何不准。
  • 图片曝光差异大。
  • 纹理投影选择不合理。

18.5 透明和反光物体重建差

这是 MVS 经典难点。

原因:

  • photo-consistency 假设不成立。
  • 不同视角看到的颜色变化大。
  • 透明物体没有稳定表面纹理。

19. 面试常问问题

19.1 MVS 是什么?

MVS 是 Multi-View Stereo,多视图立体。它在已知多张图像相机内外参的情况下,通过多视图一致性恢复场景的稠密三维几何。

19.2 MVS 和 SfM 有什么区别?

SfM 用特征匹配恢复相机位姿和稀疏点云;MVS 在已知相机位姿基础上恢复稠密深度、稠密点云或 mesh。

19.3 MVS 的输入和输出是什么?

输入是多张图像、相机内参和外参。输出通常是深度图、法线图、稠密点云、mesh 或带纹理 mesh。

19.4 MVS 的核心假设是什么?

核心假设是光度一致性:同一个三维表面点在多个视角下应该具有一致或相近的外观。

19.5 什么是深度图?

深度图表示图像中每个像素对应的三维点到相机的深度。

19.6 什么是法线图?

法线图表示每个像素对应表面的方向,常用于平面假设、几何一致性和融合。

19.7 什么是 cost volume?

cost volume 是一个三维代价空间,记录每个像素在不同深度假设下的匹配代价。

19.8 PatchMatch MVS 的核心思想是什么?

随机初始化深度/法线假设,通过邻域传播和随机搜索不断优化每个像素的深度和法线。

19.9 为什么 MVS 需要已知相机位姿?

因为 MVS 需要把参考图像中的深度假设投影到其他视角比较一致性,如果相机位姿不准,投影位置会错,深度估计也会错。

19.10 MVS 为什么怕弱纹理?

弱纹理区域不同深度下的外观差异不明显,匹配代价难以区分,深度估计容易不稳定。

19.11 MVS 为什么怕反光和透明物体?

因为反光和透明物体在不同视角下外观变化大,不满足光度一致性假设。

19.12 双目视差和深度是什么关系?

校正双目中:

depth = fx * baseline / disparity

视差越大,深度越近;视差越小,深度越远。

19.13 MVS 中如何融合多张深度图?

把每张深度图反投影成 3D 点,再根据多视图几何一致性、深度一致性、法线一致性等条件过滤和合并,得到稠密点云。

19.14 COLMAP 的稠密重建流程是什么?

先用image_undistorter去畸变,再用patch_match_stereo估计深度和法线,最后用stereo_fusion融合成稠密点云,可选poisson_mesherdelaunay_mesher生成 mesh。

19.15 OpenMVS 常见流程是什么?

通常从 COLMAP 导入模型,执行DensifyPointCloud得到稠密点云,ReconstructMesh生成 mesh,RefineMesh优化 mesh,TextureMesh生成纹理。

19.16 MVS 和 3DGS 有什么关系?

MVS 主要输出显式稠密几何;3DGS 主要优化高斯表示用于新视角渲染。3DGS 通常需要 SfM 位姿和稀疏点,不一定需要 MVS,但 MVS 可用于几何参考或深度监督。

19.17 MVS 结果质量怎么看?

看稠密点云覆盖是否完整、飞点是否多、mesh 是否有破洞和错误连接、纹理是否错位、深度图是否平滑且边缘合理。

19.18 MVS 点云飞点多怎么办?

检查 SfM 位姿,开启几何一致性,收紧融合参数,删除动态和反光图片,增加视角覆盖并提高图像质量。

19.19 MVS 和深度学习 MVS 有什么区别?

传统 MVS 通常依赖手工相似性度量和优化策略;深度学习 MVS 使用神经网络提取特征、构建和正则化 cost volume,可能对复杂场景更鲁棒,但需要训练数据和更多显存。

19.20 面试中如何概括 MVS 项目经验?

可以这样回答:

我用 MVS 做过多视角稠密重建。流程是先用 SfM/COLMAP 恢复相机内外参和稀疏点云, 再进行图像去畸变,使用 PatchMatch Stereo 为每张参考图估计深度图和法线图, 然后通过多视图几何一致性把深度图融合成稠密点云,最后可选 Poisson 或 Delaunay 生成 mesh。 排查时我会重点看 SfM 位姿质量、图像重叠和纹理、深度图有效区域、飞点数量和 mesh 破洞情况。

20. 练习任务

20.1 跑通 COLMAP MVS

准备一组图片,先跑 SfM,再执行:

image_undistorter patch_match_stereo stereo_fusion poisson_mesher

查看fused.ply和 mesh。

20.2 比较稀疏和稠密点云

比较:

SfM sparse points3D MVS fused.ply

观察点数量、覆盖范围和噪声差异。

20.3 调整 fusion 参数

尝试更严格和更宽松的 fusion 参数,观察:

  • 点云密度。
  • 飞点数量。
  • 表面完整度。

20.4 OpenCV 双目实验

使用一组校正过的双目图片,运行StereoSGBM,输出视差图和点云。

20.5 OpenMVS 流程

从 COLMAP 模型导入 OpenMVS,依次运行:

InterfaceCOLMAP DensifyPointCloud ReconstructMesh RefineMesh TextureMesh

观察每一步结果变化。

21. 参考资料

  • COLMAP 官方文档:https://colmap.github.io/
  • COLMAP CLI 文档:https://colmap.github.io/cli.html
  • COLMAP Tutorial:https://colmap.github.io/tutorial.html
  • COLMAP Output Format:https://colmap.github.io/format.html
  • OpenMVS 官方仓库:https://github.com/cdcseacave/openMVS
  • OpenMVS Wiki:https://github.com/cdcseacave/openMVS/wiki
  • OpenCV StereoSGBM 文档:https://docs.opencv.org/4.x/d2/d85/classcv_1_1StereoSGBM.html
  • OpenCV reprojectImageTo3D 文档:https://docs.opencv.org/4.x/d9/d0c/group__calib3d.html
  • MVSNet 论文:https://arxiv.org/abs/1804.02505
  • PatchmatchNet 论文:https://arxiv.org/abs/2112.01411
  • Multiple View Geometry in Computer Vision,Hartley & Zisserman。
http://www.jsqmd.com/news/1124433/

相关文章:

  • 如何快速掌握nwpu-cram网络爬虫框架:Scrapy实战入门指南
  • 如何搭建Leela Chess Zero环境?5分钟快速启动你的AI象棋之旅
  • 2026年AI写小说工具深度测评:长文本稳定性与角色一致性实战指南
  • 云计算资源分享与下载
  • 基于LV3296与TM4C1299KCZAD的嵌入式条码扫描系统开发
  • 自考学生必备AI论文写作工具全攻略
  • 如何高效掌握移动应用测试:nwpu-cram的工具与方法指南
  • ICM-42688-P与PIC18F55K42在机器人控制与工业监测中的应用
  • 华北、华南、安徽赛区现场挑战赛
  • 研究生学术写作AI工具全攻略:效率与质量双提升
  • CDGA数据治理证书含金量深度解析:从知识体系到实战价值
  • AI编程中的模型选型方法论:按开发阶段精准匹配模型
  • 3分钟上手Mermaid在线编辑器:零代码制作专业图表的完整指南
  • 约束布局详解
  • 基于YOLOv8的暴力行为检测系统开发实战
  • 2025国内合规大模型实测指南:文心一言、通义千问等备案AI选型建议
  • SVM用户态API设计与工程实践指南
  • 企业本体语义平台-企业大脑的范式跃迁
  • Wireshark自定义协议解析:从proto_item基础到高级实战
  • EditAnything与ComfyUI集成教程:打造专业视频编辑工作流
  • 如何用Python桌面宠物框架DyberPet快速创建你的专属虚拟伙伴:完整教程
  • 2026年15款AI应用实战指南:从自动化到内容创作,重塑工作流
  • 你的华硕笔记本性能被封印了吗?G-Helper一键解锁硬件潜力
  • Chrome DevTools MCP:让AI助手成为你的浏览器调试专家
  • 基于YOLOV8的花卉智能检测系统开发实战
  • 开发者实战验证的16个生产级AI编程Agent选型指南
  • vue 使用 vue-wechat-title 动态设置title
  • 2026年AI论文软件核心能力速览
  • Spectre多因子模型实战:构建Barra风格的风险因子分析系统
  • 3分钟掌握Hidden Word:为你的原创内容穿上隐形防护衣