| ''' |
| ----------------------------------------------------------------------------- |
| Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved. |
| |
| NVIDIA CORPORATION and its licensors retain all intellectual property |
| and proprietary rights in and to this software, related documentation |
| and any modifications thereto. Any use, reproduction, disclosure or |
| distribution of this software and related documentation without an express |
| license agreement from NVIDIA CORPORATION is strictly prohibited. |
| ----------------------------------------------------------------------------- |
| ''' |
|
|
| import numpy as np |
| import json |
| from argparse import ArgumentParser |
| import os |
| import cv2 |
| from PIL import Image, ImageFile |
| from glob import glob |
| import math |
| import sys |
| from pathlib import Path |
|
|
| dir_path = Path(os.path.dirname(os.path.realpath(__file__))).parents[2] |
| sys.path.append(dir_path.__str__()) |
| from projects.neuralangelo.utils import misc |
|
|
| ImageFile.LOAD_TRUNCATED_IMAGES = True |
|
|
|
|
| def load_K_Rt_from_P(filename, P=None): |
| |
| if P is None: |
| lines = open(filename).read().splitlines() |
| if len(lines) == 4: |
| lines = lines[1:] |
| lines = [[x[0], x[1], x[2], x[3]] for x in (x.split(" ") for x in lines)] |
| P = np.asarray(lines).astype(np.float32).squeeze() |
|
|
| out = cv2.decomposeProjectionMatrix(P) |
| K = out[0] |
| R = out[1] |
| t = out[2] |
|
|
| K = K / K[2, 2] |
| intrinsics = np.eye(4) |
| intrinsics[:3, :3] = K |
|
|
| pose = np.eye(4, dtype=np.float32) |
| pose[:3, :3] = R.transpose() |
| pose[:3, 3] = (t[:3] / t[3])[:, 0] |
|
|
| return intrinsics, pose |
|
|
|
|
| def dtu_to_json(args): |
| assert args.dtu_path, "Provide path to DTU dataset" |
| scene_list = os.listdir(args.dtu_path) |
|
|
| for scene in scene_list: |
| scene_path = os.path.join(args.dtu_path, scene) |
| if not os.path.isdir(scene_path) or 'scan' not in scene: |
| continue |
|
|
| out = { |
| "k1": 0.0, |
| "k2": 0.0, |
| "k3": 0.0, |
| "k4": 0.0, |
| "p1": 0.0, |
| "p2": 0.0, |
| "is_fisheye": False, |
| "frames": [] |
| } |
|
|
| camera_param = dict(np.load(os.path.join(scene_path, 'cameras_sphere.npz'))) |
| images_lis = sorted(glob(os.path.join(scene_path, 'image/*.png'))) |
| for idx, image in enumerate(images_lis): |
| image = os.path.basename(image) |
|
|
| world_mat = camera_param['world_mat_%d' % idx] |
| scale_mat = camera_param['scale_mat_%d' % idx] |
|
|
| |
| P = world_mat @ scale_mat |
| P = P[:3, :4] |
| intrinsic_param, c2w = load_K_Rt_from_P(None, P) |
| c2w_gl = misc.cv_to_gl(c2w) |
|
|
| frame = {"file_path": 'image/' + image, "transform_matrix": c2w_gl.tolist()} |
| out["frames"].append(frame) |
|
|
| fl_x = intrinsic_param[0][0] |
| fl_y = intrinsic_param[1][1] |
| cx = intrinsic_param[0][2] |
| cy = intrinsic_param[1][2] |
| sk_x = intrinsic_param[0][1] |
| sk_y = intrinsic_param[1][0] |
| w, h = Image.open(os.path.join(scene_path, 'image', image)).size |
|
|
| angle_x = math.atan(w / (fl_x * 2)) * 2 |
| angle_y = math.atan(h / (fl_y * 2)) * 2 |
|
|
| scale_mat = scale_mat.astype(float) |
|
|
| out.update({ |
| "camera_angle_x": angle_x, |
| "camera_angle_y": angle_y, |
| "fl_x": fl_x, |
| "fl_y": fl_y, |
| "cx": cx, |
| "cy": cy, |
| "sk_x": sk_x, |
| "sk_y": sk_y, |
| "w": int(w), |
| "h": int(h), |
| "aabb_scale": np.exp2(np.rint(np.log2(scale_mat[0, 0]))), |
| "sphere_center": [scale_mat[0, -1], scale_mat[1, -1], scale_mat[2, -1]], |
| "sphere_radius": scale_mat[0, 0], |
| "centered": True, |
| "scaled": True, |
| }) |
|
|
| file_path = os.path.join(scene_path, 'transforms.json') |
| with open(file_path, "w") as outputfile: |
| json.dump(out, outputfile, indent=2) |
| print('Writing data to json file: ', file_path) |
|
|
|
|
| if __name__ == '__main__': |
| parser = ArgumentParser() |
| parser.add_argument('--dtu_path', type=str, default=None) |
|
|
| args = parser.parse_args() |
|
|
| dtu_to_json(args) |
|
|