MiDaS:鲁棒的单目相对深度估计模型

FreeGuideOnline 最新 2026-06-20

MiDaS:鲁棒的单目相对深度估计模型完全指南

单目深度估计是计算机视觉中最具挑战和实用价值的任务之一。它仅从单张RGB图像中推断每个像素与相机之间的距离,无需立体相机或激光雷达。MiDaS(Multiple Depth Estimation with Transformers)正是该领域的一个里程碑模型,以极高的鲁棒性和跨数据集泛化能力著称。本教程将带你从零理解MiDaS的核心思想、不同版本、实际应用,并使用PyTorch和OpenCV快速跑通第一个深度估计Demo。


什么是单目相对深度估计?

在讲解MiDaS之前,我们必须先区分两种深度估计:

  • 绝对深度估计:输出真实物理距离(如米、厘米)。这类模型通常需要相机内参和特定场景训练。
  • 相对深度估计:输出像素之间的深度顺序,数值仅在图像内具有比较意义(例如像素A比像素B更近,但无法得知确切距离)。MiDaS属于相对深度估计范畴,它生成的深度图经过归一化,强调场景中物体的远近关系,而忽略绝对尺度。

这种设计使MiDaS能跨数据集泛化:不同数据集的绝对深度尺度差异巨大,但物体间的相对关系是通用的。


MiDaS的进化版本

MiDaS并非单一模型,而是一个持续进化的模型家族。截至2023年,主要版本如下:

版本 骨干网络 核心创新 适用场景
MiDaS v2.1 ResNet, EfficientNet-Lite 混合训练策略(MIX 6数据集) 快速推理,低显存
MiDaS v3.0 Swin Transformer, BEiT 引入Transformer骨干,性能巨大提升 高质量深度图
MiDaS v3.1 DPT (Vision Transformer) 密集预测Transformer,输出更细腻 最高精度,适合艺术化应用
MiDaS Small 轻量级CNN 移动端/边缘设备优化 实时应用

本教程将主要演示 DPT-Hybrid(MiDaS v3.1的推荐模型),它在准确率和速度之间平衡最佳。


MiDaS背后的技术原理(简化版)

如果你不想深入细节,只需记住以下三点:

  1. 多数据集混合训练:MiDaS在训练时同时使用多个深度数据集(如ReDWeb、DIML、MegaDepth等),并采用尺度和平移不变损失函数(SSI Loss),让模型学习到与绝对尺度无关的深度排序,从而克服不同数据集标注尺度差异的问题。
  2. Transformer架构的引入:v3.0开始使用视觉Transformer作为编码器,能够捕获全局上下文,对大面积均匀区域的深度预测尤为准确。
  3. 密集预测Transformer(DPT):v3.1将Transformer编码器的多尺度特征重新聚合,通过“重组模块”生成高分辨率输出,使物体边缘和细小结构更清晰。

简单理解:MiDaS就是一个经过特殊训练、能在任何图片上画出可靠远近关系的AI助手。


快速上手:用PyTorch运行MiDaS

环境准备

请确保已安装以下依赖:

pip install torch torchvision opencv-python timm matplotlib

timm库为可选,但使用DPT模型时建议安装,以免自动下载模型时出现问题。

第一步:加载模型和变换

MiDaS官方提供了轻量封装,我们直接从Torch Hub加载,无需手动编写模型代码。

import cv2
import torch
import matplotlib.pyplot as plt

# 选择模型类型:"DPT_Hybrid" 精度高;"MiDaS_small" 速度快
model_type = "DPT_Hybrid"

# 从Torch Hub加载模型,首次运行会自动下载权重
midas = torch.hub.load("intel-isl/MiDaS", model_type)

# 将模型置于评估模式,并移动到可用的设备
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
midas.to(device)
midas.eval()

第二步:加载并预处理图像

MiDaS需要特定的输入变换,官方提供了对应版本的变换函数。

# 加载与模型配对的变换
midas_transforms = torch.hub.load("intel-isl/MiDaS", "transforms")
transform = midas_transforms.dpt_transform if "DPT" in model_type else midas_transforms.small_transform

# 读取图片(BGR格式,OpenCV默认)
img = cv2.imread("input.jpg")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 应用变换:缩放到模型输入尺寸,归一化
input_batch = transform(img).to(device)

第三步:推理与后处理

with torch.no_grad():
    prediction = midas(input_batch)

    # DPT模型输出格式可能需要调整,Hybrid输出为 [1, H, W]
    prediction = torch.nn.functional.interpolate(
        prediction.unsqueeze(1),
        size=img.shape[:2],
        mode="bicubic",
        align_corners=False,
    ).squeeze()

# 转为numpy数组
depth_map = prediction.cpu().numpy()

# 相对深度需要进行归一化以便可视化
depth_map_normalized = (depth_map - depth_map.min()) / (depth_map.max() - depth_map.min())

第四步:可视化结果

plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.imshow(img)
plt.title("Original RGB")
plt.axis("off")

plt.subplot(1, 2, 2)
plt.imshow(depth_map_normalized, cmap='inferno')
plt.title("MiDaS Relative Depth")
plt.axis("off")

plt.show()

# 可选:保存深度图为图像或npy文件
cv2.imwrite("depth.png", (depth_map_normalized * 255).astype("uint8"))

更轻量的选择:使用OpenVINO加速推理

在CPU或边缘设备上,可以使用OpenVINO优化模型,实现数倍加速。

  1. 将PyTorch模型导出为ONNX:
dummy_input = torch.randn(1, 3, 384, 384).to(device)
torch.onnx.export(midas, dummy_input, "midas.onnx", opset_version=11)
  1. 使用OpenVINO推理引擎加载执行,这里仅给出关键代码思路:
from openvino.runtime import Core
ie = Core()
model = ie.read_model("midas.onnx")
compiled_model = ie.compile_model(model, "CPU")
# ... 预处理输入、执行推理、后处理

实际OpenVINO部署涉及输入尺寸适配和归一化参数对齐,推荐直接使用Intel提供的MiDaS OpenVINO Notebook


理解MiDaS深度图的特性与局限

  • 输出不是真实距离:深度值范围是相对的,同一场景中较暗区域表示较远,较亮表示较近,但亮度值不能换算成米。
  • 边缘模糊问题:尽管DPT改善了边缘清晰度,但强光照阴影或反射可能导致深度误判。
  • 动态物体:MiDaS没有时序信息,对快速运动物体估计的深度可能不稳定。
  • 人像和细长结构:混合训练中包含多种场景,但对人像的深度估计有时会比专用模型粗糙。

因此,如需将相对深度转换为绝对深度,可采用以下策略:

  • 使用已知真实尺寸的参照物(如地面平面、身高)进行尺度对齐。
  • 借助SLAM或惯性测量单元提供稀疏绝对深度锚点。

实战应用场景

  1. 背景虚化效果(合成浅景深):根据深度图控制模糊核大小。
  2. 3D照片:用相对深度生成视差,制作微动视频。
  3. 增强现实遮挡:判断虚拟物体与真实场景的前后关系。
  4. 机器人导航线索:作为避障的廉价视觉输入。
  5. 图像编辑:如“雾气”效果随深度变化。

常见问题排查

  • Torch Hub下载失败:国内网络可能受限,可手动下载权重文件,放置于~/.cache/torch/hub/intel-isl_MiDaS_master/,文件名参考仓库README
  • 内存不足(OOM):减小输入尺寸,DPT默认384×384,可改为256×256;或切换到MiDaS_small
  • 输出全黑或全白:检查是否应用了正确的transform,且图像归一化方式是否与训练一致。
  • DPT模型输出形状不对:不同版本torch.hub.load返回值可能略有差异,紧跟示例代码可避免。

资源与参考资料

  • 官方GitHub仓库intel-isl/MiDaS — 包含完整训练代码和论文列表。
  • 论文
    • Towards Robust Monocular Depth Estimation: Mixing Datasets for Zero-shot Cross-dataset Transfer (Muñoz et al., 2019)
    • Vision Transformers for Dense Prediction (Ranftl et al., 2021)
  • 交互式Demo:Hugging Face Space上搜索MiDaS可在线体验。

现在,你已经掌握了MiDaS的核心知识和实践用法。不妨立即拿身边的照片实验一番,感受单目深度估计的魔力。