mirror of
https://github.com/graphdeco-inria/gaussian-splatting
synced 2025-04-08 23:14:40 +00:00
In some cases, calibration gives central point cx,cy != (0.5,0.5), or it can be decided to crop the input images. In those cases, it is necessary to split fovx to fovXleft,fovXright and fovy to fovYtop,fovYbottom Note that the export of cameras to cameras.json merges those values back to the basic fovx,fovy. This aims at avoiding the modification of diff_gaussian_rasterization branch used for SIBR_gaussianViewer_app. Signed-off-by: Matthieu Gendrin <matthieu.gendrin@orange.com>
84 lines
2.9 KiB
Python
84 lines
2.9 KiB
Python
#
|
|
# Copyright (C) 2023, Inria
|
|
# GRAPHDECO research group, https://team.inria.fr/graphdeco
|
|
# All rights reserved.
|
|
#
|
|
# This software is free for non-commercial, research and evaluation use
|
|
# under the terms of the LICENSE.md file.
|
|
#
|
|
# For inquiries contact george.drettakis@inria.fr
|
|
#
|
|
|
|
from scene.cameras import Camera
|
|
import numpy as np
|
|
from utils.general_utils import PILtoTorch
|
|
from utils.graphics_utils import fov2focal
|
|
import math
|
|
|
|
WARNED = False
|
|
|
|
def loadCam(args, id, cam_info, resolution_scale):
|
|
orig_w, orig_h = cam_info.image.size
|
|
|
|
if args.resolution in [1, 2, 4, 8]:
|
|
resolution = round(orig_w/(resolution_scale * args.resolution)), round(orig_h/(resolution_scale * args.resolution))
|
|
else: # should be a type that converts to float
|
|
if args.resolution == -1:
|
|
if orig_w > 1600:
|
|
global WARNED
|
|
if not WARNED:
|
|
print("[ INFO ] Encountered quite large input images (>1.6K pixels width), rescaling to 1.6K.\n "
|
|
"If this is not desired, please explicitly specify '--resolution/-r' as 1")
|
|
WARNED = True
|
|
global_down = orig_w / 1600
|
|
else:
|
|
global_down = 1
|
|
else:
|
|
global_down = orig_w / args.resolution
|
|
|
|
scale = float(global_down) * float(resolution_scale)
|
|
resolution = (int(orig_w / scale), int(orig_h / scale))
|
|
|
|
resized_image_rgb = PILtoTorch(cam_info.image, resolution)
|
|
|
|
gt_image = resized_image_rgb[:3, ...]
|
|
loaded_mask = None
|
|
|
|
if resized_image_rgb.shape[1] == 4:
|
|
loaded_mask = resized_image_rgb[3:4, ...]
|
|
|
|
return Camera(colmap_id=cam_info.uid, R=cam_info.R, T=cam_info.T,
|
|
FovXleft=cam_info.FovXleft, FovXright=cam_info.FovXright, FovYtop=cam_info.FovYtop, FovYbottom=cam_info.FovYbottom,
|
|
image=gt_image, gt_alpha_mask=loaded_mask,
|
|
image_name=cam_info.image_name, uid=id, data_device=args.data_device)
|
|
|
|
def cameraList_from_camInfos(cam_infos, resolution_scale, args):
|
|
camera_list = []
|
|
|
|
for id, c in enumerate(cam_infos):
|
|
camera_list.append(loadCam(args, id, c, resolution_scale))
|
|
|
|
return camera_list
|
|
|
|
def camera_to_JSON(id, camera : Camera):
|
|
Rt = np.zeros((4, 4))
|
|
Rt[:3, :3] = camera.R.transpose()
|
|
Rt[:3, 3] = camera.T
|
|
Rt[3, 3] = 1.0
|
|
|
|
W2C = np.linalg.inv(Rt)
|
|
pos = W2C[:3, 3]
|
|
rot = W2C[:3, :3]
|
|
serializable_array_2d = [x.tolist() for x in rot]
|
|
camera_entry = {
|
|
'id' : id,
|
|
'img_name' : camera.image_name,
|
|
'width' : camera.width,
|
|
'height' : camera.height,
|
|
'position': pos.tolist(),
|
|
'rotation': serializable_array_2d,
|
|
'fy' : camera.height / (2 * math.tan((camera.FovYbottom - camera.FovYtop) / 2)),
|
|
'fx' : camera.width / (2 * math.tan((camera.FovXright - camera.FovXleft) / 2))
|
|
}
|
|
return camera_entry
|