Datasets documentation

깊이 추정

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v4.8.4).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

깊이 추정

Depth estimation datasets는 이미지 내 모든 픽셀의 카메라로부터의 상대적 거리, 즉 깊이(depth)를 근사하도록 모델을 학습하는 데 사용됩니다. 이러한 데이터셋이 가능하게 하는 응용 분야는 주로 시각적 기계 인식(visual machine perception) 및 로봇공학에서의 인식(perception) 영역에 있습니다. 응용 사례로는 자율주행 차량을 위한 도로 매핑이 있습니다. 이 가이드에서는 depth estimation dataset에 변환(transformations)을 적용하는 방법을 보여 드립니다.

시작하기 전에 albumentations의 최신 버전이 설치되어 있는지 확인하세요:

pip install -U albumentations 

Albumentations는 컴퓨터 비전을 위한 데이터 증강을 수행하는 Python 라이브러리입니다. 이미지 분류, 객체 감지, 분할, 키포인트 추정과 같은 다양한 컴퓨터 비전 작업을 지원합니다.

이 가이드는 다양한 실내 장면에서 RGB 카메라와 깊이 카메라로 촬영된 비디오 시퀀스로 구성된 NYU Depth V2 데이터셋을 사용합니다. 이 데이터셋은 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 이미지 객체로, 이미지의 깊이 맵입니다.

여기서 깊이 맵은 float32 데이터를 포함하는 다양한 데이터 타입을 지원하기 때문에 TIFF 형식을 사용합니다. 다만 JPEG/PNG 형식은 uint8 또는 uint16 데이터만 저장할 수 있다는 점을 언급할 가치가 있습니다. 따라서 JPEG/PNG로 저장된 깊이 맵이 있는 경우, Image(mode="F") 타입을 사용하여 일반 깊이 맵처럼 단일 채널 float32로 로드하세요:

>>> from datasets import Image

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

다음으로, 다음 명령어로 이미지를 확인해 보세요:

>>> example["image"]

깊이 맵을 보기 전에, PIL은 float32 이미지를 표시할 수 없으므로 .convert('RGB')를 사용하여 데이터 유형을 uint8로 변환해야 합니다. 이제 해당 깊이 맵을 확인해 보세요:

>>> 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가 정의된 경우, mask 대신 aug의 depth 인자에 대상 깊이 맵을 전달할 수 있습니다. 아래에 정의된 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() 함수를 사용하여 데이터셋의 배치에 변환을 온더플라이로 적용하여 디스크 공간을 덜 사용하도록 할 수 있습니다:

>>> train_dataset.set_transform(apply_transforms)

pixel_values와 labels에 인덱싱하여 예시 이미지의 변환이 제대로 수행되었는지 확인할 수 있습니다:

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