从MVSNet到PatchMatchNet:深度学习多视图立体重建技术演进解析
2026/9/18 1:28:56 网站建设 项目流程

简介:这份深度学习三维重建笔记系统梳理了MVSNet系列近年的顶刊方法,面向刚接触多视图立体匹配或需要快速回顾论文脉络的研究者与工程师。内容为53页Word文档,压缩包内共1个docx文件,大小约3.75MB,便于离线阅读和标注。笔记先介绍MVS按输出表示可分为直接点云重建、体积重建和深度图重建,再逐篇归纳MVSNet、R-MVSNet、Cascade-MVSNet、P-MVSNet、Fast-MVSNet、CVP-MVSNet、Point-MVSNet和PatchMatchNet等模型,重点对比3D代价体、GRU代替3D CNN、特征金字塔、稀疏代价体、点云表示等设计,并整理单应性变换、平面扫描、深度特征提取、代价累计、深度估计与优化等关键推导和问题总结。全文以提纲加要点形式呈现,适合作为论文精读前的预习纲要、课堂讲义补充或答辩复习材料,能帮助读者快速把握该方向从高内存消耗到高精度、高速度的演进逻辑。已有862人学习,资源价值较明确。

1. 从 MVSNet 到 PatchMatchNet:这条演化线到底解决了什么问题

多视图立体(MVS)的任务是从多张视角重叠的图片恢复出场景的稠密三维结构。传统方法依赖手工设计的匹配代价和几何一致性传播,在弱纹理、重复纹理和大尺度场景下很容易崩掉。2018 年香港科技大学权龙团队提出 MVSNet,第一个把深度学习端到端地引入 MVS 流程,核心是把相机几何嵌入网络——通过可微单应性变换构造 3D cost volume,再让 3D CNN 做正则化、soft argmin 回归深度图。这个思路在当时是颠覆性的,但代价也非常直观:3D 代价体在深度方向上乘一遍 32 通道特征图,显存直接爆炸,根本跑不了高分辨率。后面 R-MVSNet、Cascade-MVSNet、Fast-MVSNet、Point-MVSNet、PatchMatchNet 这一串顶会论文,本质上都在回答同一个问题:如何在保持精度的前提下,把 cost volume 的显存占用量和推理耗时降下去。这份 53 页的笔记把这条演化线按有监督网络串起来,适合两类人:一是刚入门三维重建、想快速建立 MVS 网络发展脉络的同学,二是已经跑过开源代码、想系统对比各家改进动机和实验指标的工程师。读完你应该能说清楚每一篇改进到底改了什么、代价是什么、在 DTU 上提升多少。

2. 经典基线与核心组件拆解:Cost Volume 为什么是 MVSNet 的命门

2.1 从特征提取到代价体构建的标准四步

MVSNet 的流程可以拆成四个阶段,后续几乎所有有监督 MVS 网络都沿用这个骨架。第一步是深度特征提取:输入一张参考图和 N 张源图,各自过一个 8 层 2D CNN(权值共享),输出 32 通道、分辨率降为输入 1/4 的特征图。第二步是可微单应性变换(Differentiable Homography):把源视图特征在假设深度 d 处投影到参考视图的正面平行平面上。第三步是方差代价体构建:在深度维度上堆叠所有视图的 warping 结果,用方差衡量各视图在该深度处的匹配一致性。第四步是 3D 正则化加深度回归:用 U-Net 结构的 3D CNN 对代价体做滤波,softmax 得到深度概率体,再求期望作为回归深度。

# 核心伪代码:可微单应性变换 + 方差代价体 for d in range(D): # D 为深度假设数量 for i in range(N_views): # 遍历源视图 warped[i] = warp(feature[i], homography(d, i)) # 沿视图维度计算方差:方差越小,匹配越一致 cost_volume[:, :, d, :] = variance(warped)

这段代码的逻辑是:对每个假设深度 d,把所有源视图特征通过单应矩阵变换到参考视角,再按视图维度做方差。方差度量的是多视图特征之间的歧义性——如果这个 d 接近真实深度,各个视图变换后的特征应该高度相似,方差趋近于零。方差的好处是对输入视图数量不敏感,任意 N 个视图都能得到固定长度的代价向量。

2.2 论文里那个公式错误和实际代码的偏差

这个坑值得单独说。MVSNet 论文里单应性变换公式被证明是写错的,后面有几篇顶会论文照着公式推导,结果全歪了,但官方代码却是对的。这提醒我们一件事:读 MVS 论文时,公式推导必须以代码为准,尤其是涉及坐标归一化和逆变换的部分。

正确公式的核心在于先把像素坐标归一化到相机内参尺度,再做旋转和平移变换,最后乘上深度和源视角到参考视角的相对位姿。平面扫描原理本质上是在参考相机视锥内,沿着深度方向用一组平行平面去扫描场景,每个平面对应一个假设深度。

2.3 深度回归的损失设计与异常值过滤

MVSNet 把深度估计建模成回归问题,损失用平滑 L1(smooth L1),对离群点更鲁棒。在推理阶段,笔记里提到一个实用技巧:softmax 得到的概率体沿深度维取期望得到深度值,但如果把概率小于 0.8 的像素视为不可靠、直接过滤掉,重建点云质量会明显提升。这是工程上常用的置信度过滤策略。

损失函数使用真实深度图做监督,配合 smooth L1 损失回归深度信息。对于遮挡和弱纹理区域,概率体往往在多个深度上都有响应,soft argmin 会取到均值,导致深度平滑但边缘模糊,这也是后续工作重点改进的地方。

2.4 Xiaoyang Guo 的 PyTorch 版本为什么成了事实标准

笔记里特别提到 Xiaoyang Guo 把 MVSNet 从 TensorFlow 改写成了 PyTorch,这个版本在 DTU 上的精度超过了原论文报告的水平,后续几乎所有的改进工作(Cascade、PatchMatchNet、Point-MVSNet 等)都基于这个代码库。它实际上成了整个 MVS 深度学习社区的事实基线。

# 克隆 MVSNet_pytorch 并训练(典型参数组合) git clone https://github.com/xy-guo/MVSNet_pytorch python train.py --dataset dtu \ --batch_size 1 \ --numdepth 192 \ --interval_scale 2.5 \ --max_w 1600 --max_h 1152

参数说明:numdepth 设为 192 是 MVSNet 在 DTU 数据集上的标准配置,在特征图尺寸上深度采样 192 层;interval_scale 是深度采样间隔系数,DTU 的深度范围约在 425 到 935mm 之间,interval_scale 越大覆盖范围越广但精度越低,2.5 是权衡后的常用取值;max_w 和 max_h 限制输入图的宽高,显存不够时优先降这里。

3. 内存与速度两条优化路线的正面交锋:RNN、级联与稀疏代价体

3.1 内存换时间:GRU 递归正则化的边界在哪

R-MVSNet(CVPR 2019)的出现是因为 MVSNet 的 3D CNN 在深度方向上消耗太多显存。权龙团队的做法是把 3D 正则化替换成沿深度方向的循环神经网络——用一个卷积 GRU 依次处理每一层深度的 2D 代价图,GRU 的隐状态沿着深度方向传递信息。这样 GPU 显存占用从完整的 3D 代价体降到了只需要维护两个 2D 特征图,理论上能处理高分辨率输入。

# R-MVSNet 核心:GRU 沿深度方向迭代正则化 hidden = init_state() # 初始化隐状态 for d in range(D): gate = conv_gru(cost_slice[:, :, d], hidden) hidden = update_hidden(gate, hidden) depth_probs = softmax(hidden)

GRU 门控每个时间步决定让多少历史信息通过,在深度方向上累计上下文。但代价是推理耗时成倍增加——GRU 是串行结构,深度维上的迭代无法并行。笔记里的评价比较中肯:模型小了,但精度相比 MVSNet 反而小有下降。R-MVSNet 把损失从回归改成了多分类问题(交叉熵损失),等于把深度估计当成一个离散分类任务处理,深度的连续性有所丢失。

从实际使用角度看,R-MVSNet 的价值在于证明了一条可行路线:递归代价体确实能省显存、吃下大分辨率输入。但它牺牲了精度又没有显著提升速度,后续主线并没有沿着这个方向走,反而是 Cascade 和 Fast-MVSNet 的稀疏化思路成了主流。

3.2 由粗到细的级联:Cascade-MVSNet 为什么成了新基线

Cascade-MVSNet(CVPR 2020)的思路完全不同。它不去压缩代价体,而是把单一大尺度代价体拆成多个尺度串行预测:先用低分辨率图做粗深度估计,再在粗估计的深度附近做更细的采样和更高分辨率的代价体构建。这样每个阶段的深度假设数量可以控制得很小,显存消耗大幅下降,而且最终深度图是在较高分辨率下预测的,精度反而显著提升。

for stage in [0, 1, 2]: # 级联三阶段 depth_interval[stage] = depth_interval[stage-1] / 2 depth_sample_num = 8 # 每阶段只采样 8 个深度假设 depth_start = coarse_depth - depth_interval * 4 depth_end = coarse_depth + depth_interval * 4

这里的关键参数是每阶段只采样 8 个深度假设,三个阶段的深度范围逐级收紧。第一阶段在整幅图的深度范围内均匀采样,第二阶段以上一阶段的输出深度为中心、缩小深度间隔重新采样,第三阶段再进一步细化。相比 MVSNet 的 192 层采样,每阶段 8 层意味着构建代价体的显存消耗降了一个数量级。

实验数据在笔记里有明确对比:Cascade-MVSNet 在 DTU 数据集上的精度显著优于 MVSNet 和 R-MVSNet,而且显存和时间都有优势。它的另一个贡献是用三维代价体金字塔替换二维特征金字塔,把 MVS 和双目立体匹配统一到了同一个框架下——这也是它同时能解决 stereo matching 任务的原因。Loss 设置上,每个阶段都设置深度真值监督,总 loss 为三阶段 loss 的加权和,权重通常设为 0.5、1.0、2.0,越靠后的细化阶段赋予越高的权重。

3.3 稀疏化路线:Fast-MVSNet 与 CVP-MVSNet 的比较

Fast-MVSNet(CVPR 2020)进一步激进:只在稀疏的关键点位置构建代价体并预测深度,然后用深度传播和 Gauss-Newton 迭代把深度扩散到全图。笔记里给出了它的完整流程:稀疏高分辨率深度图预测、深度图扩展、Gauss-Newton 精细化三个模块。稀疏化让它的运行速度非常快,但代价是边缘区域的深度精度不如密集方法。

CVP-MVSNet(CVPR 2020)则走的是另一条路——cost volume 金字塔。它从粗糙到精细逐步构建代价体,每层预测残差深度,层与层之间用 2D 特征引导上采样。CVP-MVSNet 的精度很高,但推理速度慢,因为它本质上还是密集采样策略,只是把一次大显存卷积拆成了几次小显存卷积。

下面这张表格整理这几条路线的关键差异。

方法核心策略显存占用推理速度DTU 精度(越低越好)
MVSNet单一大 3D cost volume极高0.336
R-MVSNet深度维 GRU 递归正则化很慢0.334
Cascade-MVSNet级联多阶段粗到细0.325
Fast-MVSNet稀疏 cost volume + 扩展很快0.331
CVP-MVSNet代价体金字塔迭代细化0.296

3.4 特征金字塔与 Patch-wise 聚合的两个小分支

P-MVSNet(ICCV 2019)和 PatchMatchNet(CVPR 2021)代表了两条支线。P-MVSNet 的出发点是像素级聚合对遮挡和噪声敏感,改用 patch-wise aggregation——把单像素特征替换为局部 patch 的特征分布,再用可微聚合得到匹配代价。这相当于在代价计算环节引入上下文信息,对纹理重复区域的歧义性有抑制作用。

PatchMatchNet 则把传统 PatchMatch 算法的核心思想——随机初始化深度假设加空间传播加随机扰动——端到端地嵌入到深度网络里。它在每个尺度上用自适应传播代替固定窗口卷积,在代价聚合上用自适应空间代价聚合(adaptive spatial cost aggregation)替代 3D CNN 的大感受野正则化,显存和时间都大幅下降。PatchMatchNet 在 ETH3D Benchmark 上的表现尤其突出,因为 ETH3D 的场景是室内外小场景,深噪声多,而 PatchMatch 的传播机制天然适合多峰分布。

4. 放弃体素:Point-MVSNet 和点云路线带来的范式转移

4.1 为什么 3D Cost Volume 本质上是一种浪费

前面提到的方法再怎么优化,都没有脱离一个基本框架:在规则网格上枚举深度、构建 3D 代价体、用卷积正则化。Point-MVSNet(ICCV 2019)质疑了这种表示本身——空间大部分区域是空的,只有表面附近才有几何信息。在规则体素上做卷积,等于在大量空区域白白消耗计算量和显存。

Point-MVSNet 的做法很直接:先用一个粗网络生成初始深度图,把每个像素反投影成一个 3D 点,得到一个初始点云,然后在点云上用 PointNet++ 架构迭代优化点的位置(也就是修正深度值)。2D 图像特征和 3D 点坐标融合后,通过边缘卷积(edge convolution)在局部邻域内聚合特征,预测每个点的深度残差。

4.2 2D-3D 特征融合的两种做法

笔记里把 2D-3D 特征融合拆成了两个层面。第一个是多尺度图像特征与坐标信息融合:用 FPN(Feature Pyramid Network)提取不同感受野的图像特征,对每个 3D 点取其投影到各层特征图上的像素特征,拼接后作为点的初始特征。第二个是假设点生成:在初始深度图基础上,沿视线方向按一定间隔生成多个候选点,候选点的数量决定了优化空间的密度。

# Point-MVSNet 可微反投影:像素坐标 -> 3D 点 def unproject(pixel_coords, depth, cam_K, cam_R, cam_t): # 1. 像素坐标 -> 相机归一化坐标 pts_cam = cam_K_inv @ pixel_coords # 2. 乘深度 -> 相机坐标系下的 3D 点 pts_cam *= depth.unsqueeze(-1) # 3. 旋转平移 -> 世界坐标系 pts_world = cam_R.T @ (pts_cam - cam_t) return pts_world

这个反投影过程必须在深度网络中保持可微,因为点云坐标更新要靠梯度反传来修正。边缘卷积在这里起的作用是:对每个点取其 K 近邻,计算邻域内点与中心点的特征差异,再把差异和原特征拼接起来通过 MLP,显式建模局部几何拓扑关系,这与 3D CNN 在规则体素上的作用类似。

4.3 Point-MVSNet 的局限与分支去向

Point-MVSNet 在 DTU 上的实验数据表明,它的重建完整性和精度都优于 MVSNet,细节表现更细腻。但它的缺陷在于点云密度受初始深度图限制,迭代优化如果收敛到一个错误的局部极小值,后续的残差预测很难拉回来。另外,PointNet++ 架构的采样组网过程耗时较长,推理速度并不比 Cascade-MVSNet 快多少。这条路线后续延伸到了 Vis-MVSNet(BMVC 2020)等工作中,但主流的精度提升仍然以级联代价体为主。

5. 消融实验、损失函数与工程复现的九个关键细节

5.1 从 MVSNet 到 Cascade,损失函数怎么变

MVSNet 原始版本用的是类回归损失加 smooth L1,R-MVSNet 改成深度方向上的多分类交叉熵。到了 Cascade-MVSNet,每一级都有自己的深度真值和损失权重,三阶段加权求和。PatchMatchNet 又回到回归损失,但只在有效深度范围内计算 loss,超出范围的像素直接忽略。这里要提醒的是,从分类改回回归不是简单的形式变化——分类损失对深度概率分布的形状更敏感,能让网络输出更尖锐的概率体;回归损失则容忍多峰分布,配合 soft argmin 取期望时深度会更平滑,在或者边界区域往往表现更好。

5.2 DTU 数据集的评估协议与好结果是怎么刷出来的

DTU 数据集包含 124 个场景、每个场景 49 到 64 个视点、7 种光照条件,官方划分 79 个场景做训练、剩下 45 个做评估。评估指标用的是 accuracy(精度,衡量重建点到真实表面的距离)和 completeness(完整性,衡量真实表面到重建点的距离),两者越接近越好。笔记里特别提到一个现象:官方对比结果里,很多论文报的 DTU 数值是挑过评估协议的——有的只评估 7 号光照,有的去掉了边缘区域的点再做评估。做对比实验时,务必确认对方用的评估配置是否和你一致。

5.3 训练时显存不足的实战处理顺序

很多人在校数据集上复现的时候第一步就挂在显存上。我在实际复现中的处理顺序是:

# 1. 先确认深度采样方式,MVSNet 每 batch 只有 1 张参考图 # 2. 降 numdepth:从 192 降到 128,精度损失约 0.005 # 3. 降输入分辨率:max_w/h 从 1600/1152 降到 1280/960 # 4. 改 batch_size,同时用梯度累积模拟更大 batch # 最后才考虑改网络结构:3D UNet 改成轻量版

显存优化的顺序很重要。很多人一上来就改网络结构换上轻量化 3D 卷积,结果精度掉了不少,却没想到 numdepth 从 192 降到 128 的代价更小。调参过程中,每改一个参数都要在验证集上做一次精度记录,不能只盯显存数值。

5.4 深度图融合中的置信度过滤技巧

无论是 MVSNet 还是 Cascade 输出的深度图,直接融合成点云都会带大量外点。笔记里提到基于概率体过滤的方法,以及光度和几何一致性检查。实际工程里常用的组合是:概率小于 0.3 的点直接丢弃,光度和几何一致性误差大于某个阈值的点丢弃,最后再做一次左右一致性检查(对参考图和源图分别预测深度,验证互相投影的距离误差小于 1 像素)。

# 深度图融合前的置信度过滤 mask = (prob > 0.3) & \ (photometric_consistency < 1.5) & \ (geometric_consistency < 2.0) valid_depth = depth * mask

5.5 记一条工程经验:用 Tanks & Temples 验证泛化性

DTU 是室内小场景数据集,在它上面刷出来的指标到了室外大场景可能全线崩溃。Tanks & Temples 是专门测试泛化性的 benchmark,它有 Intermediate 和 Advanced 两组,场景包括室外雕塑、室内房间、复杂光照条件。笔记里提到,MVSNet 的模型直接拿到 Tanks & Temples 上跑,F-score 会明显下降,而 Cascade-MVSNet 因为深度假设范围自适应调整,泛化性强不少。PatchMatchNet 在 ETH3D 上表现也很突出,这说明传统 PatchMatch 算法里的传播策略确实给深度网络带来了更强的多场景适应性。

从阅读路径来看,我建议你的学习顺序是:先读懂 MVSNet 的可微单应性变换和方差代价体,这决定了你对 MVS 的核心理解;然后看 Cascade-MVSNet 怎么用级联深度假设解决显存和精度问题,这是目前最实用的工程基线;再读 PatchMatchNet 融进传统算法,理解传播机制和自适应聚合带来的收益;最后回过头去读 Point-MVSNet 的点云路线,理解所谓 3D 监督与 2D 监督在 MVS 场景下各自的边界。

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询