Ultralytics YOLO27:

使用 Ultralytics YOLO 进行单目深度估计#

Monocular depth estimation examples

单目深度估计根据单张 RGB 图像预测逐像素深度图。每个输出像素都包含一个以米为单位的深度值,表示从相机到该表面点的估计距离。

深度模型的输出是一个形状为 (H, W)、与输入图像对齐的稠密浮点图。这种逐像素表示使单目深度估计非常适合 3D 场景重建、机器人导航、AR/VR 内容创建,以及任何需要根据单个摄像头获取空间布局的应用。

提示

使用 task=depthyolo depth CLI 任务进行单目深度估计。YOLO26 深度模型文件使用 -depth 后缀,例如 yolo26n-depth.pt



Watch: Monocular Depth Estimation with Ultralytics YOLO26 | Python Tutorial | Vision AI 🚀

模型#

以下展示了在广泛的多数据集混合数据(室内 + 室外,~219 万张图像)上预训练的 YOLO26 深度模型。指标列在 NYU Depth V2 Eigen 测试集上报告。

首次使用时,模型 会自动从最新的 Ultralytics 发布版本 下载。

模型尺寸
(像素)
delta1NYUabs_relNYUrmseNYU速度
CPU ONNX
(毫秒)
速度
T4 TensorRT10
(毫秒)
参数量
(M)
FLOPs
(B)
YOLO26n-depth7680.8820.1090.414272.0 ± 27.22.7 ± 0.16.346.9
YOLO26s-depth7680.8960.1040.399393.7 ± 13.13.8 ± 0.013.268.0
YOLO26m-depth7680.9210.0890.364621.5 ± 49.76.0 ± 0.123.3130.4
YOLO26l-depth7680.9300.0830.351821.9 ± 50.77.7 ± 0.127.7157.0
YOLO26x-depth7680.9330.0800.3441240.9 ± 73.313.6 ± 0.257.0301.7
  • delta1NYU 表示在 NYU Depth V2 Eigen 测试集(654 张图像)上,预测深度在真实值 1.25 倍范围内的像素百分比,使用多尺度 + 水平翻转 TTA 和对数最小二乘对齐。
  • 不使用 TTA 的单尺度精度可通过 yolo depth val model=yolo26n-depth.pt data=nyu-depth.yaml imgsz=768 device=0 复现(将每个尺寸替换为 model=),该方法使用中值(仅缩放)对齐,得分较低:delta1 为 0.783(n)、0.793(s)、0.840(m)、0.853(l)、0.860(x)。
  • abs_rel 表示预测深度值与真实深度值之间的平均绝对相对误差。
  • rmse 表示以米为单位的均方根误差。
  • 速度 是在 imgsz=768batch=1 下仅推理阶段的延迟(不包括预处理和后处理),表示预热后计时运行的平均值 ± 标准差。CPU ONNX 是在 32 核 Intel Xeon(Skylake)上使用 ONNX Runtime fp32;T4 TensorRT10 是在 Tesla T4 上使用 TensorRT fp16。
  • 参数量FLOPs 在 768×768 下测量,这是已发布权重的训练分辨率。

查看 unreleased YOLO27 preview 以获取初步的 NYU Depth V2 结果。

与 Depth Anything V2 的速度对比#

Depth Anything V2 是广泛使用的单目深度开源基线。其 DINOv2 视觉 Transformer 主干和 DPT 解码器计算量较大,因此在同一台 Tesla T4 上使用 TensorRT fp16 时,已发布的最小 Depth Anything V2 模型比所有 YOLO26 深度模型都慢——包括参数量超过其两倍的 YOLO26x-depth。

在约 768 像素下——YOLO26 使用 imgsz=768,即其已发布权重的训练分辨率;Depth Anything V2 使用 770 像素,因为其 DINOv2 主干要求输入尺寸是补丁大小 14 的倍数:

模型参数量(M)FLOPs(B)T4 TensorRT10(毫秒)FPS相对 V2 Small 的加速比相对 V2 Base 的加速比
Depth Anything V2 Base97.51025.555.4018.1
Depth Anything V2 Small24.8346.920.9947.6
YOLO26x-depth57.0301.713.5773.71.5×4.1×
YOLO26l-depth27.7157.07.68130.22.7×7.2×
YOLO26m-depth23.3130.46.00166.73.5×9.2×
YOLO26s-depth13.268.03.82261.65.5×14.5×
YOLO26n-depth6.346.92.73365.87.7×20.3×

在约 640 像素下——分别使用 imgsz=640 和 644 像素——排序保持不变,YOLO26n-depth 比 Depth Anything V2 Small 快 5.9 倍:

模型T4 TensorRT10(毫秒)FPS
Depth Anything V2 Base35.1028.5
Depth Anything V2 Small13.6273.4
YOLO26x-depth10.2697.5
YOLO26l-depth6.14162.8
YOLO26m-depth4.71212.1
YOLO26s-depth3.08324.4
YOLO26n-depth2.29436.9
  • 延迟仅指推理阶段,使用 batch=1,即 Tesla T4 上的 TensorRT fp16——与上方模型表使用的测试工具相同;此处显示为两位小数;FPS 是未四舍五入延迟的倒数。加速比列用 Depth Anything V2 Small(20.99 毫秒)和 Base(55.40 毫秒)的延迟除以 YOLO26 的延迟。
  • Depth Anything V2 Small 和 Base 分别是已发布的 ViT-S 和 ViT-B 检查点。
  • 此比较仅涵盖延迟——这里未根据统一的精度协议评估这两个模型系列。

深度范围与对数深度头#

深度头预测 exp(logit)——无界(约 0.02–150 米)——并且将场景形状与绝对尺度解耦:网络预测相对对数深度场,绝对米数通过单独的双参数变换(exp(a·log d + b))确定,该变换可在评估时、通过轻量级校准或微调恢复。常见的替代方案是有界的 sigmoid × max_depth 深度头,它会将固定上限写入架构,因此任何超过 max_depth 的深度都会被截断——这会阻止模型训练和预测更远距离的场景。

为什么深度头是无界的:跨深度范围的证据#

受控 A/B 测试——相同数据、相同训练计划,仅深度头不同。 在完全相同的室内(≤10 米)和室外(≤80 米)数据混合集上从头训练两个深度头:

深度头输出范围混合范围验证集 δ1训练行为
sigmoid × max_depth(10 米)有界 0–10 米0.221在第 1 个 epoch 达到平台期
log(无界)0–~150 m0.367 (+66%)持续提升

有界深度头无法表示室外像素中占多数的 >10 米深度,因此几乎立即停止提升;log 深度头则能从完整范围的数据中学习。

它所解决的失败模式——按范围分层的单数据集微调。 在单个数据集上微调有界(10 米)深度头时,当数据符合上限时可以正常工作,超出上限时则会崩溃:

数据集深度范围有界深度头 δ1
SUN RGB-D≤10 m0.78 ✅
Hypersim主要 ≤10 米0.74 ✅
KITTI~80 m0.08 ❌(abs_rel ≈ 7.0——80/10 的尺度不匹配)
vKITTI280 m0.04 ❌

崩溃点恰好位于上限边界。log 深度头不存在这样的边界。

已发布模型——跨范围性能。 已发布的 log 深度头模型系列在覆盖 10 米(NYU、iBims-1)到 80 米(KITTI)的基准数据集上进行评估,使用尺度对齐的 δ1:

基准范围YOLO26x-depth(log之前的有界版本
NYU Eigen10 m0.9330.934
iBims-110 m0.9610.945
ETH3D~60 m0.9590.931
Make3D~70 m0.3020.296
KITTI Eigen80 m0.9420.891
平均值0.8190.799

两列数据均按原文发布。其他行使用各数据集页面所述的 TTA 和对数最小二乘协议进行评分,而本仓库中的验证器未实现该协议,因此 KITTI 行无法在完全相同的条件下重新测量;KITTI 页面提供了在标准 652 帧 Eigen 划分上测量的数值。

最大收益出现在更远距离的室外基准数据集(KITTI、ETH3D)上——固定的 10 米上限正是在这些场景中影响最大——同时室内性能得以保留。

训练#

使用 Depth8 数据集训练 YOLO26n-depth,共 100 个 epoch,图像尺寸为 640。有关可用参数的完整列表,请参阅配置页面。

示例
from ultralytics import YOLO

# Load a model
model = YOLO("yolo26n-depth.yaml")  # build a new model from YAML
model = YOLO("yolo26n-depth.pt")  # load a pretrained model (recommended for training)
model = YOLO("yolo26n-depth.yaml").load("yolo26n-depth.pt")  # build from YAML and transfer weights

# Train the model
results = model.train(data="depth8.yaml", epochs=100, imgsz=640)

训练页面查看完整的 train 模式详情。

在自有数据上微调#

将预训练深度模型适配到自定义数据集时,请降低学习率并使用 AdamW 优化器。默认优化器设置针对从头训练进行了调优(使用 lr0=0.01 的 SGD);将其应用于已经收敛的深度模型可能会覆盖预训练知识并降低结果——尤其是在单一领域上进行微调时。

推荐的微调方案
from ultralytics import YOLO

model = YOLO("yolo26s-depth.pt")  # start from pretrained weights

model.train(
    data="path/to/your_dataset.yaml",
    epochs=20,
    imgsz=640,
    optimizer="AdamW",
    lr0=1e-4,  # ~100x below the from-scratch default
    warmup_bias_lr=1e-4,  # keep warmup gentle too
)

其他提示:

  • 数据增强由标准参数控制degreestranslatescaleshearperspectiveflipudfliplrhsv_hhsv_shsv_v);几何变换和翻转会以相同方式应用于配对深度图。要查看已发布 YOLO26-Depth 权重使用的确切方案,请检查检查点中存储的 train_args——参见检查 YOLO26 检查点训练参数
  • mosaicmixupcutmixcopy_paste 尚未针对深度任务实现。 深度数据集加载器会自动将这些概率设为 0,因此传入这些参数不会产生任何效果。不支持这些增强方式,是因为它们会组合多张图像,从而生成无效的配对深度图。
  • 任何深度范围都可以直接使用。 log 深度头模型预测无界深度,因此无需修改即可适应短距离(微距)或长距离(室外/驾驶)数据。在数据集 YAML 中设置 max_depth:(单位为米),可以限制验证指标统计所包含的真实值像素范围。
  • 保留通用性能。 如果你需要模型在超出训练集范围的场景中仍保持准确,请在训练数据中混入少量(约 5–10%)多样化的通用图像;这能显著减少微调期间的遗忘。
  • 仅在领域差异很大且拥有大型数据集时才从头训练model=yolo26s-depth.yaml)——此时默认的 SGD lr0=0.01 是合适的,因为没有需要保留的预训练权重。

校准深度尺度#

深度头将形状(相对场景结构)与尺度(绝对米数)分离。如果模型已经能在你的场景中生成良好的相对深度,但绝对值不适合你的相机,你可以使用 model.calibrate() 在几秒内校正尺度——该方法根据少量带标签数据,对双参数对数仿射变换进行闭式拟合,无需梯度训练,也不会改变网络权重,因此不会降低相对结构。

尺度校准
from ultralytics import YOLO

model = YOLO("yolo26s-depth.pt")

# Fit scale on a labeled split (~100+ images is enough), then persist it
model.calibrate(data="path/to/your_dataset.yaml")
model.save("yolo26s-depth-calibrated.pt")

校准需要真实深度作为拟合依据,因此会在带标注的数据划分上运行——这无法在盲推理时完成。它会在与 val 指标评估相同的像素上进行拟合和评分:数据集 YAML 中达到或超过 max_depth(默认 100 m)的 GT 将被排除。当相对深度已经很好、只有尺度/范围不正确时,可以使用它;如果相对结构本身需要针对你的领域进行调整,请改用fine-tune

训练会自动为你完成此操作:model.train(...) 完成后,最佳和最后一个检查点都会在验证集上进行校准,从而开箱即用地输出经过度量尺度校准的深度。

发布的 yolo26*-depth.pt 检查点已经内置了此校准,该校准基于预训练验证数据混合集拟合得到。它是在所有领域之间共享的单一全局尺度,因此如果要在特定相机或场景类型上获得最准确的绝对深度,请在你自己的数据中取一个小型带标注划分,运行 model.calibrate()——它会替换内置的拟合结果。

数据集格式#

深度估计数据集会将每张 RGB 图像与经过缩放的 uint16 深度 PNG 或以米为单位的浮点 NPY 深度图配对。PNG 值默认使用毫米;采用其他约定的数据集会在其 YAML 中设置 depth_scale。加载器会通过将 images 组件替换为 depth 来推导深度路径,优先使用 .png,找不到时回退到 .npy

dataset/
├── images/
│   ├── train/
│   └── val/
└── depth/
    ├── train/
    └── val/

例如,路径为 images/train/scene_001.jpg 的图像会与路径为 depth/train/scene_001.png 的深度图配对。有关完整的格式规范,请参阅《深度估计数据集指南》

验证#

在深度估计数据集上验证训练好的 YOLO26n-depth 模型的准确率。请显式传入 data,以确保验证使用指定的数据集 YAML。发布的权重是在 imgsz=768 尺寸下训练的,因此请以该尺寸进行验证和预测,以获得最佳准确率。

示例
from ultralytics import YOLO

# Load a model
model = YOLO("yolo26n-depth.pt")  # load an official model
model = YOLO("path/to/best.pt")  # load a custom model

# Validate the model
metrics = model.val(data="nyu-depth.yaml")
metrics.delta1  # percentage of pixels within threshold δ=1.25
metrics.abs_rel  # mean absolute relative error
metrics.rmse  # root mean squared error (meters)
metrics.silog  # scale-invariant logarithmic error

Predict#

使用训练好的 YOLO26n-depth 模型对图像运行预测。

示例
from ultralytics import YOLO

# Load a model
model = YOLO("yolo26n-depth.pt")  # load an official model
model = YOLO("path/to/best.pt")  # load a custom model

# Predict with the model
results = model("https://ultralytics.com/images/bus.jpg")  # predict on an image

# Access the results
for result in results:
    depth_map = result.depth.data.cpu().numpy()  # torch.Tensor -> NumPy float32, shape (H, W), meters

请在预测页面查看完整的 predict 模式详情。

结果输出#

YOLO 深度估计会为每张图像返回一个 Results 对象。每个结果都会存储一张覆盖整幅图像的稠密浮点深度图。

属性类型形状描述
result.depthDepthMap(H,W)逐像素稠密深度图。
result.depth.datatorch.Tensor(H,W)以米为单位的深度值;调用 .cpu().numpy() 可获取 NumPy。
result.boxes--没有实例框。
result.masks--没有实例掩码。

有关每项任务中任务专用的 Results 字段,请参阅按任务划分的预测结果部分。

为深度图着色#

原始深度图是一个以米为单位的单通道浮点数组——适合计算,但难以直接阅读。要将其转换为彩色图像,请使用 ultralytics.utils.plotting 中的 colorize_depth 辅助函数,该函数会将 (H, W) 深度数组映射为 (H, W, 3) BGR uint8 图像(无效像素 <= 0 会渲染为黑色)。

result.plot() 已经使用默认设置(cmap="jet"mode="disparity")将此着色结果叠加到输入图像上;如果需要独立的彩色深度图,或需要使用不同的颜色映射或归一化方式,请直接调用 colorize_depth

为预测的深度图着色
import cv2

from ultralytics import YOLO
from ultralytics.utils.plotting import colorize_depth

model = YOLO("yolo26n-depth.pt")
result = model("https://ultralytics.com/images/bus.jpg")[0]

depth = result.depth.data.cpu().numpy()  # (H, W) float32, meters

# Colorize with near = warm and save
cv2.imwrite("depth_colored.png", colorize_depth(depth, cmap="spectral"))  # (H, W, 3) BGR uint8

# Fix the range to 0-20 m so the same color means the same distance across frames
cv2.imwrite("depth_metric.png", colorize_depth(depth, vmin=0.0, vmax=20.0, cmap="inferno", mode="metric"))

# Blended overlay straight from the Results object (uses cmap="jet", mode="disparity")
result.save("depth_overlay.png")

每种颜色映射都从冷色/暗色过渡到暖色/亮色。mode 决定哪一端表示近处,vmin/vmax 会在帧之间固定范围,从而确保同一种颜色始终表示相同的距离。

参数描述
cmapjet(默认)高对比度的蓝 → 绿 → 红,即 result.plot() 使用的调色板。
cmapinferno黑 → 紫 → 橙 → 黄。感知均匀、适合色觉障碍者,在灰度图中也清晰易读。
cmapspectral红 → 黄 → 绿 → 蓝(matplotlib Spectral_r)。
modedisparity(默认)在第 2 和第 98 百分位之间对逆深度(1/d)进行归一化;暖色标记近处和远处的异常值会被吸收。
modemetricvminvmax 之间对以米为单位的深度进行线性归一化;暖色表示远处,因此颜色能够反映真实距离。

导出#

将 YOLO26n-depth 模型导出为 ONNX、CoreML 等其他格式。

示例
from ultralytics import YOLO

# Load a model
model = YOLO("yolo26n-depth.pt")  # load an official model
model = YOLO("path/to/best.pt")  # load a custom model

# Export the model
model.export(format="onnx")

下表列出了可用的 YOLO26 深度估计导出格式。你可以使用 format 参数导出为任意格式,例如 format='onnx'format='engine'。你也可以直接在导出的模型上进行预测或验证,例如 yolo predict model=yolo26n-depth.onnx。导出完成后,系统会为你的模型显示用法示例。

格式format 参数模型元数据参数
PyTorch-yolo26n-depth.pt-
TorchScripttorchscriptyolo26n-depth.torchscriptimgszquantizedynamicnmsbatchdevice
ONNXonnxyolo26n-depth.onnximgszquantizedynamicsimplifyopsetnmsbatchdatafractiondevice
OpenVINOopenvinoyolo26n-depth_openvino_model/imgszquantizedynamicnmsbatchdatafractiondevice
TensorRTengineyolo26n-depth.engineimgszquantizedynamicsimplifyopsetworkspacenmsbatchdatafractiondevice
CoreMLcoremlyolo26n-depth.mlpackageimgszdynamicquantizenmsbatchdevice
TF SavedModelsaved_modelyolo26n-depth_saved_model/imgszkerasquantizeopsetnmsbatchdatafractiondevice
TF GraphDefpbyolo26n-depth.pbimgszopsetbatchdevice
TF Edge TPUedgetpuyolo26n-depth_edgetpu.tfliteimgszquantizeopsetdatafractiondevice
PaddlePaddlepaddleyolo26n-depth_paddle_model/imgszbatchdevice
MNNmnnyolo26n-depth.mnnimgszbatchdynamicquantizesimplifyopsetnmsdevice
NCNNncnnyolo26n-depth_ncnn_model/imgszquantizebatchdevice
IMX500imxyolo26n-depth_imx_model/imgszquantizedatafractionnmsdevice
RKNNrknnyolo26n-depth_rknn_model/imgszbatchnamequantizesimplifyopsetdatafractiondevice
ExecuTorchexecutorchyolo26n-depth_executorch_model/imgszbatchdevice
Axeleraaxelerayolo26n-depth_axelera_model/imgszbatchquantizedatafractiondevice
DEEPXdeepxyolo26n-depth_deepx_model/imgszquantizesimplifyopsetdataoptimizedevice
Qualcomm QNNqnnyolo26n-depth_qnn.onnximgszbatchnamequantizesimplifyopsetdatafractiondevice
LiteRTlitertyolo26n-depth.tfliteimgszquantizebatchdatafractiondevice
Hailohailoyolo26n-depth_hailo_model/imgsznamequantizedatafractionsimplifyconfiou
Huawei Ascendascendyolo26n-depth_ascend_model/imgszbatchnamequantizeopsetsimplifynms
Apple Core AIcoreaiyolo26n-depth.aimodelimgszbatchquantize

nms=None 默认对外部 NMS 使用原始输出。设置 nms=False 以选择可用的无 NMS 检测头;不支持的格式将回退到其本机输出路径。上面的 nms 条目标识了可以通过 nms=True 嵌入 NMS 的格式。

请在导出页面查看完整的 export 详情。

常见问题#

  • 准备成对的 RGB 图像以及 16 位深度 PNG 或以米为单位的浮点 NPY 深度图,然后创建一个数据集 YAML,指向你的 images/ 目录。加载器会通过在路径中将 images 替换为 depth 来自动查找深度文件,优先使用 .png,找不到时回退到 .npy

    从预训练权重开始,并使用较低的学习率和 AdamW,以便微调保留模型已经学到的内容(有关原因,请参阅在你自己的数据上进行微调:)

    示例
    from ultralytics import YOLO
    
    # Load a pretrained YOLO26 depth model
    model = YOLO("yolo26s-depth.pt")
    
    # Fine-tune on a custom depth dataset
    results = model.train(
        data="path/to/your_dataset.yaml",
        epochs=20,
        imgsz=640,
        optimizer="AdamW",
        lr0=1e-4,
        warmup_bias_lr=1e-4,
    )

    请查看配置页面,了解更多可用参数。

  • 深度估计验证会报告 Depth Anything 及相关单目深度研究所使用的指标集:

    • delta1 / delta2 / delta3 —— 预测深度与真实深度之比(或其倒数)分别低于 1.25、1.25² 和 1.25³ 的像素百分比。数值越高越好。
    • abs_rel —— 平均绝对相对误差。数值越低越好。
    • rmse —— 以米为单位的均方根误差。数值越低越好。
    • silog —— 尺度不变对数误差。数值越低越好。

    每张图像中的每个预测都会与该图像的真实值进行中值对齐,每个指标都会在该图像上完成计算,然后将每张图像的结果在验证集上取平均。因此,无论图像包含多少有效深度像素,每张图像的权重都相同。有效真实深度像素少于 10 个的图像会被跳过,不计入平均值,因为对少量像素取中值进行对齐没有意义;非有限预测值则会按照深度边界进行评分。这与 Depth Anything V2 使用的逐样本平均方式和 10 像素下限一致。

  • 深度图以形状为 (H, W)torch.Tensor 存储,其中每个值都是以米为单位的预测深度(使用 result.depth.data.cpu().numpy() 获取 NumPy float32 数组)。运行预测后,可通过 result.depth.data 访问它。该图与输入图像分辨率对齐。

  • Ultralytics YOLO26 内置了多个深度估计数据集的数据集 YAML 配置,包括 NYU Depth V2、KITTI、Hypersim、SUN RGB-D 和 ARKitScenes。完整列表和格式详情请参阅深度估计数据集指南

  • 提供用于评估的数据集 YAML,即可验证预训练的 YOLO26 深度模型:

    示例
    from ultralytics import YOLO
    
    # Load a pretrained model
    model = YOLO("yolo26n-depth.pt")
    
    # Validate the model
    metrics = model.val(data="nyu-depth.yaml")
    print("delta1:", metrics.delta1)
    print("abs_rel:", metrics.abs_rel)
    print("rmse:", metrics.rmse)
  • 使用 Python 或 CLI 将 YOLO26 深度模型导出为 ONNX:

    示例
    from ultralytics import YOLO
    
    # Load a pretrained model
    model = YOLO("yolo26n-depth.pt")
    
    # Export the model to ONNX format
    model.export(format="onnx")

    有关导出为各种格式的更多详情,请参阅导出页面。

评论