
简介这份深度学习三维重建笔记系统梳理了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 把深度估计建模成回归问题损失用平滑 L1smooth 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-MVSNetCVPR 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-MVSNetCVPR 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-MVSNetCVPR 2020进一步激进只在稀疏的关键点位置构建代价体并预测深度然后用深度传播和 Gauss-Newton 迭代把深度扩散到全图。笔记里给出了它的完整流程稀疏高分辨率深度图预测、深度图扩展、Gauss-Newton 精细化三个模块。稀疏化让它的运行速度非常快但代价是边缘区域的深度精度不如密集方法。CVP-MVSNetCVPR 2020则走的是另一条路——cost volume 金字塔。它从粗糙到精细逐步构建代价体每层预测残差深度层与层之间用 2D 特征引导上采样。CVP-MVSNet 的精度很高但推理速度慢因为它本质上还是密集采样策略只是把一次大显存卷积拆成了几次小显存卷积。下面这张表格整理这几条路线的关键差异。方法核心策略显存占用推理速度DTU 精度越低越好MVSNet单一大 3D cost volume极高慢0.336R-MVSNet深度维 GRU 递归正则化低很慢0.334Cascade-MVSNet级联多阶段粗到细低快0.325Fast-MVSNet稀疏 cost volume 扩展低很快0.331CVP-MVSNet代价体金字塔迭代细化中慢0.2963.4 特征金字塔与 Patch-wise 聚合的两个小分支P-MVSNetICCV 2019和 PatchMatchNetCVPR 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-MVSNetICCV 2019质疑了这种表示本身——空间大部分区域是空的只有表面附近才有几何信息。在规则体素上做卷积等于在大量空区域白白消耗计算量和显存。Point-MVSNet 的做法很直接先用一个粗网络生成初始深度图把每个像素反投影成一个 3D 点得到一个初始点云然后在点云上用 PointNet 架构迭代优化点的位置也就是修正深度值。2D 图像特征和 3D 点坐标融合后通过边缘卷积edge convolution在局部邻域内聚合特征预测每个点的深度残差。4.2 2D-3D 特征融合的两种做法笔记里把 2D-3D 特征融合拆成了两个层面。第一个是多尺度图像特征与坐标信息融合用 FPNFeature 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-MVSNetBMVC 2020等工作中但主流的精度提升仍然以级联代价体为主。5. 消融实验、损失函数与工程复现的九个关键细节5.1 从 MVSNet 到 Cascade损失函数怎么变MVSNet 原始版本用的是类回归损失加 smooth L1R-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 * mask5.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 场景下各自的边界。本文还有配套的精品资源点击获取