Instructions to use phi-lab-rice/GRADE with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use phi-lab-rice/GRADE with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("phi-lab-rice/GRADE", dtype=torch.bfloat16, device_map="cuda") prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
Download src/Baselines/radarcam-depth/data/datasets.py from phi-lab-rice/GRADE: direct link, hf CLI and curl.
- Browser
- Download file 13.2 kB
-
https://huggingface.co/phi-lab-rice/GRADE/resolve/main/src/Baselines/radarcam-depth/data/datasets.py
- Command line
-
hf download hf://phi-lab-rice/GRADE/src/Baselines/radarcam-depth/data/datasets.py
-
curl -L -o datasets.py https://huggingface.co/phi-lab-rice/GRADE/resolve/main/src/Baselines/radarcam-depth/data/datasets.py
13.2 kB
| import torch | |
| import torch.utils.data | |
| from torch.utils.data import Dataset | |
| import numpy as np | |
| import data.data_utils as data_utils | |
| import random | |
| import os | |
| from PIL import Image | |
| from data.data_utils import load_depth | |
| def random_sample(T): | |
| ''' | |
| Arg(s): | |
| T : numpy[float32] | |
| C x N array | |
| Returns: | |
| numpy[float32] : random sample from T | |
| ''' | |
| index = np.random.randint(0, T.shape[0]) | |
| return T[index, :] | |
| def random_crop(inputs, shape, crop_type=['none']): | |
| ''' | |
| Apply crop to inputs e.g. images, depth | |
| Arg(s): | |
| inputs : list[numpy[float32]] | |
| list of numpy arrays e.g. images, depth, and validity maps | |
| shape : list[int] | |
| shape (height, width) to crop inputs | |
| crop_type : str | |
| none, horizontal, vertical, anchored, top, bottom, left, right, center | |
| Return: | |
| list[numpy[float32]] : list of cropped inputs | |
| ''' | |
| n_height, n_width = shape | |
| _, o_height, o_width = inputs[0].shape | |
| # Get delta of crop and original height and width | |
| d_height = o_height - n_height | |
| d_width = o_width - n_width | |
| # By default, perform center crop | |
| y_start = d_height // 2 | |
| x_start = d_width // 2 | |
| # If left alignment, then set starting height to 0 | |
| if 'left' in crop_type: | |
| x_start = 0 | |
| # If right alignment, then set starting height to right most position | |
| elif 'right' in crop_type: | |
| x_start = d_width | |
| elif 'horizontal' in crop_type: | |
| # Select from one of the pre-defined anchored locations | |
| if 'anchored' in crop_type: | |
| # Create anchor positions | |
| crop_anchors = [ | |
| 0.0, 0.50, 1.0 | |
| ] | |
| widths = [ | |
| anchor * d_width for anchor in crop_anchors | |
| ] | |
| x_start = int(widths[np.random.randint(low=0, high=len(widths))]) | |
| # Randomly select a crop location | |
| else: | |
| x_start = np.random.randint(low=0, high=d_width) | |
| # If top alignment, then set starting height to 0 | |
| if 'top' in crop_type: | |
| y_start = 0 | |
| # If bottom alignment, then set starting height to lowest position | |
| elif 'bottom' in crop_type: | |
| y_start = d_height | |
| elif 'vertical' in crop_type and np.random.rand() <= 0.30: | |
| # Select from one of the pre-defined anchored locations | |
| if 'anchored' in crop_type: | |
| # Create anchor positions | |
| crop_anchors = [ | |
| 0.0, 0.50, 1.0 | |
| ] | |
| heights = [ | |
| anchor * d_height for anchor in crop_anchors | |
| ] | |
| y_start = int(heights[np.random.randint(low=0, high=len(heights))]) | |
| # Randomly select a crop location | |
| else: | |
| y_start = np.random.randint(low=0, high=d_height) | |
| elif 'center' in crop_type: | |
| pass | |
| # Crop each input into (n_height, n_width) | |
| y_end = y_start + n_height | |
| x_end = x_start + n_width | |
| outputs = [ | |
| T[:, y_start:y_end, x_start:x_end] for T in inputs | |
| ] | |
| return outputs | |
| class RCNetTrainingDataset(torch.utils.data.Dataset): | |
| ''' | |
| Dataset for fetching: | |
| (1) image | |
| (2) radar point | |
| (3) ground truth | |
| (4) bounding boxes for the points | |
| (5) image crops for summary part of the code | |
| Arg(s): | |
| image_paths : list[str] | |
| paths to images | |
| radar_paths : list[str] | |
| paths to radar points | |
| ground_truth_paths : list[str] | |
| paths to ground truth depth maps | |
| crop_width : int | |
| width of crop centered at the radar point | |
| total_points_sampled: int | |
| total number of points sampled from the total radar points available. Repeats the same points multiple times if total points in the frame is less than total sampled points | |
| sample_probability_of_lidar: int | |
| randomly sample lidar with this probability and add noise to it instead of using radar points | |
| min_radar_depth_m: float | |
| minimum depth accepted for synthetic radar sampling | |
| max_radar_depth_m: float | |
| maximum depth accepted for synthetic radar sampling | |
| ''' | |
| def __init__(self, | |
| image_paths, | |
| radar_paths, | |
| ground_truth_paths, | |
| patch_size, | |
| total_points_sampled, | |
| sample_probability_of_lidar, | |
| min_radar_depth_m=0.05, | |
| max_radar_depth_m=11.2): | |
| self.n_sample = len(image_paths) | |
| assert self.n_sample == len(ground_truth_paths) | |
| assert self.n_sample == len(radar_paths) | |
| self.image_paths = image_paths | |
| self.radar_paths = radar_paths | |
| self.ground_truth_paths = ground_truth_paths | |
| self.patch_size = patch_size | |
| self.pad_size_x = patch_size[1] // 2 | |
| self.padding = ((0, 0), (0, 0), (self.pad_size_x, self.pad_size_x)) | |
| self.data_format = 'CHW' | |
| self.total_points_sampled = total_points_sampled | |
| self.sample_probability_of_lidar = sample_probability_of_lidar | |
| self.min_radar_depth_m = min_radar_depth_m | |
| self.max_radar_depth_m = max_radar_depth_m | |
| def __getitem__(self, index): | |
| # Load image | |
| image = data_utils.load_image( | |
| self.image_paths[index], | |
| normalize=False, | |
| data_format=self.data_format) | |
| height, width = image.shape[1:] | |
| if height == 720: # ZJU dataset | |
| image = image[:, 720 // 3: 720 // 4 * 3, :] | |
| image = np.pad( | |
| image, | |
| pad_width=self.padding, | |
| mode='edge') | |
| # Load radar points N x 3 | |
| radar_points = np.load(self.radar_paths[index]) | |
| if height == 720: | |
| radar_points = radar_points[radar_points[:, 1] < 720 // 4 * 3] | |
| radar_points[:, 1] = radar_points[:, 1] - 720 // 3 | |
| radar_points = radar_points[radar_points[:, 1] >= 0] | |
| if radar_points.ndim == 1: | |
| # Only one point (,3), expand to 1 x 3 | |
| radar_points = np.expand_dims(radar_points, axis=0) | |
| # Store bounding boxes for all radar points | |
| bounding_boxes_list = [] | |
| # randomly sample radar points to output | |
| if radar_points.shape[0] <= self.total_points_sampled: | |
| radar_points = np.repeat(radar_points, 100, axis=0) | |
| random_idx = np.random.randint(radar_points.shape[0], size=self.total_points_sampled) | |
| radar_points = radar_points[random_idx, :] | |
| # Load ground truth depth | |
| ground_truth = data_utils.load_depth( | |
| self.ground_truth_paths[index], | |
| data_format=self.data_format) | |
| if height == 720: | |
| ground_truth = ground_truth[:, 720 // 3: 720 // 4 * 3] | |
| if random.random() < self.sample_probability_of_lidar: | |
| ground_truth_for_sampling = np.copy(ground_truth) | |
| ground_truth_for_sampling = ground_truth_for_sampling.squeeze() | |
| valid_lidar = np.isfinite(ground_truth_for_sampling) | |
| valid_lidar &= ground_truth_for_sampling >= self.min_radar_depth_m | |
| valid_lidar &= ground_truth_for_sampling <= self.max_radar_depth_m | |
| idx_lidar_samples = np.where(valid_lidar) | |
| n_lidar_samples = len(idx_lidar_samples[0]) | |
| if n_lidar_samples > 0: | |
| # Keep the fixed point count required by RC-Net. Replacement | |
| # handles frames with fewer valid GT pixels than requested. | |
| if n_lidar_samples >= self.total_points_sampled: | |
| random_indices = random.sample( | |
| range(n_lidar_samples), self.total_points_sampled | |
| ) | |
| else: | |
| random_indices = np.random.choice( | |
| n_lidar_samples, | |
| size=self.total_points_sampled, | |
| replace=True, | |
| ) | |
| points_x = idx_lidar_samples[1][random_indices] | |
| points_y = idx_lidar_samples[0][random_indices] | |
| points_z = ground_truth_for_sampling[points_y, points_x] | |
| noise_for_fake_radar_x = np.random.normal(0, 25, radar_points.shape[0]) | |
| noise_for_fake_radar_z = np.random.uniform(low=0.0, high=0.4, size=radar_points.shape[0]) | |
| fake_radar_points = np.copy(radar_points) | |
| fake_radar_points[:, 0] = points_x + noise_for_fake_radar_x | |
| fake_radar_points[:, 0] = np.clip(fake_radar_points[:, 0], 0, ground_truth_for_sampling.shape[1]) | |
| fake_radar_points[:, 2] = points_z + noise_for_fake_radar_z | |
| # we keep the y as the same it is since it is erroneous | |
| # convert x and y indices back to int after adding noise | |
| fake_radar_points[:, 0] = fake_radar_points[:, 0].astype(int) | |
| fake_radar_points[:, 1] = fake_radar_points[:, 1].astype(int) | |
| radar_points = np.copy(fake_radar_points) | |
| # get the shifted radar points after padding | |
| for radar_point_idx in range(0, radar_points.shape[0]): | |
| # Set radar point to the center of the patch | |
| radar_points[radar_point_idx, 0] = radar_points[radar_point_idx, 0] + self.pad_size_x | |
| bounding_box = [0, 0, 0, 0] | |
| bounding_box[0] = radar_points[radar_point_idx, 0] - self.pad_size_x | |
| bounding_box[1] = 0 | |
| bounding_box[2] = radar_points[radar_point_idx, 0] + self.pad_size_x | |
| bounding_box[3] = self.patch_size[0] | |
| bounding_boxes_list.append(np.asarray(bounding_box)) | |
| ground_truth = np.pad( | |
| ground_truth, | |
| pad_width=self.padding, | |
| mode='constant', | |
| constant_values=0) | |
| ground_truth_crops = [] | |
| # Crop image and ground truth | |
| for radar_point_idx in range(0, radar_points.shape[0]): | |
| start_x = int(radar_points[radar_point_idx, 0] - self.pad_size_x) | |
| end_x = int(radar_points[radar_point_idx, 0] + self.pad_size_x) | |
| start_y = image.shape[-2] - self.patch_size[0] | |
| ground_truth_cropped = ground_truth[:, start_y:, start_x:end_x] | |
| ground_truth_crops.append(ground_truth_cropped) | |
| image = image[:, start_y:, ...] | |
| ground_truth = np.asarray(ground_truth_crops) | |
| # Convert to float32 | |
| image, radar_points, ground_truth = [ | |
| T.astype(np.float32) | |
| for T in [image, radar_points, ground_truth] | |
| ] | |
| bounding_boxes_list = [T.astype(np.float32) for T in bounding_boxes_list] | |
| bounding_boxes_list = np.stack(bounding_boxes_list, axis=0) | |
| return image, radar_points, bounding_boxes_list, ground_truth | |
| def __len__(self): | |
| return self.n_sample | |
| class RCNetInferenceDataset(torch.utils.data.Dataset): | |
| ''' | |
| Dataset for fetching: | |
| (1) image | |
| (2) radar points | |
| (3) ground truth (if available) | |
| Arg(s): | |
| image_paths : list[str] | |
| paths to images | |
| radar_paths : list[str] | |
| paths to radar points | |
| ground_truth_paths : list[str] | |
| paths to ground truth paths | |
| ''' | |
| def __init__(self, image_paths, radar_paths, ground_truth_paths=None): | |
| self.n_sample = len(image_paths) | |
| assert self.n_sample == len(radar_paths) | |
| self.image_paths = image_paths | |
| self.radar_paths = radar_paths | |
| if ground_truth_paths is not None and None not in ground_truth_paths: | |
| assert self.n_sample == len(ground_truth_paths) | |
| self.ground_truth_available = True | |
| else: | |
| self.ground_truth_available = False | |
| self.ground_truth_paths = ground_truth_paths | |
| self.data_format = 'CHW' | |
| def __getitem__(self, index): | |
| # Load image | |
| image = data_utils.load_image( | |
| self.image_paths[index], | |
| normalize=False, | |
| data_format=self.data_format) | |
| height, width = image.shape[1:] | |
| if height == 720: # ZJU dataset | |
| image = image[:, 720 // 3: 720 // 4 * 3, :] | |
| # Load radar points N x 3 | |
| radar_points = np.load(self.radar_paths[index]) | |
| if height == 720: | |
| radar_points = radar_points[radar_points[:, 1] < 720 // 4 * 3] | |
| radar_points[:, 1] = radar_points[:, 1] - 720 // 3 | |
| radar_points = radar_points[radar_points[:, 1] >= 0] | |
| if radar_points.ndim == 1: | |
| # Expand to 1 x 3 | |
| radar_points = np.expand_dims(radar_points, axis=0) | |
| inputs = [image, radar_points] | |
| if self.ground_truth_available: | |
| # Load ground truth depth | |
| ground_truth = data_utils.load_depth( | |
| self.ground_truth_paths[index], | |
| data_format=self.data_format) | |
| if height == 720: | |
| ground_truth = ground_truth[:, 720 // 3: 720 // 4 * 3] | |
| inputs.append(ground_truth) | |
| # Convert to float32 | |
| inputs = [ | |
| T.astype(np.float32) | |
| for T in inputs | |
| ] | |
| return inputs | |
| def __len__(self): | |
| return self.n_sample | |