Datasets documentation
Ước lượng độ sâu
Ước lượng độ sâu
Bộ dữ liệu ước lượng độ sâu được sử dụng để huấn luyện mô hình xấp xỉ khoảng cách tương đối của từng pixel trong một hình ảnh so với máy ảnh, còn được gọi là độ sâu. Các ứng dụng được hỗ trợ bởi những bộ dữ liệu này chủ yếu nằm trong các lĩnh vực như nhận thức thị giác của máy và nhận thức trong robot. Ví dụ về ứng dụng bao gồm lập bản đồ đường phố cho xe tự lái. Hướng dẫn này sẽ cho bạn thấy cách áp dụng các phép biến đổi cho một bộ dữ liệu ước lượng độ sâu.
Trước khi bắt đầu, hãy đảm bảo bạn đã cài đặt các phiên bản mới nhất của albumentations:
pip install -U albumentations
Albumentations là một thư viện Python để thực hiện tăng cường dữ liệu cho thị giác máy tính. Nó hỗ trợ nhiều tác vụ thị giác máy tính khác nhau như phân loại ảnh, phát hiện đối tượng, phân đoạn và ước lượng điểm chính.
Hướng dẫn này sử dụng bộ dữ liệu NYU Depth V2, bao gồm các chuỗi video từ nhiều cảnh trong nhà khác nhau, được ghi lại bằng camera RGB và camera độ sâu. Bộ dữ liệu bao gồm các cảnh từ 3 thành phố và cung cấp các hình ảnh cùng với bản đồ độ sâu tương ứng của chúng dưới dạng nhãn.
Tải phần train của bộ dữ liệu và xem một ví dụ:
>>> 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>}Bộ dữ liệu có hai trường:
image: một đối tượng ảnh PNG PIL có kiểu dữ liệuuint8.depth_map: một đối tượng ảnh PIL Tiff có kiểu dữ liệufloat32, là bản đồ độ sâu của ảnh.
Ở đây, các bản đồ độ sâu sử dụng định dạng TIFF vì định dạng này hỗ trợ nhiều kiểu dữ liệu, bao gồm dữ liệu float32.
Tuy nhiên, cần lưu ý rằng định dạng JPEG/PNG chỉ có thể lưu trữ dữ liệu uint8 hoặc uint16.
Do đó, nếu bạn có các bản đồ độ sâu được lưu dưới dạng JPEG/PNG, hãy sử dụng kiểu Image(mode="F") để tải chúng dưới dạng float32 một kênh như các bản đồ độ sâu thông thường:
>>> from datasets import Image
>>> train_dataset = train_dataset.cast_column("depth_map", Image(mode="F"))Tiếp theo, hãy xem một hình ảnh bằng cách sử dụng:
>>> example["image"]
Trước khi xem bản đồ độ sâu, chúng ta cần chuyển kiểu dữ liệu của nó sang uint8 bằng cách sử dụng .convert('RGB') vì PIL không thể hiển thị các hình ảnh float32. Bây giờ hãy xem bản đồ độ sâu tương ứng của nó:
>>> example["depth_map"].convert("RGB")
Tất cả đều đen! Bạn cần thêm màu vào bản đồ độ sâu để hiển thị nó một cách chính xác. Để làm điều đó, chúng ta có thể tự động áp dụng màu trong quá trình hiển thị bằng plt.imshow() hoặc tạo một bản đồ độ sâu có màu bằng plt.cm rồi hiển thị nó. Trong ví dụ này, chúng ta sử dụng phương án sau, vì có thể lưu/ghi lại bản đồ độ sâu có màu sau đó. (hàm tiện ích bên dưới được lấy từ FastDepth repository).
>>> 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"])
Bạn cũng có thể trực quan hóa nhiều hình ảnh khác nhau cùng với các bản đồ độ sâu tương ứng của chúng.
>>> 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")
Bây giờ hãy áp dụng một số phép tăng dữ liệu bằng albumentations. Các phép biến đổi tăng dữ liệu bao gồm:
- Lật ngang ngẫu nhiên
- Cắt ngẫu nhiên
- Độ sáng và độ tương phản ngẫu nhiên
- Hiệu chỉnh gamma ngẫu nhiên
- Bão hòa sắc ngẫu nhiên
>>> 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()
... ]Ngoài ra, hãy định nghĩa một ánh xạ để phản ánh chính xác hơn tên khóa đích.
>>> additional_targets = {"depth": "mask"}
>>> aug = A.Compose(transforms=transforms, additional_targets=additional_targets)Khi đã định nghĩa additional_targets, bạn có thể truyền các bản đồ độ sâu đích vào tham số depth của aug thay vì mask. Bạn sẽ nhận thấy thay đổi này trong hàm apply_transforms() được định nghĩa bên dưới.
Tạo một hàm để áp dụng phép biến đổi cho các hình ảnh cũng như bản đồ độ sâu của chúng:
>>> 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 examplesSử dụng hàm set_transform() để áp dụng phép biến đổi trực tiếp lên các lô dữ liệu của tập dữ liệu nhằm tiết kiệm dung lượng ổ đĩa:
>>> train_dataset.set_transform(apply_transforms)Bạn có thể kiểm tra xem phép biến đổi đã hoạt động hay chưa bằng cách truy cập vào pixel_values và labels của một hình ảnh mẫu:
>>> example = train_dataset[index]
>>> plt.imshow(example["pixel_values"])
>>> plt.axis("off")
>>> plt.show()
Trực quan hóa cùng phép biến đổi đó trên bản đồ độ sâu tương ứng của hình ảnh:
>>> show_depthmap(example["labels"])
Bạn cũng có thể trực quan hóa nhiều mẫu huấn luyện bằng cách tái sử dụng random_indices trước đó:
>>> 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")