Spaces:
Sleeping
Sleeping
| import os | |
| import glob | |
| import json | |
| import cv2 | |
| import numpy as np | |
| import argparse | |
| import torch | |
| import imageio.v2 as imageio | |
| import imageio.v3 as imageio_v3 | |
| import nvdiffrast.torch as dr | |
| # Enable OpenEXR support in OpenCV | |
| os.environ['OPENCV_IO_ENABLE_OPENEXR'] = '1' | |
| def swap_yz_in_extrinsic_matrix(matrix): | |
| assert matrix.shape == (4, 4), "Input must be a 4x4 matrix" | |
| new_matrix = matrix.copy() | |
| new_matrix[1, :], new_matrix[2, :] = new_matrix[2, :].copy(), new_matrix[1, :].copy() | |
| new_matrix[:, 1], new_matrix[:, 2] = new_matrix[:, 2].copy(), new_matrix[:, 1].copy() | |
| return new_matrix | |
| def swap_yz_output_in_extrinsic_matrix(matrix): | |
| assert matrix.shape == (4, 4), "Input must be a 4x4 matrix" | |
| new_matrix = matrix.copy() | |
| new_matrix[1, :], new_matrix[2, :] = new_matrix[2, :].copy(), new_matrix[1, :].copy() | |
| return new_matrix | |
| def euler_to_rotation_matrix(euler_angles, inverse_y=True, y_bias=0): | |
| alpha, gamma, beta = euler_angles | |
| beta += y_bias | |
| if inverse_y: | |
| beta = -beta | |
| R_x = np.array([[1, 0, 0], | |
| [0, np.cos(alpha), -np.sin(alpha)], | |
| [0, np.sin(alpha), np.cos(alpha)]]) | |
| R_y = np.array([[np.cos(beta), 0, np.sin(beta)], | |
| [0, 1, 0], | |
| [-np.sin(beta), 0, np.cos(beta)]]) | |
| R_z = np.array([[np.cos(gamma), -np.sin(gamma), 0], | |
| [np.sin(gamma), np.cos(gamma), 0], | |
| [0, 0, 1]]) | |
| R = np.dot(R_z, np.dot(R_y, R_x)) | |
| return R | |
| def remove_yaw_rotation(c2w_list): | |
| c2w_0 = c2w_list[0] | |
| rotation_0 = c2w_0[:3, :3] | |
| yaw_0 = np.arctan2(rotation_0[2, 0], rotation_0[0, 0]) | |
| yaw_rotation_matrix = np.array([ | |
| [np.cos(-yaw_0), 0, np.sin(-yaw_0), 0], | |
| [0, 1, 0, 0], | |
| [-np.sin(-yaw_0), 0, np.cos(-yaw_0), 0], | |
| [0, 0, 0, 1] | |
| ]) | |
| c2w_list_adjusted = [yaw_rotation_matrix @ c2w_i for c2w_i in c2w_list] | |
| return c2w_list_adjusted | |
| def adjust_yaw_rotation(c2w_list, yaw_0): | |
| yaw_rotation_matrix = np.array([ | |
| [np.cos(-yaw_0), 0, np.sin(-yaw_0), 0], | |
| [0, 1, 0, 0], | |
| [-np.sin(-yaw_0), 0, np.cos(-yaw_0), 0], | |
| [0, 0, 0, 1] | |
| ]) | |
| c2w_list_adjusted = [yaw_rotation_matrix @ c2w_i for c2w_i in c2w_list] | |
| return c2w_list_adjusted | |
| def reverse_yaw_rotation(c2w_list): | |
| c2w_list_reversed = [] | |
| for c2w in c2w_list: | |
| rotation = c2w[:3, :3] | |
| yaw = np.arctan2(rotation[2, 0], rotation[0, 0]) | |
| reversed_yaw = 2 * yaw | |
| reverse_yaw_rotation_matrix = np.array([ | |
| [np.cos(reversed_yaw), 0, np.sin(reversed_yaw), 0], | |
| [0, 1, 0, 0], | |
| [-np.sin(reversed_yaw), 0, np.cos(reversed_yaw), 0], | |
| [0, 0, 0, 1] | |
| ]) | |
| c2w_reversed = reverse_yaw_rotation_matrix @ c2w | |
| c2w_list_reversed.append(c2w_reversed) | |
| return c2w_list_reversed | |
| def prepare_camera_poses(num_frames, fixed_pose, pose_file, pose_offset, pose_reset, device, ign_camera_pose=True, swap_type=0, load_w2c=False, remove_y_rotation=False, reverse_y_rotation=False, yaw_0=0, pose_list=None, rotation_euler=None): | |
| """Prepare camera poses based on the provided arguments.""" | |
| if pose_list is not None: | |
| c2w_list = pose_list | |
| for frame_idx, transform_matrix in enumerate(c2w_list): | |
| if swap_type == 0: | |
| new_transform_matrix = transform_matrix | |
| elif swap_type == 1: | |
| new_transform_matrix = swap_yz_in_extrinsic_matrix(transform_matrix) | |
| elif swap_type == 2: | |
| new_transform_matrix = swap_yz_output_in_extrinsic_matrix(transform_matrix) | |
| if load_w2c: | |
| new_transform_matrix = np.linalg.inv(new_transform_matrix) | |
| c2w_list[frame_idx] = new_transform_matrix | |
| if pose_reset: | |
| w2c_0 = np.linalg.inv(c2w_list[0]) | |
| c2w_list = [w2c_0 @ c2w_i for c2w_i in c2w_list] | |
| if remove_y_rotation: | |
| c2w_list = remove_yaw_rotation(c2w_list) | |
| if reverse_y_rotation: | |
| c2w_list = reverse_yaw_rotation(c2w_list) | |
| if rotation_euler is not None: | |
| for frame_idx, transform_matrix in enumerate(c2w_list): | |
| rotation_matrix = euler_to_rotation_matrix(rotation_euler, inverse_y=True, y_bias=np.pi/2) | |
| if ign_camera_pose: | |
| transform_matrix = c2w_list[0] | |
| else: | |
| transform_matrix = c2w | |
| rotation_matrix_4x4 = np.eye(4) | |
| rotation_matrix_4x4[:3, :3] = rotation_matrix | |
| new_transform_matrix = np.dot(rotation_matrix_4x4, transform_matrix) | |
| c2w_list[frame_idx] = new_transform_matrix | |
| return c2w_list | |
| elif fixed_pose or pose_file is None: | |
| return [np.eye(4) for _ in range(num_frames)] | |
| with open(pose_file, 'r') as f: | |
| meta = json.load(f) | |
| frames = meta['frames'][pose_offset:pose_offset + num_frames] | |
| for frame_idx, data in enumerate(frames): | |
| transform_matrix = np.array(data["transform_matrix"]) | |
| if swap_type == 0: | |
| new_transform_matrix = transform_matrix | |
| elif swap_type == 1: | |
| new_transform_matrix = swap_yz_in_extrinsic_matrix(transform_matrix) | |
| if load_w2c: | |
| new_transform_matrix = np.linalg.inv(new_transform_matrix) | |
| data["transform_matrix"] = new_transform_matrix.tolist() | |
| frames[frame_idx] = data | |
| if ign_camera_pose: | |
| c2w_list = [np.array(frames[0]["transform_matrix"]) for frame in frames] | |
| else: | |
| c2w_list = [np.array(frame['transform_matrix']) for frame in frames] | |
| if pose_reset: | |
| w2c_0 = np.linalg.inv(c2w_list[0]) | |
| c2w_list = [w2c_0 @ c2w_i for c2w_i in c2w_list] # compute c2c0 | |
| if remove_y_rotation: | |
| c2w_list = remove_yaw_rotation(c2w_list) | |
| if reverse_y_rotation: | |
| c2w_list = reverse_yaw_rotation(c2w_list) | |
| if yaw_0 != 0: | |
| c2w_list = adjust_yaw_rotation(c2w_list, yaw_0) | |
| for frame_idx, (data, c2w) in enumerate(zip(frames, c2w_list)): | |
| if "hdri_euler" in data.keys(): | |
| rotation_matrix = euler_to_rotation_matrix(data["hdri_euler"], inverse_y=False) | |
| if ign_camera_pose: | |
| transform_matrix = c2w_list[0] | |
| else: | |
| transform_matrix = c2w | |
| rotation_matrix_4x4 = np.eye(4) | |
| rotation_matrix_4x4[:3, :3] = rotation_matrix | |
| new_transform_matrix = np.dot(rotation_matrix_4x4, transform_matrix) | |
| c2w_list[frame_idx] = new_transform_matrix | |
| else: | |
| print(f"Warning: 'hdri_euler' not found in frame {frame_idx} of {pose_file}. Using original transform matrix.") | |
| break | |
| return c2w_list | |
| def latlong_vec(res, device=None): | |
| gy, gx = torch.meshgrid(torch.linspace( 0.0 + 1.0 / res[0], 1.0 - 1.0 / res[0], res[0], device=device), | |
| torch.linspace(-1.0 + 1.0 / res[1], 1.0 - 1.0 / res[1], res[1], device=device), | |
| indexing='ij') | |
| sintheta, costheta = torch.sin(gy*np.pi), torch.cos(gy*np.pi) | |
| sinphi, cosphi = torch.sin(gx*np.pi), torch.cos(gx*np.pi) | |
| dir_vec = torch.stack(( | |
| sintheta*sinphi, | |
| costheta, | |
| -sintheta*cosphi | |
| ), dim=-1) | |
| # return dr.texture(cubemap[None, ...], dir_vec[None, ...].contiguous(), filter_mode='linear', boundary_mode='cube')[0] | |
| return dir_vec #[H, W, 3] | |
| def envmap_vec(res, device=None): | |
| return -latlong_vec(res, device).flip(0).flip(1) #[H, W, 3] | |
| def dot(x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: | |
| return torch.sum(x*y, -1, keepdim=True) | |
| def length(x: torch.Tensor, eps: float =1e-20) -> torch.Tensor: | |
| return torch.sqrt(torch.clamp(dot(x,x), min=eps)) # Clamp to avoid nan gradients because grad(sqrt(0)) = NaN | |
| def safe_normalize(x: torch.Tensor, eps: float =1e-20) -> torch.Tensor: | |
| return x / length(x, eps) | |
| def cube_to_dir(s, x, y): | |
| if s == 0: rx, ry, rz = torch.ones_like(x), -y, -x | |
| elif s == 1: rx, ry, rz = -torch.ones_like(x), -y, x | |
| elif s == 2: rx, ry, rz = x, torch.ones_like(x), y | |
| elif s == 3: rx, ry, rz = x, -torch.ones_like(x), -y | |
| elif s == 4: rx, ry, rz = x, -y, torch.ones_like(x) | |
| elif s == 5: rx, ry, rz = -x, -y, -torch.ones_like(x) | |
| return torch.stack((rx, ry, rz), dim=-1) | |
| def latlong_to_cubemap(latlong_map, res): | |
| cubemap = torch.zeros(6, res[0], res[1], latlong_map.shape[-1], dtype=torch.float32, device='cuda') | |
| for s in range(6): | |
| gy, gx = torch.meshgrid(torch.linspace(-1.0 + 1.0 / res[0], 1.0 - 1.0 / res[0], res[0], device='cuda'), | |
| torch.linspace(-1.0 + 1.0 / res[1], 1.0 - 1.0 / res[1], res[1], device='cuda'), | |
| indexing='ij') | |
| v = safe_normalize(cube_to_dir(s, gx, gy)) | |
| tu = torch.atan2(v[..., 0:1], -v[..., 2:3]) / (2 * np.pi) + 0.5 | |
| tv = torch.acos(torch.clamp(v[..., 1:2], min=-1, max=1)) / np.pi | |
| texcoord = torch.cat((tu, tv), dim=-1) | |
| cubemap[s, ...] = dr.texture(latlong_map[None, ...], texcoord[None, ...], filter_mode='linear')[0] | |
| return cubemap | |
| def load_and_preprocess_hdr(hdr_dir, env_strength, env_flip, env_rot, device, rotation180=False, inverse_env=False, flip_env=False): | |
| """Load and preprocess the HDR environment map.""" | |
| if hdr_dir.endswith('.hdr') or hdr_dir.endswith('.exr'): | |
| latlong_img = imageio_v3.imread(hdr_dir, flags=cv2.IMREAD_UNCHANGED, plugin='opencv') | |
| elif hdr_dir.endswith('.jpg') or hdr_dir.endswith('.png'): | |
| import skimage | |
| latlong_img = skimage.io.imread(hdr_dir)[..., :3] | |
| latlong_img = skimage.img_as_float(latlong_img) | |
| latlong_img = np.power(latlong_img, 2.4).astype(np.float32) | |
| latlong_img *= 2 # for mit dataset | |
| if rotation180: | |
| height, width, channels = latlong_img.shape | |
| shift_amount = width // 2 | |
| shifted_hdr = np.zeros_like(latlong_img) | |
| shifted_hdr[:, -shift_amount:, :] = latlong_img[:, :shift_amount, :] | |
| shifted_hdr[:, :-shift_amount, :] = latlong_img[:, shift_amount:, :] | |
| latlong_img = shifted_hdr | |
| if inverse_env: | |
| latlong_img = latlong_img[:, ::-1, :] | |
| height, width, channels = latlong_img.shape | |
| shift_amount = width // 2 | |
| shifted_hdr = np.zeros_like(latlong_img) | |
| shifted_hdr[:, -shift_amount:, :] = latlong_img[:, :shift_amount, :] | |
| shifted_hdr[:, :-shift_amount, :] = latlong_img[:, shift_amount:, :] | |
| latlong_img = shifted_hdr | |
| if flip_env: | |
| latlong_img = latlong_img[:, ::-1, :].copy() | |
| latlong_img = torch.tensor(latlong_img, dtype=torch.float32, device=device) | |
| latlong_img *= env_strength | |
| # Cleanup NaNs and Infs | |
| latlong_img = torch.nan_to_num(latlong_img, nan=0.0, posinf=65504.0, neginf=0.0) | |
| latlong_img = latlong_img.clamp(0.0, 65504.0) | |
| if env_flip: | |
| latlong_img = torch.flip(latlong_img, dims=[1]) | |
| if env_rot != 0: | |
| lat_h, lat_w = latlong_img.shape[:2] | |
| pixel_rot = int(lat_w * env_rot / 360) | |
| latlong_img = torch.roll(latlong_img, shifts=pixel_rot, dims=1) | |
| # Convert to cubemap | |
| cubemap = latlong_to_cubemap(latlong_img, [512, 512]) | |
| return cubemap | |
| def prepare_metadata(hdr_dir, env_rot, env_flip, env_strength, fixed_pose, rotate_envlight, save_dir, prefix): | |
| """Prepare metadata about the environment map processing.""" | |
| env_meta = { | |
| 'envmap': os.path.basename(hdr_dir), | |
| 'envmap_rot': env_rot, | |
| 'envmap_flip': env_flip, | |
| 'envmap_strength': env_strength, | |
| 'fixed_pose': fixed_pose, | |
| 'rotate_envlight': rotate_envlight, | |
| } | |
| if save_dir: | |
| os.makedirs(save_dir, exist_ok=True) | |
| meta_path = os.path.join(save_dir, f'{prefix}.meta.json') | |
| with open(meta_path, 'w') as f: | |
| json.dump(env_meta, f, indent=4) | |
| return env_meta | |
| def rotate_y(a, device=None): | |
| s, c = np.sin(a), np.cos(a) | |
| return torch.tensor([[ c, 0, s, 0], | |
| [ 0, 1, 0, 0], | |
| [-s, 0, c, 0], | |
| [ 0, 0, 0, 1]], dtype=torch.float32, device=device) | |
| def process_projected_envmap(cubemap, vec, c2w, y_rot, H, W): | |
| """Process the camera-oriented projected environment map.""" | |
| vec_cam = vec.view(-1, 3) @ c2w[:3, :3].T | |
| vec_query = (vec_cam @ y_rot[:3, :3].T).view(1, H, W, 3) | |
| env_proj = dr.texture(cubemap.unsqueeze(0), -vec_query.contiguous(), | |
| filter_mode='linear', boundary_mode='cube')[0] | |
| env_proj = torch.flip(env_proj, dims=[0, 1]) | |
| return env_proj | |
| def rgb2srgb(rgb): | |
| return torch.where(rgb <= 0.0031308, 12.92 * rgb, 1.055 * rgb**(1/2.4) - 0.055) | |
| def reinhard(x, max_point=16): | |
| y_rein = x * (1 + x / (max_point ** 2)) / (1 + x) | |
| return y_rein | |
| def hdr_mapping(env_hdr, log_scale): | |
| """Map HDR environment maps to LDR and logarithmic representations.""" | |
| env_ev0 = rgb2srgb(reinhard(env_hdr, max_point=16).clamp(0, 1)) | |
| env_log = rgb2srgb(torch.log1p(env_hdr) / np.log1p(log_scale)).clamp(0, 1) | |
| return { | |
| 'env_hdr': env_hdr, # Original HDR image | |
| 'env_ev0': env_ev0, # LDR image after tone mapping | |
| 'env_log': env_log, # Logarithmic scaling | |
| } | |
| def process_environment_map( | |
| hdr_dir, | |
| resolution=(512, 512), | |
| num_frames=1, | |
| fixed_pose=True, | |
| pose_file=None, | |
| pose_list=None, | |
| rotation_euler=None, | |
| pose_offset=0, | |
| pose_reset=False, | |
| rotate_envlight=False, | |
| env_format=['proj'], | |
| log_scale=10000, | |
| env_strength=1.0, | |
| env_flip=True, | |
| env_rot=180.0, | |
| save_dir=None, | |
| prefix='0000', | |
| device=None, | |
| rotation180=False, | |
| ign_camera_pose=True, | |
| inverse_env=False, | |
| swap_type=0, | |
| load_w2c=False, | |
| flip_env=False, | |
| remove_y_rotation=False, | |
| reverse_y_rotation=False, | |
| yaw_0=0, | |
| ): | |
| """ | |
| Preprocess HDR environment maps for rendering. | |
| FIXME: Note that this function bakes in a flip and rotate operation for the environment light. Set to env_flip=True and env_rot=180 is considered as loading the original environment map. | |
| Args: | |
| hdr_dir (str): Path to the HDR environment map file. | |
| resolution (tuple of int): Resolution of the output images (H, W). | |
| num_frames (int): Number of frames to process. | |
| fixed_pose (bool): Use a fixed camera pose (identity matrix) if True. | |
| pose_file (str): Path to the camera pose file (JSON). | |
| pose_offset (int): Offset for the pose frames in the pose file. | |
| pose_reset (bool): Reset camera poses to be relative to the first frame. | |
| rotate_envlight (bool): Rotate the environment light over frames if True. | |
| env_format (list of str): Formats of the environment maps to generate ('proj', 'fixed', 'ball'). | |
| log_scale (int): Log scale factor for HDR mapping. | |
| env_strength (float): Strength multiplier for the environment map. | |
| env_flip (bool): Flip the environment map horizontally if True. | |
| env_rot (float): Rotation angle for the environment map in degrees. | |
| save_dir (str): Directory to save the processed images (optional). | |
| prefix (str): Prefix for the output files (used if saving images). | |
| Returns: | |
| dict: A dictionary containing the processed environment maps and metadata. | |
| { | |
| 'metadata': env_meta, | |
| 'fixed': mapping_results_for_fixed_envmap, # Only if 'fixed' in env_format | |
| 'env_ldr': stacked_tensor_of_proj_env_ldr, # Only if 'proj' in env_format | |
| 'env_log': stacked_tensor_of_proj_env_log, # Only if 'proj' in env_format | |
| 'ball_env_ldr': stacked_tensor_of_ball_env_ldr, # Only if 'ball' in env_format | |
| 'ball_env_log': stacked_tensor_of_ball_env_log, # Only if 'ball' in env_format | |
| } | |
| Tensors are with shape (T, H, W, 3) in [0, 1] | |
| """ | |
| H, W = resolution # (704, 1280) | |
| if device is None: | |
| device = 'cuda' if torch.cuda.is_available() else 'cpu' | |
| vec = latlong_vec((H, W), device=device) | |
| # Prepare camera poses | |
| poses = prepare_camera_poses( | |
| num_frames=num_frames, | |
| fixed_pose=fixed_pose, | |
| pose_file=pose_file, | |
| pose_offset=pose_offset, | |
| pose_reset=pose_reset, | |
| device=device, | |
| ign_camera_pose=ign_camera_pose, | |
| swap_type=swap_type, | |
| load_w2c=load_w2c, | |
| remove_y_rotation=remove_y_rotation, | |
| reverse_y_rotation=reverse_y_rotation, | |
| yaw_0=yaw_0, | |
| pose_list=pose_list, | |
| rotation_euler=rotation_euler, | |
| ) | |
| # Prepare rotations for the environment light # 57 * rot | |
| rots = np.linspace(0, 2 * np.pi, num_frames) if rotate_envlight else [0] * num_frames | |
| # Load and preprocess the HDR environment map | |
| cubemap = load_and_preprocess_hdr( | |
| hdr_dir=hdr_dir, | |
| env_strength=env_strength, | |
| env_flip=env_flip, | |
| env_rot=env_rot, | |
| device=device, | |
| rotation180=rotation180, | |
| inverse_env=inverse_env, | |
| flip_env=flip_env, | |
| ) | |
| # Prepare metadata | |
| env_meta = prepare_metadata( | |
| hdr_dir=hdr_dir, | |
| env_rot=env_rot, | |
| env_flip=env_flip, | |
| env_strength=env_strength, | |
| fixed_pose=fixed_pose, | |
| rotate_envlight=rotate_envlight, | |
| save_dir=save_dir, | |
| prefix=prefix | |
| ) | |
| # Initialize result dictionary | |
| results = { | |
| 'metadata': env_meta, | |
| } | |
| # Prepare lists to collect per-frame tensors | |
| if 'proj' in env_format: | |
| proj_env_ldr_list = [] | |
| proj_env_log_list = [] | |
| # Process per-frame environment maps | |
| for i in range(num_frames): | |
| c2w = torch.from_numpy(poses[i]).float().to(device) | |
| y_rot = rotate_y(rots[i], device=device) | |
| if 'proj' in env_format: | |
| env_proj = process_projected_envmap(cubemap, vec, c2w, y_rot, H, W) | |
| mapping_results = hdr_mapping(env_proj, log_scale=log_scale) | |
| proj_env_ldr_list.append(mapping_results['env_ev0']) | |
| proj_env_log_list.append(mapping_results['env_log']) | |
| if 'proj' in env_format: | |
| results['env_ldr'] = torch.stack(proj_env_ldr_list, dim=0) | |
| results['env_log'] = torch.stack(proj_env_log_list, dim=0) | |
| return results | |
| def save_array_as_video(video_array, output_path: str, fps: int = 24): | |
| """ | |
| video_array: t h w c, np.array or tensors | |
| """ | |
| if isinstance(video_array, torch.Tensor): | |
| video_array = video_array.cpu().numpy() | |
| if video_array.dtype != np.uint8: | |
| print("float 2 uint8") | |
| # If the data range is [-1, 1] | |
| if video_array.min() < 0: | |
| video_array = ((video_array + 1) * 127.5).clip(0, 255).astype(np.uint8) | |
| # If the data range is [0, 1] | |
| else: | |
| video_array = (video_array * 255).clip(0, 255).astype(np.uint8) | |
| try: | |
| if not os.path.isfile(output_path): | |
| imageio.mimsave( | |
| output_path, | |
| [frame for frame in video_array], | |
| fps=fps, | |
| codec='libx264' | |
| ) | |
| print("succeed to save vide") | |
| print(f"video already exists in {output_path}") | |
| except Exception as e: | |
| print(f"fail to save video: {e}") | |
| def process_hdr(hdr_path, save_path, env_strength=1.0, inverse_env=False): | |
| hdr_path = glob.glob(f'{hdr_path}*')[0] | |
| if '.hdr' in hdr_path: | |
| env_strength = env_strength / 3.0 | |
| num_of_frames = 57 | |
| ldr_list = [] | |
| hdr_log_list = [] | |
| env_dir_list = [] | |
| envlight_dict = process_environment_map( | |
| hdr_dir=hdr_path, | |
| resolution=(320, 576), | |
| num_frames=num_of_frames, # 1 for mit dataset | |
| fixed_pose=True, | |
| rotate_envlight=False, | |
| env_format=['proj', ], | |
| device='cuda', | |
| rotation180=False, | |
| inverse_env=inverse_env, # True for mit dataset, False for others | |
| log_scale=60000, | |
| env_strength=env_strength, # 1.0 for mit dataset | |
| ) # Tensors are with shape (T, H, W, 3) in [0, 1] | |
| ldr_list = (envlight_dict['env_ldr'].cpu().numpy() * 255).astype(np.uint8) | |
| hdr_log_list = (envlight_dict['env_log'].cpu().numpy() * 255).astype(np.uint8) | |
| env_nrm = ((envmap_vec([320, 576], device='cpu').cpu().numpy()*0.5 + 0.5) * 255).astype(np.uint8) | |
| for _ in range(num_of_frames): | |
| env_dir_list.append(env_nrm) | |
| os.makedirs(save_path, exist_ok=True) | |
| ldr_video_path = os.path.join(save_path, "ldr_video_fix_first_frame.mp4") | |
| hdr_log_video_path = os.path.join(save_path, "hdr_log_video_fix_first_frame.mp4") | |
| env_dir_video_path = os.path.join(save_path, "env_dir_video_fix_first_frame.mp4") | |
| if os.path.exists(ldr_video_path): | |
| os.remove(ldr_video_path) | |
| if os.path.exists(hdr_log_video_path): | |
| os.remove(hdr_log_video_path) | |
| if os.path.exists(env_dir_video_path): | |
| os.remove(env_dir_video_path) | |
| save_array_as_video(np.array(ldr_list),ldr_video_path) | |
| save_array_as_video(np.array(hdr_log_list),hdr_log_video_path) | |
| save_array_as_video(np.array(env_dir_list),env_dir_video_path) | |
| def parse_arguments() -> argparse.Namespace: | |
| parser = argparse.ArgumentParser(description="Env maps processing script") | |
| # Specific arguments | |
| parser.add_argument( | |
| "--env_dir", | |
| type=str, | |
| default=None, | |
| help="Path to the directory containing the environment map." | |
| ) | |
| parser.add_argument( | |
| "--save_path", | |
| type=str, | |
| default=None, | |
| help="Path to the directory where the processed environment maps will be saved." | |
| ) | |
| parser.add_argument( | |
| "--env_strength", | |
| type=float, | |
| default=1.0, | |
| help="Strength of the environment map." | |
| ) | |
| return parser.parse_args() | |
| if __name__ == "__main__": | |
| args = parse_arguments() | |
| process_hdr(args.env_dir, save_path=args.save_path, env_strength=args.env_strength) | |