ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

单目深度估计实战:用 MiDaS 从一张照片还原三维空间的距离信息

2026/8/17 19:53:18 拓冰建站 浏览量
单目深度估计实战:用 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/MiDaS拿到一张普通照片你能立刻说出画面里每个物体离你多远吗人眼可以但计算机做不到——这正是单目深度估计Monocular Depth Estimation要解决的问题只靠单张 RGB 图像预测出每个像素对应的深度值。Intel 实验室开源的 MiDaS 把这件事做到了开箱即用的水平本文会带你从模型选型、分辨率设置到结果后处理完整跑通一条高清晰度深度图的生成链路并附上实测有效的排坑清单。什么是深度图简单说它是一张和原图同尺寸的灰度图每个像素的亮度代表该点距离相机的远近。有了它二维照片就有了三维空间的结构信息。一个深度值背后藏着什么先理解 MiDaS 在解决什么问题深度估计的传统做法是双目视觉用两台相机拍下同一场景靠左右视差反算距离。MiDaS 走的是更轻的路线——单目即一台相机、一张图。但这带来一个致命问题单张图像本身就存在尺度歧义。同样是一辆车的照片你无法判断它到底是近处的小车还是远处的大卡车。MiDaS 的策略是退一步不做绝对距离只做相对深度近处亮、远处暗把尺度问题交给下游任务处理。它的另一项关键能力是零样本跨数据集迁移Zero-shot Cross-dataset Transfer。模型在多达 12 个数据集上混合训练包括 ReDWeb、DIML、MegaDepth、TartanAir、ApolloScape、KITTI、NYU Depth V2 等覆盖室内、室外、航拍、驾驶等差异极大的场景。训练时多目标优化让它在从未见过的数据集上也能保持稳定表现——这也是它鲁棒robust二字的由来。论文《Towards Robust Monocular Depth Estimation: Mixing Datasets for Zero-shot Cross-dataset Transfer》详细描述了这套方法。先选对模型再谈精度读懂 MiDaS 的模型命名与权衡打开仓库的midas/model_loader.py你会发现内置了 14 种模型类型。命名有规律可循dpt_beit_large_512中dpt表示解码器采用 Dense Prediction Transformer 架构beit是骨干网络特征提取器large是规模512是训练分辨率。看懂这串名字你就知道该选谁。模型类型参数量训练分辨率RTX 3090 推理帧率适合场景dpt_beit_large_512345M512×512约 6 FPS追求极致细节离线处理dpt_swin2_large_384213M384×384约 41 FPS精度与速度均衡dpt_swin2_tiny_25642M256×256约 64 FPS嵌入式设备、实时应用dpt_next_vit_large_38472M384×384约 30 FPS轻量但精度不俗dpt_levit_22451M224×224约 73 FPS手机端、高帧率需求midas_v21_small_25621M256×256约 90 FPS老牌轻量模型CPU 可跑选型时记住一句话显存和帧率是硬约束细节是软需求。BEiT-L-512 比 v3.0 的 DPT-L-384 平均精度提升约 28%代价是帧率只有它的十分之一。如果你的应用是离线的建筑测绘、文物数字化直接上dpt_beit_large_512如果是实时机器人避障dpt_swin2_tiny_256才是正确选择。让网络吃得下你的图分辨率调整的三个关键细节输入一张 4K 照片网络不可能直接处理——编码器对输入尺寸有硬性要求。MiDaS 的分辨率适配逻辑集中在midas/transforms.py的Resize类理解它就能用好--height和--square两个参数。细节一为什么必须是 32 的倍数。Transformer 骨干网络在内部会把图像切成 patch图像块并逐层降采样。如果输入尺寸不是 32 的倍数最后几层的特征图尺寸就无法对齐直接报错。Resize里的constrain_to_multiple_of方法会自动把目标尺寸就近对齐到 32 的倍数你传一个不规范的--height它也不会崩。细节二保持纵横比还是强制方形。Swin、Swin2、LeViT 这类分层骨干只支持方形输入所以仓库里它们默认keep_aspect_ratioFalse图像会被拉伸。而 BEiT、DPT 系列支持任意宽高比默认会尽量保持原图比例。手动指定--square会强制方形——拉伸带来的透视畸变可能让深度出现偏差非必要不建议开。细节三三种缩放策略。Resize支持三种resize_methodminimal缩放幅度最小输出可能略小于目标尺寸lower_bound保证输出至少达到目标尺寸upper_bound保证输出最多不超过目标尺寸。DPT 系模型用minimal老版卷积模型v2.1用upper_bound。这些细节在你自定义推理管线时决定了预处理质量。三条路径跑通第一次推理命令行、摄像头与 Python API路径一命令行批处理最快见效克隆仓库后先按environment.yaml创建环境环境名midas-py310内含 PyTorch 1.13、OpenCV 等依赖然后把模型权重放进weights/目录git clone https://gitcode.com/gh_mirrors/mi/MiDaS cd MiDaS conda env create -f environment.yaml conda activate midas-py310把待处理图片放入input/执行python run.py \ --model_type dpt_beit_large_512 \ --input_path input \ --output_path output结果会写到output/下每张图同时生成 PNG 和 PFM 两种格式。用--height 768可以尝试更高分辨率会提升细节但可能降精度、增显存占用用--grayscale可以输出灰度而非默认的 Inferno 彩色映射。路径二摄像头实时预览不带输入输出路径模型会直接从摄像头抓帧python run.py --model_type dpt_swin2_tiny_256 --side--side让原图和深度图并排显示方便实时对比。在 Intel i7-1185G7 这类 CPU 上搭配 OpenVINO 版模型openvino_midas_v21_small_256实测可跑到约 22 FPS。路径三Python API 自由控制想要自定义预处理或后处理直接调load_model即可它在midas/model_loader.py中返回模型、预处理变换和网络输入尺寸三件套import cv2, torch 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/photo.jpg) img_rgb cv2.cvtColor(img, cv2.COLOR_BGR2RGB) / 255.0 sample transform({image: img_rgb})[image] with torch.no_grad(): out model.forward(sample.unsqueeze(0).to(device)) depth torch.nn.functional.interpolate( out.unsqueeze(1), sizeimg.shape[:2], # 上采样回原图分辨率 modebicubic, align_cornersFalse, ).squeeze().cpu().numpy()run.py的process函数内部正是这样做的网络输出小尺寸深度图后用双三次插值放大到与原图一致保证每像素一一对应。输出不止一张图PNG、PFM 与 16 位精度utils.py中的write_depth揭示了输出格式的秘密PNG默认走 Inferno 彩色映射适合人眼查看但只有 8 位精度加--grayscale后输出 16 位灰度 PNG适合后续算法处理因为 16 位能保留更细腻的深度层次。PFM浮点格式直接保存推理出的原始相对深度值供科研或二次开发使用不丢失任何信息。如果你要拿深度图做三维重建、点云生成这类严肃用途推荐始终保留 PFM 版本可视化展示再用彩色 PNG。一张排查清单从显存溢出到条纹伪影下面是我在实践中最常遇到的三个问题直接给你可执行的处置顺序显存溢出CUDA out of memory把--height逐档下调例如 512 → 384 → 256每档都是 32 的倍数开启--optimize把模型切到半精度float16显存占用近乎减半仍然溢出就换轻量模型dpt_swin2_tiny_256是最稳妥的兜底。深度图出现条纹或噪点关掉--square恢复原始纵横比检查 PyTorch 版本Transformer 相关 bug 在 1.10 已修复environment.yaml里锁定的 1.13 是安全版本换骨干网络试一次Swin2 对某些场景比 BEiT 更稳。推理速度慢到不可用确认是否误用了 512 分辨率的大模型——它本身就只有个位数 FPS换dpt_levit_224约 73 FPS或 v2.1 小模型CPU 上部署时考虑 OpenVINO 版本模型Intel 平台有明显加速。三个容易被误解的点误区一分辨率越高深度一定越准。实际并非如此。仓库的精度表里BEiT-L-512 在 384 高度推理时误差反而比 512 时更大且不同数据集表现不一。分辨率提高带来的是细节密度不必然带来数值精度提升。先小分辨率验证流程再逐步放大是更稳妥的做法。误区二--optimize对所有模型都安全。run.py里有一句明确的警告Swin 系列模型在半精度下可能产生非有限的深度值。所以 Swin 系慎开半精度BEiT 系则问题不大。误区三MiDaS 输出的深度可以直接当真实距离用。不能。它是相对深度尺度未知。想要绝对距离米制需要像 ZoeDepth 这类在 MiDaS 基础上追加度量深度模块的方案或者自己标定尺度因子。还能往哪走四条延伸路线MiDaS 的价值不止于单机脚本仓库提供了多条落地路径移动端mobile/目录下有完整的 Android 与 iOS 工程内置 TFLite 转换与调用示例把深度估计塞进手机应用并不难机器人ros/目录提供了 ROS1 的 C 与 Python 封装包含 talker/listener 示例可直接接入机器人感知管线模型转换tf/目录包含 ONNX 与 TensorFlow 的转换和推理脚本便于接入其他推理框架实时应用官方仓库中的 LDM3D文本生成图像深度和 ZoeDepth米制深度都建立在 MiDaS 之上说明它已经是被验证过的地基。结尾从第一张深度图开始回顾一下整条路径先根据硬件选型大模型离线、小模型实时再理解分辨率适配的三个细节32 倍数、纵横比、缩放策略然后用命令行或 Python API 跑通第一次推理最后根据输出格式与排查清单持续调优。这套流程走完你就已经掌握了单目深度估计落地的基本功。下一步不妨把 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),仅供参考