| import os |
| import json |
| import argparse |
| import torch |
| from tqdm import tqdm |
|
|
| from scripts.camera.geometry.camera import SimpleRadial |
| from scripts.camera.geometry.gravity import Gravity |
| from scripts.camera.geometry.perspective_fields import get_perspective_field |
| from scripts.camera.utils.conversions import fov2focal |
| from scripts.camera.utils.text import parse_camera_params |
|
|
| class Cam_Generator: |
| def __init__(self, mode="base"): |
| self.mode = mode |
|
|
| def _load_text(self, caption, h=512, w=512, k1=0, k2=0): |
| |
| roll, pitch, vfov = parse_camera_params(caption, self.mode) |
| |
| |
| f = fov2focal(torch.tensor(vfov), h) |
| px, py = w / 2, h / 2 |
| params = torch.tensor([w, h, f, f, px, py, k1, k2]).float() |
| gravity = torch.tensor([roll, pitch]).float() |
| return params, gravity |
|
|
| def _read_param(self, parameters, gravity): |
| |
| camera = SimpleRadial(parameters).float() |
| roll, pitch = gravity.unbind(-1) |
| gravity_obj = Gravity.from_rp(roll, pitch) |
| camera = camera.scale(torch.Tensor([1, 1])) |
| return {"camera": camera, "gravity": gravity_obj} |
|
|
| def _get_perspective(self, data): |
| |
| camera = data["camera"] |
| gravity_obj = data["gravity"] |
| up_field, lat_field = get_perspective_field( |
| camera, gravity_obj, use_up=True, use_latitude=True |
| ) |
| del camera, gravity_obj |
| return torch.cat([up_field[0], lat_field[0]], dim=0) |
|
|
| def get_cam(self, caption): |
| params, gravity = self._load_text(caption) |
| data = self._read_param(params, gravity) |
| return self._get_perspective(data) |
|
|
| def process_folders(input_root, output_root, start_idx=0, num_folders=None, mode="base"): |
| gen = Cam_Generator(mode=mode) |
| all_dirs = sorted([ |
| d for d in os.listdir(input_root) |
| if os.path.isdir(os.path.join(input_root, d)) |
| ]) |
| if num_folders is None: |
| num_folders = len(all_dirs) - start_idx |
| selected = all_dirs[start_idx:start_idx + num_folders] |
|
|
| for sub in tqdm(selected, desc="Subfolders"): |
| in_sub = os.path.join(input_root, sub) |
| out_sub = os.path.join(output_root, sub) |
| os.makedirs(out_sub, exist_ok=True) |
|
|
| json_files = sorted([ |
| f for f in os.listdir(in_sub) |
| if f.lower().endswith('.json') |
| ]) |
|
|
| for jf in tqdm(json_files, desc=f"Processing {sub}", leave=False): |
| in_path = os.path.join(in_sub, jf) |
| with open(in_path, 'r', encoding='utf-8') as f: |
| data = json.load(f) |
| caption = data.get('caption', '') |
| cam = gen.get_cam(caption) |
| out_name = os.path.splitext(jf)[0] + '.pt' |
| out_path = os.path.join(out_sub, out_name) |
| torch.save(cam, out_path) |
|
|
| def main(): |
| parser = argparse.ArgumentParser( |
| description="Batch process the captions to the camera maps and save as .pt" |
| ) |
| parser.add_argument('--input_root', type=str, |
| help='Root directory of JSON subfolders') |
| parser.add_argument('--output_root', type=str, |
| help='Root directory to save .pt files') |
| parser.add_argument('--start_idx', type=int, default=0, |
| help='Start index of subfolders (0-based, default=0)') |
| parser.add_argument('--num_folders', type=int, default=None, |
| help='Number of subfolders to process (default: all)') |
| parser.add_argument('--mode', type=str, default='base', |
| help='parse_camera_params mode') |
| args = parser.parse_args() |
|
|
| process_folders( |
| args.input_root, |
| args.output_root, |
| start_idx=args.start_idx, |
| num_folders=args.num_folders, |
| mode=args.mode |
| ) |
|
|
|
|
| if __name__ == '__main__': |
| main() |
|
|