Ultralytics 深度估计预测器解析:以 DepthPredictor 源码理解 YOLO 单目深度推理

发布时间:2026/9/8 17:12:26
Ultralytics 深度估计预测器解析:以 DepthPredictor 源码理解 YOLO 单目深度推理 Ultralytics 深度估计预测器解析以 DepthPredictor 源码理解 YOLO 单目深度推理【免费下载链接】ultralyticsUltralytics YOLO26, YOLO11, YOLOv8 — object detection, instance segmentation, semantic segmentation, image classification, pose estimation, object tracking项目地址: https://gitcode.com/GitHub_Trending/ul/ultralytics单目深度估计是让模型从一张 RGB 图像中逐像素预测深度值单位为米的任务。本文以 Ultralytics 仓库中的 depth/predict.py 为绝对主线逐段剖析DepthPredictor的初始化逻辑与postprocess后处理管线并结合Results/DepthMap数据结构、ops.scale_masks工具函数与 YOLO 任务分发机制讲清楚“YOLO 深度模型推理时网络原始输出张量如何一步步变成一张与原图对齐的 (H, W) 深度图”。读完本文你将能从源码层面理解yolo depth predict的内部工作方式并准确读写推理结果。深度预测器在任务体系中的位置Ultralytics 的models/yolo/depth目录是深度估计任务的完整实现由 5 个 Python 文件构成predict.py —— 定义DepthPredictor负责推理前向与后处理train.py —— 定义DepthTrainer训练完成后还会自动执行尺度校准val.py —— 定义DepthValidator计算 delta1 / abs_rel / rmse / silog 等指标calibrate.py —— 提供无须梯度训练的 log-affine 尺度校准init.py —— 统一导出DepthPredictor、DepthTrainer、DepthValidator。在 YOLO 的任务注册表中depth任务被映射到上述三个类见 model.py 中task_map的depth分支因此当你使用YOLO(yolo26n-depth.pt)并调用model.predict(...)时Ultralytics 会自动装配到DepthPredictor上完成推理。这正是本文主角DepthPredictor的职责所在。DepthPredictor 类速览与初始化DepthPredictor继承自 engine/predictor.py 中的BasePredictor把通用推理框架数据加载、前向、批处理、回调复用到深度任务上自身只保留任务专属逻辑class DepthPredictor(BasePredictor): Predictor for YOLO depth estimation models. Produces per-pixel depth maps from RGB images. 它的构造函数只是透传给父类并强制把任务类型设为depthdef __init__(self, cfgDEFAULT_CFG, overridesNone, _callbacksNone) - None: super().__init__(cfg, overrides, _callbacks) self.args.task depth其中cfg默认取ultralytics.utils.DEFAULT_CFG对应 cfg/default.yaml 中 imgsz、device、conf 等全部默认超参overrides用于临时覆盖参数例如通过dict(modelyolo26n-depth.pt, sourcebus.jpg)传入。args.task depth这行赋值看似简单却决定了整条推理链路中使用深度任务专属的默认配置与回调。类 docstring 给出了最小可用示例from ultralytics.models.yolo.depth import DepthPredictor predictor DepthPredictor(overridesdict(modelyolo26n-depth.pt)) results predictor(image.jpg)推理主流程继承自 BasePredictor 的调用链DepthPredictor并未覆写predict/stream_inference因此推理主流程全部由BasePredictor驱动大致为解析overrides并合并默认配置DEFAULT_CFG依据模型后缀加载权重并创建对应后端PyTorch / ONNX / TensorRT / CoreML 等见 nn/autobackend.py逐 batch 对输入做预处理resize letterbox 填充到模型输入尺寸前向得到原始预测张量调用本类覆写的postprocess还原出原图分辨率的深度图包装成Results。需要特别指出的是深度估计是纯逐像素回归任务不需要 NMS、也不需要类别过滤。对比检测任务的预测器DepthPredictor唯一的任务专属覆盖点就是postprocess——这一点也与 DepthValidator 中“No NMS needed for depth — return predictions as-is”的实现遥相呼应。postprocess 逐段拆解从原始张量到深度图postprocess是DepthPredictor的核心下面结合 predict.py 的完整实现逐段分析。第一步规整张量形状depth_maps preds[0] if isinstance(preds, (tuple, list)) else preds # (B, 1, H, W) if depth_maps.ndim 3: depth_maps depth_maps.unsqueeze(1) # (B, H, W) → (B, 1, H, W)不同后端尤其是导出后的 ONNX / TensorRT返回的预测格式并不统一有的返回(B, 1, H, W)的 4 维张量有的直接返回(B, H, W)的 3 维张量。这里先安全解包 tuple/list再统一补出通道维保证后续所有操作都基于标准的 NCHW 布局。第二步裁掉 letterbox 填充并恢复到模型输入分辨率# Restore model-input resolution so all backends crop letterbox padding before scaling to the original image. depth_maps ops.scale_masks(depth_maps, img.shape[2:], paddingFalse)在推理前预处理阶段输入图通常会被 letterbox 到模型要求的正方形尺寸如 640×640左右会填充灰色条带。这些填充区域产生的“深度预测”是无意义的必须裁掉。ops.scale_masks定义于 utils/ops.py在这里以paddingFalse被调用此时函数内部会依据目标形状自动计算缩放比例gain与填充量pad_w/pad_h然后仅对真实内容区域执行F.interpolate(..., modebilinear)双线性插值缩放。这一步先把模型输出的深度图还原成 letterbox 前的分辨率且明确跳过 pad 区保证“所有后端”行为一致——这正是源码注释强调的意图。第三步统一原图来源if not isinstance(orig_imgs, list): # torch.Tensor source (B, 3, H, W) orig_imgs ops.convert_torch2numpy_batch(orig_imgs)[..., ::-1]orig_imgs可能是原始的 numpy list每项 BGR uint8 的 HWC 图也可能是由 dataloader 合并出的torch.TensorBCHWRGB 顺序的 float 张量。当输入是 Tensor 时ops.convert_torch2numpy_batchutils/ops.py负责把它permute成 BHWC、反归一化回 0–255 的 uint8随后[..., ::-1]把 RGB 再翻转为 BGR使两种来源最终都对齐到 numpy BGR 格式方便后续可视化叠加。第四步逐图缩放到原始分辨率并包装 Resultsfor i, orig_img in enumerate(orig_imgs): img_path self.batch[0][i] if isinstance(self.batch[0], list) else self.batch[0] depth ops.scale_masks(depth_maps[i : i 1].float(), orig_img.shape[:2]) results.append(Results(orig_imgorig_img, pathimg_path, namesself.model.names, depthdepth.squeeze()))对每张原图再一次调用ops.scale_masks这次是默认paddingTrue把批内第 i 张深度图直接双线性插值到该原图的(H, W)。depth.squeeze()去掉批与通道两个维度得到单张(H, W)的深度张量连同原图、路径与类别名一起封装进Results。因此可以推断无论模型输入尺寸是多少、letterbox 填充多少result.depth始终与result.orig_img的宽高严格对齐。推理输出结构Results.depth 与 DepthMap深度任务的Results与检测、分割任务有本质区别没有 boxes没有 masks只携带一张稠密深度图。Ultralytics 用专用类型封装它Results 初始化时把深度张量包装为self.depth DepthMap(depth, self.orig_shape)DepthMap 继承_DenseResultTensor见 results.py后者保证“每个图像只有零或一张密集结果”行索引操作不会破坏单图数据——这与 boxes/masks 那种多实例、按行切分的语义截然不同。实际取用深度图的标准写法与 tasks/depth.md 文档中的 Predict 示例一致from ultralytics import YOLO model YOLO(yolo26n-depth.pt) # 或自定义模型 path/to/best.pt results model(bus.jpg) for result in results: depth_map result.depth.data.cpu().numpy() # (H, W) float32单位为米对应输出字段速查属性类型形状含义result.depthDepthMap(H, W)稠密逐像素深度图result.depth.datatorch.Tensor(H, W)单位为米的深度值.cpu().numpy()得到 NumPy 数组result.boxes/result.masks无—深度任务不产生实例框或实例掩码原始深度图是单通道 float 数组直接肉眼很难判读。若需可视化可使用ultralytics.utils.plotting中的colorize_depth辅助函数或直接调用result.plot()默认以cmapjet、modedisparity将彩色深度叠加回输入图详细参数与用法见 tasks/depth.md 的 “Colorizing the depth map” 小节。端到端运行方式Python APIfrom ultralytics import YOLO # 加载官方预训练模型或本地自定义模型 model YOLO(yolo26n-depth.pt) # model YOLO(path/to/best.pt) # 对图片/视频/目录/URL 等任意 source 推理 results model(https://ultralytics.com/images/bus.jpg) # 逐结果取深度图并转 NumPy for result in results: depth_map result.depth.data.cpu().numpy()CLIyolo depth predict modelyolo26n-depth.pt sourcehttps://ultralytics.com/images/bus.jpg yolo depth predict modelpath/to/best.pt sourcepath/to/images/其中yolo depth predict中显式的depth任务声明与DepthPredictor.__init__里self.args.task depth是同一意图的两种表达二者任一都能确保走对任务管线。CLI 的source支持单张图、目录、视频、摄像头流与 URLimgsz、device、conf、save等参数均可通过yolo predict通用参数覆盖详见 modes/predict.md。直接使用 Predictor 类如需在脚本中精细控制例如复用同一个实例处理多路输入也可以绕过YOLO封装直接实例化from ultralytics.models.yolo.depth import DepthPredictor predictor DepthPredictor(overridesdict(modelyolo26n-depth.pt, conf0.001)) results predictor(bus.jpg)与训练 / 验证侧协同的尺度机制理解预测器还需要一点上下文深度预测的绝对尺度米由训练与验证环节共同约束预测端直接消费最终结果。尺度与形状解耦深度头输出exp(logit)的无界相对对数深度绝对米数由独立的双参数 log-affine 变换exp(a·log d b)决定详见 tasks/depth.md “Depth range and the log-depth head”一节训练后自动校准train.py 的final_eval见第 130–173 行在训练结束后会调用calibrate_checkpoint对 best / last 两个 checkpoint 在验证集上做尺度校准并写盘所以官方发布的yolo26*-depth.pt以及你本地训练产出的权重加载后输出的都是已带正确米制尺度的深度图——预测端无需任何额外处理验证指标DepthValidator 使用DepthMetrics(max_depth...)统计 delta1/abs_rel/rmse/silog仅用于评估不参与DepthPredictor的推理路径。从源码结构可以推断DepthPredictor之所以能保持如此精简仅约 50 行正是因为“通用推理框架下沉到BasePredictor、尺度管理上收到训练阶段”这一清晰的分工设计。进一步阅读任务完整指南模型表、微调配方、尺度校准、指标定义docs/en/tasks/depth.md预测模式通用参数与用法docs/en/modes/predict.md深度数据集格式与内置数据集 YAMLdocs/en/datasets/depth/index.md掩码缩放工具scale_masksultralytics/utils/ops.py结果对象与DepthMap定义ultralytics/engine/results.py深度任务的训练 / 验证 / 预测装配ultralytics/models/yolo/model.py【免费下载链接】ultralyticsUltralytics YOLO26, YOLO11, YOLOv8 — object detection, instance segmentation, semantic segmentation, image classification, pose estimation, object tracking项目地址: https://gitcode.com/GitHub_Trending/ul/ultralytics创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻