A378-MVSA模型的顶刊创新项目
1、关于数据
MVSSynth 是一个电脑生成的虚拟数据集,类似于用游戏引擎(比如《GTA V》)创建的虚拟场景。它包含了很多照片、深度信息和相机位置信息,专门用来帮助计算机学习如何从照片中推测物体离相机的距离(深度估计)。这个数据集就像一个虚拟世界,里面有100张照片(PNG格式),每张照片对应一个深度图(EXR格式)和一个描述相机位置的文件(JSON格式)。
为什么用虚拟数据?
-
虚拟数据可以精确地知道每个物体的距离(深度)和相机的位置,现实世界的数据采集可能会出错或不完整。
-
就像玩游戏时,电脑知道场景中每个物体的位置,MVSSynth 提供了类似的“完美答案”,让模型学习更准确。



数据集的三大组成部分(对应 images、depths 和 poses 文件夹):
-
照片(PNG文件,images文件夹):
-
100张彩色照片,每张分辨率为810x540(宽x高)。
-
这些照片就像你在游戏中看到的画面,记录了虚拟场景的模样(比如房子、街道等)。
-
每张照片是一个“视角”,就像你在不同位置用相机拍下的场景。
-
深度图(EXR文件,depths文件夹):
-
100个EXR文件,每个对应一张照片。
-
深度图就像一张黑白地图,告诉你照片中每个点(像素)离相机的距离。离得近的地方颜色浅,离得远的地方颜色深。
-
EXR格式是一种特殊的图片格式,能保存非常精确的距离数据(不像普通PNG图片只能存颜色),还能标记“天空”这种没有具体距离的地方(用无穷大表示)。
-
相机信息(JSON文件,poses文件夹):
-
100个JSON文件,每个对应一张照片,记录了相机在虚拟世界中的位置和设置。
-
想象你在玩游戏,拿着一个虚拟相机拍照,JSON文件告诉你:
-
相机在哪个位置(比如在房间的哪个角落)。
-
相机朝哪个方向(比如朝向桌子还是窗户)。
-
相机的“镜头参数”(比如镜头有多宽,中心点在哪里)。
-
JSON文件内容简单解释:
json
-
c_x 和 c_y:
-
告诉我们相机的“镜头中心”在照片上的位置。c_x=480(接近810的一半),c_y=270(540的一半),说明镜头中心在照片中间。
-
这就像相机对准画面的哪个点,决定了照片的中心在哪里。
-
f_x 和 f_y:
-
表示镜头有多“宽”或“窄”,决定相机能看到多大的范围。
-
f_x 和 f_y 接近(约579),说明镜头在横向和纵向的视野差不多,拍出来的照片不会变形。
-
extrinsic:
-
是一个4x4的表格(矩阵),描述相机在虚拟世界中的位置和朝向。
-
前3x3部分(左上角)告诉我们相机朝向哪个方向(比如朝前、朝左还是朝上)。
-
右边一列(-5343, 955, -16475)是相机的位置坐标,相当于在虚拟世界的x、y、z坐标(单位可能是毫米,数值大是因为虚拟场景可能很大)。
-
最后一行 [0, 0, 0, 1] 是数学上的固定格式,确保计算正确。
数据组织方式:
-
这100张照片、深度图和JSON文件属于同一个场景(比如一个虚拟房间,场景ID可能是“0105”)。
-
模型不单独看一张照片,而是把几张照片(比如8张)组合成一个“元组”(tuple),包括一张主照片(参考帧)和几张辅助照片(源帧)。这些照片是从不同角度拍同一个场景,元组信息记录在 train_tuples.txt 文件中,比如:
-
text
-
模型如何利用这些数据进行训练?
mvsanywhere 模型的目标是看几张照片(一个元组),然后猜出主照片中每个点离相机的距离(生成深度图)。它通过训练学习如何利用多张照片的视角差异和相机信息来推测深度。以下是通俗的训练过程:
(1) 数据输入:模型拿到什么?
每次训练,模型从 MVSSynthDataset 获取一个数据样本(元组),包含:
-
主照片和辅助照片:一张主照片(RGB)和7张辅助照片(默认8个视图),每张照片是512x384像素(调整后的分辨率)。
-
深度图:主照片对应的深度图(EXR文件加载后调整为256x192),告诉模型每个像素的真实距离(答案)。
-
相机信息:
-
镜头参数(从JSON的 c_x, c_y, f_x, f_y 计算,调整到512x384分辨率)。
-
相机位置和朝向(从JSON的 extrinsic,描述主照片和辅助照片的相机位置)。
-
有效性掩码:标记深度图中哪些地方是有效的(比如天空区域无效,标记为NaN)。
类比:想象你在拼一个3D拼图,模型拿到:
-
8张不同角度的照片(像从不同位置看一个房间)。
-
一张“答案图”(深度图),告诉你房间里每个物体离相机的距离。
-
相机信息,告诉你每张照片是从哪里、怎么拍的。
(2) 模型怎么处理这些数据?
模型(mvsanywhere)像一个聪明的侦探,通过以下步骤学习推测深度:
-
看照片的特征:
-
模型先分析主照片和辅助照片,找出每张照片里的关键特征(比如桌子边、墙角等)。
-
它用一个“图像编码器”(image_encoder_name=efficientnet)把照片变成一堆数字(特征),方便比较。
-
比较不同视角:
-
模型知道每张照片的相机位置(JSON中的 extrinsic),它把辅助照片的特征“投影”到主照片的视角,比较它们之间的相似性。
-
比如,桌子在主照片中是一个角度,在辅助照片中是另一个角度,模型通过相机位置把这些角度对齐,计算桌子在不同照片中的一致性。
-
猜深度:
-
模型根据照片的相似性和相机信息,猜测主照片中每个点离相机的距离,生成一张“预测深度图”。
-
这张预测深度图就像模型的“作业”,会跟真实的深度图(EXR文件)对比。
-
计算错误(损失函数):
-
模型用损失函数(losses.py 中的 MSGradientLoss, ScaleInvariantLoss 等)检查预测深度图和真实深度图的差距:
-
差距有多大:预测的距离和真实距离差多少(类似“猜错了多少米”)。
-
形状是否正确:物体的边缘、坡度是否跟真实的一样。
-
多视角一致性:从不同角度推测的深度是否吻合。
-
-
比如,ScaleInvariantLoss 关注整体形状是否正确,即使距离数值有缩放也算对。
-
调整模型:
-
模型根据错误调整自己的“猜测方法”(通过优化器更新参数),下次猜得更准。
-
训练会重复很多次(默认220,000步,max_steps),每次用一个新的元组,直到模型学会准确推测深度。
类比:模型像一个学生,老师(深度图)给它答案,告诉它哪里猜错了。学生通过不断练习(看不同元组的照片),学会从照片和相机信息推测距离。
2、模型结构
1. 主入口结构
主模型文件中:
-
get_model_class:根据
opts.model_type返回要用的模型类(目前只支持DepthModel)。 -
load_model_inference:加载推理用模型,支持从 checkpoint 加载;如果 cost volume 属于
CostVolumeManager/FeatureVolumeManager/ViewAgnosticFeatureVolumeManager,会转成更快的版本(调用.to_fast())。 -
load_model_training:加载训练用模型,可以选择完整加载或 lazy-load(逐个参数匹配加载)。
所以核心就是 DepthModel,它内部会组织特征提取、体积构建和解码。
2. 成本体积(Cost Volume)模块
这是 MVS 的核心。共有三种实现:
-
CostVolumeManager(
cost_volume.py) 标准的基于 dot product 的 cost volume。 流程:生成深度平面 → 将源特征 warp 到参考视角 → 与参考特征做点积 → 累积得到体积 -
FeatureVolumeManager(
feature_volume.py) 在标准 cost volume 的基础上,引入 MLP 来处理特征 + metadata(深度、射线方向、位姿差等),得到更鲁棒的体积 -
特点:利用
pose_distance、射线角度、掩码等多种信息。 -
输出:经过 MLP 压缩的体积。
-
ViewAgnosticFeatureVolumeManager(
view_agnostic_feature_volume.py) 类似FeatureVolumeManager,但更 视角无关,减少对源视角数量的依赖,输入的 metadata 精简后通过 MLP 计算匹配分数
这些类都继承自 CostVolumeManager,因此共享 深度平面生成、特征投影/反投影 的逻辑。
3. 特征提取网络
多种 backbone:
-
DINOv2 Transformer(
vit_modules.py)DINOv2类封装了 Facebook Research 的预训练 DINOv2 ViT 模型,作为强大的图像特征提取器 -
ResNet / CNN(
networks.py、networks_fast.py) 定义了 ResNet encoder、MLP、DepthDecoderPP 等,用于特征下采样、cost volume 融合和解码 -
layers.py 定义了一些基础组件:
BasicBlock(残差块)、TensorFormatter(处理多深度维度张量)等
4. 深度解码器
-
depth_anything_blocks.py 定义了
DPTHead,一个 Transformer 风格的解码器,融合不同尺度的特征后预测深度图 -
networks.py / networks_fast.py 中定义了 DepthDecoderPP(进阶 U-Net 解码器)和 SkipDecoder(跳跃连接解码器)
解码器的作用:把 cost volume 或融合后的特征逐步上采样,得到不同尺度的深度预测。
5. 训练与推理流程
-
训练:
-
特征提取(DINOv2 / ResNet 等)
-
构建 cost/feature volume
-
解码得到多尺度深度预测
-
计算监督损失(在
DepthModel内实现,虽然文件没上传,但从引用推测)。 -
推理:
-
加载 checkpoint
-
可选择更快的
to_fast()cost volume -
设置预测尺度(
set_prediction_scale) -
前向计算输出深度。
6. 模型的模块化设计
整体上,mvsanywhere 把 MVS 分解成几个可替换的模块:
-
特征提取器(ResNet / DINOv2 / ViT)
-
体积构建器(CostVolumeManager / FeatureVolumeManager / ViewAgnosticFeatureVolumeManager)
-
解码器(SkipDecoder / DepthDecoderPP / DPTHead)
-
包装模型类(DepthModel)
这种模块化让实验时可以方便地更换 backbone 或 cost volume。
👉 总结来说: 主代码相当于一个 入口调度器,真正的核心逻辑分散在:
-
cost_volume.py&feature_volume.py&view_agnostic_feature_volume.py→ 体积构建 -
networks.py&networks_fast.py&depth_anything_blocks.py&layers.py→ 特征提取 & 解码器 -
vit_modules.py→ ViT 特征提取
最终由 DepthModel 组合成一个端到端的 MVS 深度估计模型。