Spaces:
No application file
No application file
| 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.0)) | |
| homography = np.matmul(s, homography) | |
| else: | |
| sinv = np.diag(np.append(1.0 / scales, 1.0)) | |
| 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 | |