行业资讯

MVS 学习

发布时间:2026/7/4 22:27:30
MVS 学习 目标理解 MVS 如何在已知相机位姿下恢复稠密几何能使用 COLMAP/OpenMVS 完成稠密重建能用 OpenCV 做双目视差实验并能回答常见面试问题。目录1. MVS 是什么2. MVS 解决什么问题3. MVS 和 SfM、SLAM、NeRF、3DGS 的关系4. MVS 基本输入和输出5. MVS 核心原理6. 极线约束和深度搜索7. 代价体 Cost Volume8. PatchMatch MVS9. 深度图、法线图和融合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 - 深度图 稠密点云 Mesh3.2 MVS 和 SLAMSLAM 偏实时定位和建图MVS 多用于离线高质量稠密重建。3.3 MVS 和 NeRF/3DGSNeRF/3DGS 主要用于新视角合成不一定直接输出干净 mesh。MVS 主要追求显式几何depth maps dense point cloud mesh3DGS 常用 COLMAP 的 SfM 结果不一定需要 MVS。但如果要 mesh、稠密点云或几何监督MVS 会很有用。4. MVS 基本输入和输出4.1 输入MVS 输入通常要求图像之间有足够重叠。相机位姿准确。相机内参准确。图像清晰。场景尽量静态。如果位姿错MVS 很难恢复正确深度。4.2 输出常见输出depth map: 每张参考图上每个像素的深度 normal map: 每个像素对应表面的法线方向 dense point cloud: 多张深度图融合后的稠密点云 mesh: 从点云或深度图重建的表面 textured mesh: 带纹理的 mesh5. MVS 核心原理MVS 的核心假设同一个三维表面点在不同视角中应该有一致的外观。这叫 photo-consistency光度一致性。对于参考图像中的一个像素MVS 会在不同深度假设下把该 3D 点投影到其他视角比较颜色或特征是否一致。流程选参考图像 - 对每个像素假设多个深度 - 投影到邻近视角 - 计算匹配代价 - 选择代价最小的深度 - 空间正则化和一致性检查6. 极线约束和深度搜索对于两张已知相机位姿的图像一个像素在另一张图中的匹配点不需要全图搜索而是在极线上搜索。双目校正后极线通常变成水平线此时匹配问题变成视差搜索disparity x_left - x_right depth fx * baseline / disparity多视图情况下深度假设会投影到多个源视图综合多个视图的匹配代价。7. 代价体 Cost Volume深度估计常构建 cost volumeheight x width x depth_candidates每个位置表示某个像素在某个深度假设下的匹配代价。传统方法可能使用NCC。SAD/SSD。Census transform。Patch matching。深度学习方法可能使用特征提取网络。多视图特征 warping。3D CNN 正则化 cost volume。8. PatchMatch MVSPatchMatch 是 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.bin12.1 图像去畸变colmap image_undistorter\--image_pathimages\--input_pathworkspace/sparse/0\--output_pathworkspace/dense\--output_typeCOLMAP输出workspace/dense/ images/ sparse/ stereo/12.2 PatchMatch Stereocolmap patch_match_stereo\--workspace_pathworkspace/dense\--workspace_formatCOLMAP\--PatchMatchStereo.geom_consistencytrue如果没有 GPUcolmap patch_match_stereo\--workspace_pathworkspace/dense\--workspace_formatCOLMAP\--PatchMatchStereo.geom_consistencytrue\--PatchMatchStereo.gpu_index-112.3 深度融合colmap stereo_fusion\--workspace_pathworkspace/dense\--workspace_formatCOLMAP\--input_typegeometric\--output_pathworkspace/dense/fused.ply12.4 Mesh 重建Poissoncolmap poisson_mesher\--input_pathworkspace/dense/fused.ply\--output_pathworkspace/dense/meshed-poisson.plyDelaunaycolmap delaunay_mesher\--input_pathworkspace/dense\--output_pathworkspace/dense/meshed-delaunay.ply12.5 查看结果可以使用COLMAP GUI。MeshLab。CloudCompare。Blender。查看workspace/dense/fused.ply workspace/dense/meshed-poisson.ply workspace/dense/meshed-delaunay.ply13. 实操二OpenMVS 稠密重建和网格纹理OpenMVS 常用于从 COLMAP 结果继续做稠密点云、mesh 和纹理。13.1 从 COLMAP 转 OpenMVSOpenMVS 提供接口工具例如InterfaceCOLMAP。具体命令随安装方式略有差异常见思路InterfaceCOLMAP\-iworkspace/dense\-oscene.mvs如果你的 OpenMVS 工具路径不同请查看InterfaceCOLMAP--help13.2 稠密点云DensifyPointCloud scene.mvs输出常见scene_dense.mvs scene_dense.ply13.3 重建 MeshReconstructMesh scene_dense.mvs输出常见scene_dense_mesh.mvs scene_dense_mesh.ply13.4 优化 MeshRefineMesh scene_dense_mesh.mvs13.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.pyimportcv2ascvimportnumpyasnpimportopen3daso3ddefmain():leftcv.imread(left.png,cv.IMREAD_GRAYSCALE)rightcv.imread(right.png,cv.IMREAD_GRAYSCALE)colorcv.imread(left.png,cv.IMREAD_COLOR)ifleftisNoneorrightisNoneorcolorisNone:raiseRuntimeError(Please provide left.png and right.png.)stereocv.StereoSGBM_create(minDisparity0,numDisparities128,blockSize5,P18*1*5*5,P232*1*5*5,modecv.STEREO_SGBM_MODE_SGBM_3WAY,)disparitystereo.compute(left,right).astype(np.float32)/16.0fx700.0baseline0.10cxleft.shape[1]/2.0cyleft.shape[0]/2.0validdisparity1.0depthnp.zeros_like(disparity,dtypenp.float32)depth[valid]fx*baseline/disparity[valid]ys,xsnp.where(valid)zdepth[ys,xs]x(xs-cx)*z/fx y(ys-cy)*z/fx pointsnp.stack([x,y,z],axis1)colorscolor[ys,xs][:,::-1]/255.0pcdo3d.geometry.PointCloud()pcd.pointso3d.utility.Vector3dVector(points)pcd.colorso3d.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 是否需要 MVSNeRF 训练通常需要相机位姿不一定需要 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 volumecost 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_mesher或delaunay_mesher生成 mesh。19.15 OpenMVS 常见流程是什么通常从 COLMAP 导入模型执行DensifyPointCloud得到稠密点云ReconstructMesh生成 meshRefineMesh优化 meshTextureMesh生成纹理。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.htmlCOLMAP Tutorialhttps://colmap.github.io/tutorial.htmlCOLMAP Output Formathttps://colmap.github.io/format.htmlOpenMVS 官方仓库https://github.com/cdcseacave/openMVSOpenMVS Wikihttps://github.com/cdcseacave/openMVS/wikiOpenCV StereoSGBM 文档https://docs.opencv.org/4.x/d2/d85/classcv_1_1StereoSGBM.htmlOpenCV reprojectImageTo3D 文档https://docs.opencv.org/4.x/d9/d0c/group__calib3d.htmlMVSNet 论文https://arxiv.org/abs/1804.02505PatchmatchNet 论文https://arxiv.org/abs/2112.01411Multiple View Geometry in Computer VisionHartley Zisserman。