Transformers 文档

单目深度估计

Hugging Face's logo
加入 Hugging Face 社区

并获取增强的文档体验

开始使用

单目深度估计

单目深度估计是一项计算机视觉任务,涉及从单张图像预测场景的深度信息。换句话说,它是从单个相机视点估计场景中物体距离的过程。

单目深度估计有多种应用,包括 3D 重建、增强现实、自动驾驶和机器人技术。这是一项具有挑战性的任务,因为它要求模型理解场景中物体与相应深度信息之间的复杂关系,而这些关系可能受到光照条件、遮挡和纹理等因素的影响。

主要有两种深度估计类别

  • 绝对深度估计:此任务变体旨在提供来自相机的精确深度测量值。该术语与度量深度估计互换使用,其中深度以米或英尺为单位提供精确测量值。绝对深度估计模型输出深度图,其数值表示真实世界的距离。

  • 相对深度估计:相对深度估计旨在预测场景中物体或点的深度顺序,而无需提供精确的测量值。这些模型输出一个深度图,指示场景的哪些部分彼此之间更近或更远,而没有到 A 和 B 的实际距离。

在本指南中,我们将了解如何使用 Depth Anything V2(一种最先进的零样本相对深度估计模型)和 ZoeDepth(一种绝对深度估计模型)进行推理。

查看深度估计任务页面以查看所有兼容的架构和检查点。

在我们开始之前,我们需要安装最新版本的 Transformers

pip install -q -U transformers

深度估计 pipeline

尝试使用支持深度估计的模型进行推理的最简单方法是使用相应的pipeline()。从 Hugging Face Hub 上的检查点实例化一个 pipeline

>>> from transformers import pipeline
>>> import torch
>>> from accelerate.test_utils.testing import get_backend
# automatically detects the underlying device type (CUDA, CPU, XPU, MPS, etc.)
>>> device, _, _ = get_backend()
>>> checkpoint = "depth-anything/Depth-Anything-V2-base-hf"
>>> pipe = pipeline("depth-estimation", model=checkpoint, device=device)

接下来,选择要分析的图像

>>> from PIL import Image
>>> import requests

>>> url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/bee.jpg"
>>> image = Image.open(requests.get(url, stream=True).raw)
>>> image
Photo of a bee

将图像传递给 pipeline。

>>> predictions = pipe(image)

pipeline 返回一个包含两个条目的字典。第一个条目名为 predicted_depth,是一个张量,其值为每个像素的深度(以米为单位)。第二个条目 depth 是一个 PIL 图像,可视化了深度估计结果。

让我们看一下可视化结果

>>> predictions["depth"]
Depth estimation visualization

手动进行深度估计推理

既然您已经了解了如何使用深度估计 pipeline,那么让我们看看如何手动复制相同的结果。

首先从 Hugging Face Hub 上的检查点加载模型和相关的处理器。这里我们将使用与之前相同的检查点

>>> from transformers import AutoImageProcessor, AutoModelForDepthEstimation

>>> checkpoint = "Intel/zoedepth-nyu-kitti"

>>> image_processor = AutoImageProcessor.from_pretrained(checkpoint)
>>> model = AutoModelForDepthEstimation.from_pretrained(checkpoint).to(device)

使用 image_processor 为模型准备图像输入,它将负责必要的图像转换,例如调整大小和归一化

>>> pixel_values = image_processor(image, return_tensors="pt").pixel_values.to(device)

将准备好的输入传递给模型

>>> import torch

>>> with torch.no_grad():
...     outputs = model(pixel_values)

让我们对结果进行后处理,以删除任何填充并将深度图调整大小以匹配原始图像大小。post_process_depth_estimation 输出一个字典列表,其中包含 "predicted_depth"。

>>> # ZoeDepth dynamically pads the input image. Thus we pass the original image size as argument
>>> # to `post_process_depth_estimation` to remove the padding and resize to original dimensions.
>>> post_processed_output = image_processor.post_process_depth_estimation(
...     outputs,
...     source_sizes=[(image.height, image.width)],
... )

>>> predicted_depth = post_processed_output[0]["predicted_depth"]
>>> depth = (predicted_depth - predicted_depth.min()) / (predicted_depth.max() - predicted_depth.min())
>>> depth = depth.detach().cpu().numpy() * 255
>>> depth = Image.fromarray(depth.astype("uint8"))

原始实现中,ZoeDepth 模型对原始图像和翻转图像都执行推理,并对结果进行平均。post_process_depth_estimation 函数可以通过将翻转后的输出传递给可选的 outputs_flipped 参数来为我们处理这个问题

>>> with torch.no_grad():   
...     outputs = model(pixel_values)
...     outputs_flipped = model(pixel_values=torch.flip(inputs.pixel_values, dims=[3]))
>>> post_processed_output = image_processor.post_process_depth_estimation(
...     outputs,
...     source_sizes=[(image.height, image.width)],
...     outputs_flipped=outputs_flipped,
... )
Depth estimation visualization
< > 在 GitHub 上更新