Spaces:
Running
Running
import torch | |
import cv2 | |
import numpy as np | |
from torchvision import transforms | |
from torch.utils.data import Dataset | |
from pathlib import Path | |
class PatchesDataset(Dataset): | |
""" | |
HPatches dataset class. | |
# Note: output_shape = (output_width, output_height) | |
# Note: this returns Pytorch tensors, resized to output_shape (if specified) | |
# Note: the homography will be adjusted according to output_shape. | |
Parameters | |
---------- | |
root_dir : str | |
Path to the dataset | |
use_color : bool | |
Return color images or convert to grayscale. | |
data_transform : Function | |
Transformations applied to the sample | |
output_shape: tuple | |
If specified, the images and homographies will be resized to the desired shape. | |
type: str | |
Dataset subset to return from ['i', 'v', 'all']: | |
i - illumination sequences | |
v - viewpoint sequences | |
all - all sequences | |
""" | |
def __init__(self, root_dir, use_color=True, data_transform=None, output_shape=None, type='all'): | |
super().__init__() | |
self.type = type | |
self.root_dir = root_dir | |
self.data_transform = data_transform | |
self.output_shape = output_shape | |
self.use_color = use_color | |
base_path = Path(root_dir) | |
folder_paths = [x for x in base_path.iterdir() if x.is_dir()] | |
image_paths = [] | |
warped_image_paths = [] | |
homographies = [] | |
for path in folder_paths: | |
if self.type == 'i' and path.stem[0] != 'i': | |
continue | |
if self.type == 'v' and path.stem[0] != 'v': | |
continue | |
num_images = 5 | |
file_ext = '.ppm' | |
for i in range(2, 2 + num_images): | |
image_paths.append(str(Path(path, "1" + file_ext))) | |
warped_image_paths.append(str(Path(path, str(i) + file_ext))) | |
homographies.append(np.loadtxt(str(Path(path, "H_1_" + str(i))))) | |
self.files = {'image_paths': image_paths, 'warped_image_paths': warped_image_paths, 'homography': homographies} | |
def scale_homography(self, homography, original_scale, new_scale, pre): | |
scales = np.divide(new_scale, original_scale) | |
if pre: | |
s = np.diag(np.append(scales, 1.)) | |
homography = np.matmul(s, homography) | |
else: | |
sinv = np.diag(np.append(1. / scales, 1.)) | |
homography = np.matmul(homography, sinv) | |
return homography | |
def __len__(self): | |
return len(self.files['image_paths']) | |
def __getitem__(self, idx): | |
def _read_image(path): | |
img = cv2.imread(path, cv2.IMREAD_COLOR) | |
if self.use_color: | |
return img | |
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) | |
return gray | |
image = _read_image(self.files['image_paths'][idx]) | |
warped_image = _read_image(self.files['warped_image_paths'][idx]) | |
homography = np.array(self.files['homography'][idx]) | |
sample = {'image': image, 'warped_image': warped_image, 'homography': homography, 'index' : idx} | |
# Apply transformations | |
if self.output_shape is not None: | |
sample['homography'] = self.scale_homography(sample['homography'], | |
sample['image'].shape[:2][::-1], | |
self.output_shape, | |
pre=False) | |
sample['homography'] = self.scale_homography(sample['homography'], | |
sample['warped_image'].shape[:2][::-1], | |
self.output_shape, | |
pre=True) | |
for key in ['image', 'warped_image']: | |
sample[key] = cv2.resize(sample[key], self.output_shape) | |
if self.use_color is False: | |
sample[key] = np.expand_dims(sample[key], axis=2) | |
transform = transforms.ToTensor() | |
for key in ['image', 'warped_image']: | |
sample[key] = transform(sample[key]).type('torch.FloatTensor') | |
return sample | |