一条命令,把普通照片变成高清深度图:MiDaS 单目深度估计上手全指南
一条命令把普通照片变成高清深度图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/MiDaSMiDaSMonocular 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 的平均改进度气泡大小代表参数量。你可以清楚看到一条性能走廊模型推理高度参数量FPSRTX 3090定位dpt_beit_large_512512345M5.7精度天花板比 v3.0 平均提升约 28%dpt_swin2_large_384384213M41精度/速度兼顾的甜点dpt_levit_22422451M73边缘设备首选midas_v21_small_25625621M90最轻量移动端实时数据取自项目 README 官方 accuracy 表推理环境为 RTX 3090OpenVINO 版本在 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-py310environment.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 系列的边缘明显更利落小模型则相对糊一些——这就是精度换速度在视觉上的直接体现。进阶玩转让深度图更清晰、更快、更全能分辨率不够试试 --heightrun.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会以bits2写出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, optimizeTrue) 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), sizeimg.shape[:2], modebicubic, align_cornersFalse ).squeeze().cpu().numpy()这段逻辑与run.py里的推理代码一致适合想接进自己项目的读者。摄像头实时 多端部署run.py有个隐藏玩法不传 input/output 路径就会直接打开摄像头实时出深度图加--side还能左右并排显示原图与深度图python run.py --model_type dpt_swin2_tiny_256 --side另外tf/目录提供 TensorFlow 与 ONNX 版本当前支持 v2.1mobile/有完整的 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 别加--optimizeBEiT 系列可以放心用。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 2022arXiv:1907.01341、《Vision Transformers for Dense Prediction》ICCV 2021arXiv: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),仅供参考