Datasets documentation

Estimativa de profundidade

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Estimativa de profundidade

Conjuntos de dados de estimativa de profundidade são usados para treinar um modelo a aproximar a distância relativa de cada pixel em uma imagem em relação à câmera, também conhecida como profundidade. As aplicações habilitadas por esses conjuntos de dados estão principalmente em áreas como percepção visual de máquinas e percepção em robótica. Exemplos de aplicações incluem o mapeamento de ruas para carros autônomos. Este guia mostrará como aplicar transformações a um conjunto de dados de estimativa de profundidade.

Antes de começar, verifique se você tem as versões mais recentes de albumentations instaladas:

pip install -U albumentations 

Albumentations é uma biblioteca em Python para realizar aumento de dados para visão computacional. Ela suporta diversas tarefas de visão computacional, como classificação de imagens, detecção de objetos, segmentação e estimativa de pontos-chave.

Este guia utiliza o conjunto de dados NYU Depth V2, que é composto por sequências de vídeo de diversas cenas internas, gravadas por câmeras RGB e de profundidade. O conjunto de dados consiste em cenas de 3 cidades e fornece imagens juntamente com seus mapas de profundidade como rótulos.

Carregue o split train do conjunto de dados e veja um exemplo:

>>> 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>}

O conjunto de dados possui dois campos:

  • image: um objeto de imagem PNG da PIL com tipo de dados uint8.
  • depth_map: um objeto de imagem PIL Tiff com tipo de dados float32, que é o mapa de profundidade da imagem.

Aqui, os mapas de profundidade usam o formato TIFF, pois ele suporta uma ampla variedade de tipos de dados, incluindo dados float32. No entanto, vale mencionar que o formato JPEG/PNG só pode armazenar dados uint8 ou uint16. Portanto, se você tiver mapas de profundidade salvos como JPEG/PNG, use o tipo Image(mode="F") para carregá-los como float32 de canal único, como os mapas de profundidade normais:

>>> from datasets import Image

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

A seguir, verifique uma imagem com:

>>> example["image"]

Antes de analisarmos o mapa de profundidade, precisamos primeiro converter seu tipo de dados para uint8 usando .convert('RGB'), pois o PIL não consegue exibir imagens float32. Agora, observe o mapa de profundidade correspondente:

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

Tudo está preto! Você precisará adicionar alguma cor ao mapa de profundidade para visualizá-lo corretamente. Para isso, podemos aplicar a colorização automaticamente durante a exibição usando plt.imshow() ou criar um mapa de profundidade colorido usando plt.cm e, em seguida, exibi-lo. Neste exemplo, usamos a segunda opção, pois podemos salvar/escrever o mapa de profundidade colorido posteriormente. (a utilidade abaixo foi retirada do repositório 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"])

Você também pode visualizar várias imagens diferentes e seus mapas de profundidade correspondentes.

>>> 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")

Agora aplique algumas aumentações com albumentations. As transformações de aumento incluem:

  • Inversão horizontal aleatória
  • Recorte aleatório
  • Brilho e contraste aleatórios
  • Correção gama aleatória
  • Saturação de matiz aleatória
>>> 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()
... ]

Além disso, defina um mapeamento para refletir melhor o nome da chave de destino.

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

Com additional_targets definido, você pode passar os mapas de profundidade de destino para o argumento depth de aug em vez de mask. Você notará essa mudança na função apply_transforms() definida abaixo.

Crie uma função para aplicar a transformação às imagens, bem como aos seus mapas de profundidade:

>>> 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

Use a função set_transform() para aplicar a transformação em tempo real aos lotes do conjunto de dados, consumindo menos espaço em disco:

>>> train_dataset.set_transform(apply_transforms)

Você pode verificar se a transformação funcionou indexando os pixel_values e labels de uma imagem de exemplo:

>>> example = train_dataset[index]

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

Visualize a mesma transformação no mapa de profundidade correspondente à imagem:

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

Você também pode visualizar várias amostras de treinamento reutilizando o random_indices anterior:

>>> 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")
Update on GitHub