- 计算机视觉
- 深度学习
【免费下载链接】DAIN
Depth-Aware Video Frame Interpolation (CVPR 2019)
本篇以 MegaDepth 官方仓库说明(MegaDepth/README.md)为主体,结合其源码(Hourglass 网络、评测脚本与数据加载器)深入展开。你将掌握:如何用 MegaDepth 预训练模型对任意互联网照片做单目深度预测,如何在 MegaDepth V1 测试集上复现尺度不变 RMSE(si-RMSE)与 Structure from Motion Disagreement Rate(SDR)两项评测指标,并理解背后的实现细节与参数含义。
一、项目背景:MegaDepth 与它在 DAIN 仓库中的位置
MegaDepth 是发表于 CVPR 2018 的工作"MegaDepth: Learning Single-View Depth Prediction from Internet Photos"(作者 Zhengqi Li 与 Noah Snavely),核心目标是仅凭一张 RGB 照片预测出该场景的单目深度。它从互联网照片中挖掘大规模训练数据,让模型在完全陌生的场景上也具备可观的泛化能力。
仓库中的实现代码骨架基于pytorch-CycleGAN-and-pix2pix演化而来,因而保留了其options / data / models / util四段式目录结构。如果你在学术工作中使用其代码或模型,README 给出了标准引用格式:
@inproceedings{MDLi18, title={MegaDepth: Learning Single-View Depth Prediction from Internet Photos}, author={Zhengqi Li and Noah Snavely}, booktitle={Computer Vision and Pattern Recognition (CVPR)}, year={2018} }为什么 MegaDepth 会出现在 DAIN(Depth-Aware Video Frame Interpolation)仓库中?从源码可以找到直接证据:DAIN 主网络的构造代码 networks/DAIN.py 中,depthNet正是通过MegaDepth.__dict__'HourGlass'实例化的:
if self.training: self.depthNet=MegaDepth.__dict__'HourGlass' else: self.depthNet=MegaDepth.__dict__['HourGlass']()也就是说,MegaDepth 预训练模型在 DAIN 训练阶段作为深度先验提取器被复用,其权重文件必须放在MegaDepth/checkpoints/test_local/best_generalization_net_G.pth。理解这份 README 的推理与评测流程,也是理解 DAIN 深度感知机制的第一步。
二、依赖与环境要求
README 明确说明,MegaDepth 的代码最初基于PyTorch 0.2 + Python 2.7编写,但“可以轻松适配 Python 3 和更新的 PyTorch 版本”。结合当前仓库实际,还有两点需要留意:
- 运行前需为 Python 安装skimage与h5py库:前者用于图像读取与
resize,后者用于读取数据集中的深度 HDF5 文件(证据见 MegaDepth/data/image_folder.py 的导入语句)。 - 在 DAIN 仓库语境下,MegaDepth 模型随主项目跑在 PyTorch 1.0.0 环境中(见仓库根 README.md 的依赖说明),因此实际使用中按新版 PyTorch 适配即可;
MegaDepth_model.py与各模型文件使用的是标准nn.Module/nn.SequentialAPI,迁移成本很低。
三、对任意互联网照片做单目深度预测(推理实战)
README 给出了端到端的推理路径,核心步骤有三步:
- 下载预训练权重:从项目官网获取
best_generalization_net_G.pth(下载地址详见原 README),放置到checkpoints/test_local/best_generalization_net_G.pth。该文件名不是随意命名的——MegaDepth/models/base_model.py 中的load_network按'%s_net_%s.pth' % (epoch_label, network_label)拼装文件名,即best_generalization_net_G.pth对应epoch_label='best_generalization'、network_label='G'。 - 修改加载逻辑:按 README 指引,在 MegaDepth/models/HG_model.py 的
init函数中改为:model_parameters = self.load_network(model, 'G', 'best_generalization')需要说明的是,当前仓库快照中的
HGModel.__init__已重构为通过pretrained路径参数直接torch.load加载权重(见 HG_model.py),且对DataParallel保存权重中常见的module.前缀做了k[7:]剥离处理。两种方式指向同一份权重文件,原理等价。 - 运行推理脚本:
python demo.py输出为一张逆深度图
demo.png(由输入图demo.jpg预测得到)。注意:当前仓库快照并未包含demo.py,运行前需从 MegaDepth 原项目获取该脚本;而加载权重、前向推理的核心逻辑(HourGlass工厂函数)位于 MegaDepth/MegaDepth_model.py。
3.1 关于 RGB 可视化与天空区域的说明
README 特别指出:如果希望像论文配图那样用RGB 颜色映射来可视化深度,需要先借助语义分割把天空区域 mask 掉——原因是天空区域的逆深度预测往往不一致,若不处理会导致 RGB 可视化不合理。具体做法是安装/运行基于 ADE20K 训练的pspnet-pytorch(Kazuto1011 的开源实现)对天空做分割掩膜。这一提示直接关系到预测结果的可视化质量,属于实践中的关键细节。
3.2 源码级补充:Hourglass 深度网络的构成
从 MegaDepth/pytorch_DIW_scratch.py 可以看到,深度网络是一个以nn.Sequential组织的大型Hourglass(沙漏)结构:
- 输入层:
Conv2d(3, 128, 7×7)+ BatchNorm + ReLU; - 主干:多级下采样(
MaxPool2d/AvgPool2d2×2)与多分支空洞卷积(3×3、5×5、7×7、11×11 等核),各分支通过LambdaReduce做torch.cat通道拼接; - 上采样:
UpsamplingNearest2d(scale_factor=2)逐级恢复分辨率,配合逐元素相加(CAddTable)形成沙漏的对称结构; - 输出层:
Conv2d(64, 1, 3×3),输出单通道预测。
模型封装入口为MegaDepth_model.py中的HourGlass(pretrained=None):它通过TrainOptions().parse()解析参数、调用create_model(opt, pretrained)构造HGModel,最终返回model.netG(真正的nn.Module)。DAIN 训练时正是通过该工厂函数注入预训练权重的。
四、在 MegaDepth 测试集上复现评测
MegaDepth 测试评估包含两项指标:尺度不变 RMSE(si-RMSE)与Structure from Motion Disagreement Rate(SDR)。前置准备如下:
- 从项目官网下载MegaDepth V1数据集;
- 下载针对 MegaDepth 数据集训练的模型
best_vanila_net_G.pth,同样放入checkpoints/test_local/; - 下载测试列表
test_lists.tar.gz,解压后应包含横向(landscape)与纵向(portrait)两个文件夹; - (若用于 DAIN 训练)按仓库根 README.md 的说明,将
best_generalization_net_G.pth下载至MegaDepth/checkpoints/test_local/。
4.1 尺度不变 RMSE(si-RMSE)评测
修改 MegaDepth/rmse_error_main.py 中的路径变量后运行:
python rmse_error_main.py需要修改的变量及其默认值:
| 变量 | 默认值(示例) | 含义 |
|---|---|---|
dataset_root | "/phoenix/S6/zl548/" | MegaDepth_v1 数据集的根目录 |
test_list_dir_l | '.../test_list/landscape/' | 横向(landscape)测试列表目录 |
test_list_dir_p | '.../test_list/portrait/' | 纵向(portrait)测试列表目录 |
input_height/input_width | landscape 用240×320,portrait 用320×240 | 测试输入分辨率,与图片方向对应 |
脚本流程(与源码对应):CreateDataLoader(见 MegaDepth/data/data_loader.py,实际为AlignedDataLoader,batch_size=16、num_workers=3)加载数据 →create_model(opt)构造模型 → 逐个 batch 调用model.evaluate_sc_inv(),最终打印 landscape、portrait 与平均 si-RMSE。
尺度不变 RMSE 的实现在 MegaDepth/models/HG_model.py:
def rmse_Loss(self, log_prediction_d, mask, log_gt): N = torch.sum(mask) log_d_diff = log_prediction_d - log_gt log_d_diff = torch.mul(log_d_diff, mask) s1 = torch.sum( torch.pow(log_d_diff,2) )/N s2 = torch.pow(torch.sum(log_d_diff),2)/(N*N) data_loss = s1 - s2 data_loss = torch.sqrt(data_loss) return data_loss即对对数空间的预测深度与真值求差,用s1 - s2减去全局尺度偏移项,再开平方——这正是"尺度不变"的含义:评测时允许整体深度存在一个全局缩放因子,仍能正确度量相对深度结构的误差。预测会先经过torch.exp还原深度值,且只在mask覆盖的有效像素上统计。
4.2 Structure from Motion Disagreement Rate(SDR)评测
修改路径变量后运行:
python SDR_compute.py⚠️ 注意:README 中该句将变量说明写为rmse_error_main.py,但仓库中 SDR 的实际评测入口是 MegaDepth/SDR_compute.py,实际操作时需在该文件内同步修改dataset_root与两个test_list_dir(其中test_list_dir_l = dataset_root + '/MegaDpeth_code/test_list/landscape/')。
SDR 的核心思想:利用 SfM(Structure from Motion)重建出的稀疏特征点对及其顺序约束(哪个点离相机更近)作为弱监督真值,来检验预测深度是否违反这些约束。实现路径如下:
- 数据加载:
CreateDataLoader_TEST(batch_size=1)使用 MegaDepth/data/image_folder.py 的ImageFolder_TEST,从sparse_features/<folder>/<img>.h5读取/SfM_features,其前四行分别是归一化的y_A, x_A, y_B, x_B坐标,第五行为顺序标签ord_;无特征文件的图像会被标记has_SfM_feature = False并跳过。 - 深度采样:
computeSDR(HG_model.py)对预测深度图用torch.index_select+torch.gather在特征点坐标处采样出两个深度值z_A、z_B,再取torch.exp还原。 - 分类判定:
batch_classify(HG_model.py)计算深度比z_A / z_B,以阈值 1.1判定远近关系——大于 1.1 记为 +1(更近),小于 1/1.1 记为 -1,否则视为相等;再与真值比较,分别累计Equal(等距)、Unequal(不等距)与Total三类错误率。 - 汇总输出:脚本最终打印
Equal SDR、Unequal SDR与总体SDR三项指标(SDR_compute.py)。
4.3 数据加载细节(评测的底层支撑)
无论哪项评测,测试列表都由imgs_MD.p(图像路径列表)与targets_MD.p(深度/HDF5 路径列表)两个 pickle 文件提供(image_folder.py)。RMSE 评测中深度真值从 HDF5 的/depth键读取,并经过 1%/98% 分位数截断、最大值归一化与最近邻 resize 生成 mask(gt > 1e-8);__getitem__会把无效深度像素置为 1.0,保证torch.log运算稳定(image_folder.py)。
五、评测脚本涉及的命令行参数
评测脚本入口都执行TrainOptions().parse()(在导入 torch 之前设置CUDA_VISIBLE_DEVICES),因此以下参数均会影响运行环境与模型构造。核心参数默认值整理如下(来源:MegaDepth/options/base_options.py、MegaDepth/options/train_options.py):
| 参数 | 默认值 | 说明 |
|---|---|---|
--gpu_ids | '0,1' | 使用的 GPU 编号,评测时建议设为单个 GPU |
--name | 'test_local' | 实验名,决定权重读取目录checkpoints_dir/name/ |
--checkpoints_dir | './checkpoints/' | 权重根目录,与best_generalization_net_G.pth的存放位置直接相关 |
--model | 'pix2pix' | 模型选择,create_model实际固定构造HGModel |
--batchSize | 1 | 输入 batch 大小 |
--loadSize | 286 | 图像缩放尺寸 |
--fineSize | 256 | 裁剪尺寸 |
--input_nc/--output_nc | 3 | 输入/输出通道数 |
--norm | 'instance' | 归一化方式 |
--phase | 'train' | 数据阶段,评测可覆写 |
--which_epoch | 'latest' | 加载哪个 epoch 的权重 |
--lr/--beta1 | 0.0002/0.5 | Adam 优化器参数(训练用) |
--niter/--niter_decay | 100 | 学习率策略(训练用) |
值得留意的是:BaseOptions.parse()在解析参数后会创建checkpoints_dir/name/目录并把全部参数写入opt.txt(base_options.py)。因此运行评测脚本前,./checkpoints/test_local/会被自动创建,你只需把预训练权重放进去即可。
六、泛化模型 vs 数据集专用模型
README 结尾特意强调了两份预训练模型的适用场景差异:
best_generalization_net_G.pth:面向任意互联网照片的通用模型,对完全未知的场景具有更好的(定性意义上的)泛化能力——DAIN 训练所用的正是这份模型;best_vanila_net_G.pth:针对 MegaDepth V1 数据集训练的专用模型,用于在测试集上复现论文指标。
实际使用时请按“未知场景推理 → generalization 版 / 数据集评测 → vanila 版”的原则选择,避免误用导致指标或效果失真。
七、复现注意事项小结
- 路径是评测的第一道门槛:
rmse_error_main.py与SDR_compute.py中的dataset_root、test_list_dir_l/p必须指向你本地真实的 MegaDepth_v1 与测试列表目录,且 landscape/portrait 的输入分辨率(240×320 与 320×240)不要对调。 - 环境适配:原 README 面向 PyTorch 0.2 / Python 2.7,当前 DAIN 仓库运行于 PyTorch 1.0.0 环境,迁移时重点确认
h5py、skimage安装及torch.cuda可用。 - 理解输出:
demo.py输出的是逆深度图(数值越大表示距离越近);做 RGB 可视化前务必用语义分割(ADE20K 训练的 PSPNet)mask 掉天空,否则视觉效果会因天空深度不一致而失真。 - 指标含义:si-RMSE 衡量对数空间、尺度不变意义上的深度误差;SDR 衡量预测深度与 SfM 稀疏顺序约束的冲突率,两者从不同侧面评估单目深度预测质量。
至此,你已掌握 MegaDepth 从单图推理到双指标评测的完整链路,并理解了其沙漏网络、权重加载约定与数据管线在 DAIN 深度感知模块中的实际用途。后续如需深入,可直接对照 MegaDepth/models/HG_model.py、MegaDepth/SDR_compute.py 与 MegaDepth/data/image_folder.py 继续研究。
- 计算机视觉
- 深度学习
【免费下载链接】DAIN
Depth-Aware Video Frame Interpolation (CVPR 2019)
相关推荐
深度估计技术终极指南:5步掌握DenseDepth单目深度预测
深度估计技术终极指南:5步掌握DenseDepth单目深度预测 深度估计技术作为计算机视觉领域的重要研究方向,通过单目图像实现高质量深度信息预测,为机器人导航、
如何正确评估Monodepth2深度预测精度:完整指南
如何正确评估Monodepth2深度预测精度:完整指南 Monodepth2是一个基于单目图像的深度估计开源项目,能够从单张图片中预测场景的深度信息。本文将详细
OCR计算机视觉WeChatMsg:新手3步导出微信聊天记录指南
WeChatMsg:新手3步导出微信聊天记录指南 去年换手机时,我盯着"聊天记录无法迁移"的提示干瞪眼——几年的对话和老照片,就这么卡在旧设备上。后来我找到了
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考