Spaces:
Running on Zero
Running on Zero
| from PIL import Image | |
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| import torch | |
| import cv2 | |
| import argparse | |
| import os | |
| import numpy as np | |
| from tqdm import tqdm | |
| from utils.projection import intrins_to_intrins_inv, get_cam_coords | |
| from utils.visualize import normal_to_rgb | |
| from utils.d2n.plane_svd import Depth2normal as d2n_svd | |
| def count_data(root_dir, scenes): | |
| count = 0 | |
| # Walk through all directories and files in the root directory | |
| for scene in scenes: | |
| for dirpath, dirnames, filenames in os.walk(root_dir): | |
| # Filter files that end with the given suffix | |
| for filename in filenames: | |
| if filename.startswith("depth") and f'Scene{scene}' in dirpath: | |
| count += 1 | |
| return count | |
| def args_parser(): | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("--data_path", required=True) | |
| parser.add_argument("--depth_min", type=float, default=1e-3) | |
| parser.add_argument("--depth_max", type=float, default=80.0) | |
| parser.add_argument("--batch_size", type=int, default=4) | |
| parser.add_argument("--scenes", type=str, nargs="+", | |
| default=['01', '02', '06', '18', '20']) | |
| return parser.parse_args() | |
| if __name__ == "__main__": | |
| args = args_parser() | |
| cuda_avail = torch.cuda.is_available() | |
| device = torch.device("cuda" if cuda_avail else "cpu") | |
| data_path = args.data_path | |
| depth_min = args.depth_min | |
| depth_max = args.depth_max | |
| batch_size = args.batch_size | |
| # scenes = ['01', '02', '06', '18', '20'] | |
| scenes = args.scenes | |
| print(f"Processing scenes: {scenes}. ") | |
| num_data = count_data(data_path, scenes) | |
| print(f'Total number of data: {num_data}. ') | |
| conditions = [ | |
| '15-deg-left', '15-deg-right', '30-deg-left', '30-deg-right', 'clone', | |
| 'fog', 'morning', 'overcast', 'rain', 'sunset' | |
| ] | |
| cameras = ['0', '1'] | |
| # SceneX/Y/frames/depth/Camera_Z/depth_%05d.png | |
| # SceneX/Y/intrinsic.txt | |
| pbar = tqdm(total=num_data) | |
| for scene in scenes: | |
| for cond in conditions: | |
| intrinsic_file = os.path.join(data_path,f'Scene{scene}/{cond}/intrinsic.txt') | |
| with open(intrinsic_file, 'r') as file: | |
| lines = file.readlines() | |
| frames_x_cameras = len(lines)-1 | |
| intrinsics = np.zeros((frames_x_cameras//len(cameras), len(cameras),4)) | |
| for line in lines[1:]: | |
| line = line.strip().split(" ") | |
| frame_id = int(line[0]) | |
| camera_id = int(line[1]) | |
| k_00 = float(line[2]) | |
| k_11 = float(line[3]) | |
| k_02 = float(line[4]) | |
| k_12 = float(line[5]) | |
| intrinsics[frame_id][camera_id] = np.array([k_00, k_11, k_02, k_12]) | |
| for cam in cameras: | |
| depth_dir = os.path.join(data_path, f'Scene{scene}/{cond}/frames/depth/Camera_{cam}') | |
| depth_files = os.listdir(depth_dir) | |
| num_batch = len(depth_files) // batch_size | |
| batches = [batch_size]*num_batch | |
| res = len(depth_files) % batch_size | |
| if res > 0: | |
| num_batch += 1 | |
| batches += [res] | |
| for idx_b, batch in enumerate(batches): | |
| depth_batch = [] | |
| intrins_inv_batch = [] | |
| depth_path_batch = [] | |
| for i in range(batch): | |
| depth_file_idx = idx_b * batch_size + i | |
| depth_file = depth_files[depth_file_idx] | |
| depth_path = os.path.join(depth_dir, depth_file) | |
| depth_path_batch.append(depth_path) | |
| depth = cv2.imread(depth_path, cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH) | |
| depth = depth / 100 # cm -> m | |
| depth = depth[:, :, None] # (H, W, 1) | |
| depth = torch.from_numpy(depth).permute(2, 0, 1).unsqueeze(0) # (1, 1, H, W) | |
| depth = depth.to(device) | |
| depth_batch.append(depth) | |
| frame_id = int(depth_file.split(".")[0].split("_")[-1]) | |
| k_00 = intrinsics[frame_id][int(cam)][0] | |
| k_11 = intrinsics[frame_id][int(cam)][1] | |
| k_02 = intrinsics[frame_id][int(cam)][2] | |
| k_12 = intrinsics[frame_id][int(cam)][3] | |
| intrins = np.array([ | |
| [k_00, 0, k_02], | |
| [0, k_11, k_12], | |
| [0, 0, 1 ] | |
| ]) | |
| intrins_inv = intrins_to_intrins_inv(intrins) | |
| intrins_inv = torch.from_numpy(intrins_inv).unsqueeze(0).to(device) | |
| intrins_inv_batch.append(intrins_inv) | |
| depth_batch = torch.cat(depth_batch, dim=0) | |
| intrins_inv_batch = torch.cat(intrins_inv_batch, dim=0) | |
| points = get_cam_coords(intrins_inv_batch, depth_batch) | |
| with torch.no_grad(): | |
| D2N = d2n_svd(d_min=depth_min, d_max=depth_max, k=5, d=1, gamma=0.05, min_nghbr=4) | |
| normal, valid_mask = D2N(points) | |
| normal_rgb = normal_to_rgb(normal, valid_mask) | |
| for i in range(batch): | |
| norm_rgb = normal_rgb[i] | |
| norm_rgb = Image.fromarray(norm_rgb, "RGB") | |
| norm_rgb_save_path = depth_path_batch[i].replace("depth",'normal') | |
| os.makedirs(os.path.dirname(norm_rgb_save_path), exist_ok=True) | |
| norm_rgb.save(norm_rgb_save_path) | |
| pbar.update(batch) | |
| pbar.close() |