SplatAnything / scripts /convert_cameras.py
ritianyu's picture
Publish preview-first SplatAnything demo for ZeroGPU
dc09dcc verified
Raw History Blame Contribute Delete
3.72 kB
#!/usr/bin/env python3
"""Convert existing calibration to prior_camera.json, or validate it before inference."""
import argparse
from pathlib import Path
import sys
# Allow direct invocation from any working directory without installing the repository.
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from src.utils.camera_conversion import cameras_from_arrays, cameras_from_colmap
from src.utils.camera_io import (
list_image_files, load_cameras_json, validate_cameras_for_images, write_cameras_json,
)
def main(argv=None):
parser = argparse.ArgumentParser(description=__doc__)
commands = parser.add_subparsers(dest='command', required=True)
colmap = commands.add_parser('colmap', help='Convert an undistorted COLMAP text or binary model.')
colmap.add_argument('--model', required=True, help='Sparse model folder containing cameras/images files.')
colmap.add_argument('--model_format', choices=['auto', 'bin', 'txt'], default='auto')
arrays = commands.add_parser('arrays', help='Convert calibrated pose/K .npy arrays with an explicit image order.')
arrays.add_argument('--poses', required=True, help='Numeric [N,4,4] or [N,3,4] .npy file.')
arrays.add_argument('--intrinsics', required=True, help='Pixel K: [3,3] shared, or [N,3,3] .npy file.')
arrays.add_argument('--image_names', required=True, help='UTF-8 text: one image filename per pose row.')
arrays.add_argument('--pose_convention', choices=['c2w', 'w2c'], required=True)
arrays.add_argument('--camera_axes', choices=['opencv', 'opengl'], required=True)
arrays.add_argument('--intrinsics_pixel_center', choices=['opencv', 'colmap'], default='opencv',
help='OpenCV: first pixel center is (0,0); COLMAP: (0.5,0.5).')
check = commands.add_parser('check', help='Validate an existing JSON and its image coverage.')
check.add_argument('--cameras', required=True)
for command in (colmap, arrays, check):
command.add_argument('--images', required=True, help='Flat folder of original-resolution pinhole images.')
for command in (colmap, arrays):
command.add_argument('--output', help='Default: prior_camera.json beside the images directory.')
command.add_argument('--overwrite', action='store_true', help='Replace an existing output JSON.')
args = parser.parse_args(argv)
try:
images = list_image_files(args.images)
if args.command == 'check':
poses, intrinsics = load_cameras_json(args.cameras)
validate_cameras_for_images(images, poses, intrinsics)
print(f'Valid: {len(images)} images have OpenCV c2w poses and pixel intrinsics.')
print('Pose accuracy and the declared coordinate convention require your calibration records.')
return
if args.command == 'colmap':
poses, intrinsics = cameras_from_colmap(images, args.model, args.model_format)
else:
poses, intrinsics = cameras_from_arrays(
images, args.poses, args.intrinsics, args.image_names,
args.pose_convention, args.camera_axes, args.intrinsics_pixel_center)
output = Path(args.output) if args.output else Path(args.images).resolve().parent / 'prior_camera.json'
write_cameras_json(output, images, poses, intrinsics, overwrite=args.overwrite)
print(f'Saved {len(images)} cameras to {output}')
print('Output: OpenCV camera-to-world matrices; original-image pixel intrinsics.')
print('Next: run the pose inference script with the same --images folder as its input directory.')
except (ValueError, OSError) as exc:
parser.error(str(exc))
if __name__ == '__main__':
main()