一条命令,把普通照片变成高清深度图:MiDaS 单目深度估计上手全指南
【免费下载链接】MiDaSCode for robust monocular depth estimation described in "Ranftl et. al., Towards Robust Monocular Depth Estimation: Mixing Datasets for Zero-shot Cross-dataset Transfer, TPAMI 2022"项目地址: https://gitcode.com/gh_mirrors/mi/MiDaS
MiDaS(Monocular Depth Estimation)是 Intel 实验室开源的单目深度估计工具:输入一张普通照片,它就能输出一张每个像素都标好"离相机多远"的深度图。它最出名的本事是零样本跨数据集迁移——用最多 12 个数据集混合训练出的模型,到了从没见过的场景里依然稳。本文从"它为什么这么能打"讲到"一条命令跑通出图",再带你把分辨率、精度、速度调到自己满意。
从"一眼看穿距离"说起
想象你正要遥控一台扫地机器人进卧室。它面前只有一颗摄像头,没有激光雷达、没有结构光,怎么判断"床脚离我 50 厘米、墙角离我 2 米"?靠的就是单目深度估计——从一张 2D 照片里,反推出每个像素的远近关系。
人类做这件事毫不费力:两只眼睛有视差,大脑还有十几年对物体大小的经验。电脑却难得多,因为单张照片在数学上本来就是"信息不完整"的:同一张图,可能是一辆小车近在眼前,也可能是一辆大车停在远处。所以早期的单目深度估计模型有个通病——换一个场景就崩:在室内数据集上训出来的模型,拿到室外马路上立刻"眼瞎"。
MiDaS 之所以成为这个领域绕不开的名字,就是因为它把"泛化能力"这件事做成了核心卖点,而且把使用门槛压到了一条命令行。
两个关键抉择,决定了 MiDaS 的上限
为什么要把 12 个数据集"煮"进一个模型
传统做法是"一个数据集训练一个模型":在 NYU Depth V2 上训,就服务室内;在 KITTI 上训,就服务自动驾驶。问题在于,每个数据集的深度尺度、标注风格、场景分布都不一样,硬把它们混在一起训练,模型会互相"打架",越训越差。
MiDaS 的解法来自它的论文标题:Mixing Datasets for Zero-shot Cross-dataset Transfer(混合数据集实现零样本跨数据集迁移)。它把 ReDWeb、DIML、Movies、MegaDepth、WSVD、TartanAir、HRWSI、ApolloScape、BlendedMVS、IRS、KITTI、NYU Depth V2 这些风格迥异的数据集,通过多目标优化的方式揉进同一个模型——每个数据集都有自己的优化目标,模型被迫学到"与数据集无关的深度结构",而不是死记某一种场景的套路。
这就像一个人学外语:只背一本教材的人,换到真实对话就卡壳;听过几十种口音、看过几十种场合的人,遇到新场景也能听懂个七八成。MiDaS 学的不是"某个数据集的深度规律",而是"深度本身长什么样"。所以在 6 个全新数据集的评测里,它都能保持稳定表现,这就是官方 accuracy 表里"零样本误差"的含义。
一台机器放不下所有模型:模型动物园的取舍
如果你翻到项目 README 的 accuracy 表,会发现 MiDaS 3.1 一口气提供了 5 种 transformer 骨干(BEiT、Swin2、Swin、Next-ViT、LeViT),加上 3.0 的 DPT、2.1 的卷积模型,一共十几种。为什么不只做"最强的那一个"?
答案藏在这张图里——精度和速度,是鱼与熊掌:
横轴是 RTX 3090 上的推理速度(FPS),纵轴是相对 MiDaS 3.0 DPT-L-384 的平均改进度,气泡大小代表参数量。你可以清楚看到一条"性能走廊":
| 模型 | 推理高度 | 参数量 | FPS(RTX 3090) | 定位 |
|---|---|---|---|---|
| dpt_beit_large_512 | 512 | 345M | 5.7 | 精度天花板,比 v3.0 平均提升约 28% |
| dpt_swin2_large_384 | 384 | 213M | 41 | 精度/速度兼顾的甜点 |
| dpt_levit_224 | 224 | 51M | 73 | 边缘设备首选 |
| midas_v21_small_256 | 256 | 21M | 90 | 最轻量,移动端实时 |
(数据取自项目 README 官方 accuracy 表,推理环境为 RTX 3090;OpenVINO 版本在 Intel 笔记本 CPU 上也能跑到约 22 FPS。)
v3.1 里最强的 BEiT-Large-512 平均精度比 v3.0 提升约 28%,但每秒只能处理 5.7 张;而 21M 参数的 v2.1 small 能跑 90 FPS,代价是精度垫底。所以 MiDaS 干脆不做单选题,把不同档位的模型都摆上货架,让你按自己的硬件和场景挑。
从零到出图,三步走
第一步:克隆与装环境
git clone https://gitcode.com/gh_mirrors/mi/MiDaS cd MiDaS # 用 conda 一键还原环境(Python 3.10.8 + PyTorch 1.13 + CUDA 11.7) conda env create -f environment.yaml conda activate midas-py310环境名是midas-py310,environment.yaml里已经锁好了 opencv、timm、einops 等依赖版本,基本不会出现"缺包"的意外。
第二步:下载权重
权重统一放进weights/目录,模型名对应文件名。以默认模型为例:
wget -P weights https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_beit_large_512.pt(其他模型如 dpt_swin2_large_384.pt、dpt_levit_224.pt 等,同理下载到该目录。项目midas/model_loader.py里的default_models字典写明了每个模型名对应的权重路径,可以对照着看。)
第三步:放图,跑命令
把要处理的照片放进input/,然后:
python run.py --model_type dpt_beit_large_512 --input_path input --output_path output不传--model_type时默认就是dpt_beit_large_512。跑起来后终端会打印设备信息、模型参数量("Model loaded, number of parameters = 345M"),以及每张图的处理进度。预期输出:output/下会生成两个文件——一张伪彩色 PNG 深度图,和一个.pfm浮点深度文件(后者的精度更高,适合做后续处理)。
想看直观效果?同一场景下各模型的深度图对比,官方放了一张大图:
左边是原图,右侧每一格是一个模型输出的深度图(橙近紫远)。放大看,BEiT 系列的边缘明显更利落,小模型则相对糊一些——这就是"精度换速度"在视觉上的直接体现。
进阶玩转:让深度图更清晰、更快、更全能
分辨率不够?试试 --height
run.py默认会把输入缩放到模型的训练高度(比如 BEiT 是 512)。想输出更精细的深度细节,可以手动指定编码器输入高度:
python run.py --model_type dpt_beit_large_512 --input_path input --output_path output --height 768源码里(run.py的process函数)模型输出的预测结果会被 bicubic 插值回原始图像分辨率,所以高度设得高,细节保留得就多。但有三点要记住:第一,高度会自动对齐到 32 的倍数(midas/transforms.py里的Resize类);第二,显存会随分辨率涨得很快;第三,很多模型只支持训练时的高度,传了不支持的值会直接报错。
想要 16-bit 高精度深度?加 --grayscale
默认的 inferno 伪彩色图只有 8-bit 精度,颜色映射本身会损失深度信息。如果你要做点云、三维重建这类精度敏感的工作,记得加:
python run.py --model_type dpt_beit_large_512 --input_path input --output_path output --grayscale此时utils.write_depth会以bits=2写出16-bit 的 uint16 PNG(项目源码里这个逻辑写得很清楚),灰度图的精度比伪彩色高得多。不过说实话,最保真的还是那个.pfm文件——它存的就是 float32 原始深度。
用 Python API 自由调用
不想走命令行?midas/model_loader.py的load_model会返回(model, transform, net_w, net_h),自己拼推理管线也只要十几行:
import torch, cv2 from midas.model_loader import load_model device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model, transform, net_w, net_h = load_model(device, None, "dpt_beit_large_512", optimize=True) img = cv2.imread("input/sample.jpg") rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) / 255.0 sample = transform({"image": rgb})["image"] with torch.no_grad(): pred = model.forward(sample.unsqueeze(0).to(device)) depth = torch.nn.functional.interpolate( pred.unsqueeze(1), size=img.shape[:2], mode="bicubic", align_corners=False ).squeeze().cpu().numpy()这段逻辑与run.py里的推理代码一致,适合想接进自己项目的读者。
摄像头实时 + 多端部署
run.py有个隐藏玩法:不传 input/output 路径,就会直接打开摄像头实时出深度图,加--side还能左右并排显示原图与深度图:
python run.py --model_type dpt_swin2_tiny_256 --side另外,tf/目录提供 TensorFlow 与 ONNX 版本(当前支持 v2.1),mobile/有完整的 iOS/Android 示例工程,ros/是 ROS1 机器人部署包,项目根目录还带 Dockerfile——docker build -t midas .之后一条docker run就能在容器里跑推理。换场景几乎不需要改代码。
高频报错避坑手册
1. 症状:CUDA out of memory根因:大模型(BEiT-512)+ 高分辨率输入,显存爆了。 解法:把--height降到 384/256,或者换轻量模型(dpt_swin2_tiny_256、dpt_levit_224)。
2. 症状:Swin 系列模型输出 NaN 或非有限深度值根因:--optimize的半精度优化与 Swin 不兼容。run.py源码里自带警告:"models like Swin require float precision to work properly"。 解法:Swin/Swin2 别加--optimize,BEiT 系列可以放心用。
3. 症状:--height传了值却直接报错根因:部分模型只支持训练时的高度(比如 Swin2 只有 256/384 两档)。 解法:用模型名里的数字作为默认高度,或参考 README 的 accuracy 表按高度分组查询。
4. 症状:存出来的 PNG 是 8-bit 伪彩色,精度不够根因:inferno 色彩映射本身只有 8-bit 精度。 解法:加--grayscale输出 16-bit 灰度 PNG;追求极致精度就用自动生成的.pfm浮点文件。
5. 症状:dpt_next_vit_large_384报模块找不到根因:Next-ViT 骨干是外部依赖,需要单独拉取。 解法:按 README 说明,用git submodule把 Next-ViT 仓库挂到midas/external/next_vit。
6. 症状:openvino_midas_v21_small_256加载失败根因:缺少 OpenVINO 运行时。 解法:pip install openvino后再试。
它不止于深度图:MiDaS 的生态与未来
最后多说一句:MiDaS 输出的其实是相对深度——它知道"A 比 B 近",但不知道"A 离相机 1.5 米"。想要绝对尺度,社区里有 ZoeDepth 在 MiDaS 解码器后面接一个 metric binning 模块,直接输出真实距离;LDM3D 则用 MiDaS 生成的深度图作为监督信号,训练"文字生成图片 + 深度"的扩散模型。换句话说,MiDaS 已经成了很多下游三维视觉任务的"深度先验基础设施"。
未来这个方向会往哪走?无非是三条线:按场景复杂度动态分配分辨率、融合 RGB 与事件相机等多模态数据、把模型压到能在移动端跑 4K 实时深度估计。而无论哪条线,MiDaS 这套"混合数据集 + 多目标优化 + 模型动物园"的思路,大概率还会是地基。
想进一步研究,可以对照项目源码阅读这几个关键位置:命令行入口run.py、模型加载与参数表midas/model_loader.py、分辨率调整逻辑midas/transforms.py、特征融合模块midas/blocks.py。相关论文包括 Ranftl 等人的《Towards Robust Monocular Depth Estimation》(TPAMI 2022,arXiv:1907.01341)、《Vision Transformers for Dense Prediction》(ICCV 2021,arXiv:2103.13413),以及 MiDaS 3.1 的技术报告(arXiv:2307.14460)。
从一条命令到一整套三维视觉管线,MiDaS 值得你亲手跑一次。
【免费下载链接】MiDaSCode for robust monocular depth estimation described in "Ranftl et. al., Towards Robust Monocular Depth Estimation: Mixing Datasets for Zero-shot Cross-dataset Transfer, TPAMI 2022"项目地址: https://gitcode.com/gh_mirrors/mi/MiDaS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考