单目深度估计
单目深度估计是一项计算机视觉任务,旨在从单张图像中预测场景的深度信息。换言之,即从单一相机视角估计场景中物体的距离。
单目深度估计具有多种应用,包括 3D 重建、增强现实、自动驾驶和机器人技术。这是一项具有挑战性的任务,因为模型需要理解场景中物体与相应深度信息之间的复杂关系,而这些关系会受到光照条件、遮挡和纹理等因素的影响。
深度估计主要有两个类别:
绝对深度估计:该任务变体旨在从相机获取精确的深度测量值。该术语与度量深度估计互换使用,其中深度以米或英尺的精确测量值表示。绝对深度估计模型输出的深度图包含代表真实世界距离的数值。
相对深度估计:相对深度估计旨在预测场景中物体或点的深度顺序,而不提供精确的测量值。这些模型输出的深度图仅指示场景中各部分之间的相对远近关系,而不包含到 A 和 B 的实际距离。
在本指南中,我们将了解如何使用最先进的零样本相对深度估计模型 Depth Anything V2 以及绝对深度估计模型 ZoeDepth 进行推理。
请查看 Depth Estimation 任务页面,以查看所有兼容的架构和检查点。
在开始之前,我们需要安装最新版本的 Transformers:
pip install -q -U transformers
深度估计流水线
尝试使用支持深度估计的模型进行推理的最简单方法是使用对应的 pipeline()。 从 Hugging Face Hub 上的检查点 实例化一个 pipeline:
>>> from transformers import pipeline
from accelerate import Accelerator
>>> import torch
>>> device = Accelerator().device
>>> 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
将图像传入 pipeline。
>>> predictions = pipe(image)该 pipeline 返回一个包含两个条目的字典。第一个条目名为 predicted_depth,是一个张量,其值为每个像素以米为单位的深度。第二个条目 depth 是一张 PIL 图像,用于可视化深度估计结果。
让我们来看一下可视化结果:
>>> predictions["depth"]
手动进行深度估计推理
现在你已经了解了如何使用深度估计流水线,接下来让我们看看如何手动复现相同的结果。
首先,从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, ... )
