Datasets 文档

深度估计

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

深度估计

深度估计数据集用于训练模型以近似图像中每个像素点距离相机的相对距离,这也被称为“深度”。这些数据集所实现的应用程序主要集中在视觉机器感知和机器人感知等领域。应用示例包括为自动驾驶汽车绘制街道地图。本指南将向您展示如何对深度估计数据集应用变换。

在开始之前,请确保您已安装最新版本的 albumentations

pip install -U albumentations 

Albumentations 是一个用于计算机视觉数据增强的 Python 库。它支持各种计算机视觉任务,如图像分类、目标检测、分割和关键点估计。

本指南使用 NYU Depth V2 数据集,该数据集由 RGB 和深度相机记录的各种室内场景的视频序列组成。该数据集包含来自 3 个城市的场景,并提供图像及其作为标签的深度图。

加载数据集的 train 分片并查看一个示例

>>> from datasets import load_dataset

>>> train_dataset = load_dataset("sayakpaul/nyu_depth_v2", split="train")
>>> index = 17
>>> example = train_dataset[index]
>>> example
{'image': <PIL.PngImagePlugin.PngImageFile image mode=RGB size=640x480>,
 'depth_map': <PIL.TiffImagePlugin.TiffImageFile image mode=F size=640x480>}

该数据集有两个字段

  • image:一个数据类型为 uint8 的 PIL PNG 图像对象。
  • depth_map:一个数据类型为 float32 的 PIL Tiff 图像对象,它是该图像的深度图。

这里深度图使用了 TIFF 格式,因为它支持广泛的数据类型,包括 float32 数据。不过值得一提的是,JPEG/PNG 格式只能存储 uint8uint16 数据。因此,如果您的深度图保存为 JPEG/PNG,请使用 Image(mode="F") 类型将其加载为单通道 float32,就像普通的深度图一样。

>>> from datasets import Image

>>> train_dataset = train_dataset.cast_column("depth_map", Image(mode="F"))

接下来,查看一张图像

>>> example["image"]

在查看深度图之前,我们需要先使用 .convert('RGB') 将其数据类型转换为 uint8,因为 PIL 无法显示 float32 图像。现在来看看其对应的深度图

>>> example["depth_map"].convert("RGB")

全是黑色的!您需要为深度图添加一些颜色才能正确地可视化它。为此,我们既可以在显示期间使用 plt.imshow() 自动应用颜色,也可以使用 plt.cm 创建彩色深度图然后再显示。在本示例中,我们使用了后者,因为我们之后可以保存/写入该彩色深度图。(下面的实用程序取自 FastDepth 仓库)。

>>> import numpy as np
>>> import matplotlib.pyplot as plt

>>> cmap = plt.cm.viridis

>>> def colored_depthmap(depth, d_min=None, d_max=None):
...     if d_min is None:
...         d_min = np.min(depth)
...     if d_max is None:
...         d_max = np.max(depth)
...     depth_relative = (depth - d_min) / (d_max - d_min)
...     return 255 * cmap(depth_relative)[:,:,:3]

>>> def show_depthmap(depth_map):
...    if not isinstance(depth_map, np.ndarray):
...        depth_map = np.array(depth_map)
...    if depth_map.ndim == 3:
...        depth_map = depth_map.squeeze()

...    d_min = np.min(depth_map)
...    d_max = np.max(depth_map)
...    depth_map = colored_depthmap(depth_map, d_min, d_max)

...    plt.imshow(depth_map.astype("uint8"))
...    plt.axis("off")
...    plt.show()

>>> show_depthmap(example["depth_map"])

您还可以可视化多张不同的图像及其对应的深度图。

>>> def merge_into_row(input_image, depth_target):
...     if not isinstance(input_image, np.ndarray):
...         input_image = np.array(input_image)
...
...     d_min = np.min(depth_target)
...     d_max = np.max(depth_target)
...     depth_target_col = colored_depthmap(depth_target, d_min, d_max)
...     img_merge = np.hstack([input_image, depth_target_col])
...
...     return img_merge

>>> random_indices = np.random.choice(len(train_dataset), 9).tolist()
>>> plt.figure(figsize=(15, 6))
>>> for i, idx in enumerate(random_indices):
...     example = train_dataset[idx]
...     ax = plt.subplot(3, 3, i + 1)
...     image_viz = merge_into_row(
...         example["image"], example["depth_map"]
...     )
...     plt.imshow(image_viz.astype("uint8"))
...     plt.axis("off")

现在使用 albumentations 应用一些增强。增强变换包括

  • 随机水平翻转
  • 随机裁剪
  • 随机亮度与对比度
  • 随机伽马校正
  • 随机色相饱和度
>>> import albumentations as A

>>> crop_size = (448, 576)
>>> transforms = [
...     A.HorizontalFlip(p=0.5),
...     A.RandomCrop(crop_size[0], crop_size[1]),
...     A.RandomBrightnessContrast(),
...     A.RandomGamma(),
...     A.HueSaturationValue()
... ]

此外,定义一个映射以更好地反映目标键名。

>>> additional_targets = {"depth": "mask"}
>>> aug = A.Compose(transforms=transforms, additional_targets=additional_targets)

定义了 additional_targets 后,您可以将目标深度图传递给 augdepth 参数而非 mask 参数。您将在下面定义的 apply_transforms() 函数中注意到这一变化。

创建一个函数,将变换应用于图像及其深度图

>>> def apply_transforms(examples):
...     transformed_images, transformed_maps = [], []
...     for image, depth_map in zip(examples["image"], examples["depth_map"]):
...         image, depth_map = np.array(image), np.array(depth_map)
...         transformed = aug(image=image, depth=depth_map)
...         transformed_images.append(transformed["image"])
...         transformed_maps.append(transformed["depth"])
...
...     examples["pixel_values"] = transformed_images
...     examples["labels"] = transformed_maps
...     return examples

使用 set_transform() 函数对数据集批次进行即时(on-the-fly)转换,以减少磁盘空间占用

>>> train_dataset.set_transform(apply_transforms)

您可以通过索引示例图像的 pixel_valueslabels 来验证变换是否生效

>>> example = train_dataset[index]

>>> plt.imshow(example["pixel_values"])
>>> plt.axis("off")
>>> plt.show()

在图像对应的深度图上可视化相同的变换

>>> show_depthmap(example["labels"])

您还可以复用之前的 random_indices 来可视化多个训练样本

>>> plt.figure(figsize=(15, 6))

>>> for i, idx in enumerate(random_indices):
...     ax = plt.subplot(3, 3, i + 1)
...     example = train_dataset[idx]
...     image_viz = merge_into_row(
...         example["pixel_values"], example["labels"]
...     )
...     plt.imshow(image_viz.astype("uint8"))
...     plt.axis("off")
在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.