mirror of
https://github.com/graphdeco-inria/gaussian-splatting
synced 2024-11-24 21:13:46 +00:00
104 lines
4.1 KiB
Python
104 lines
4.1 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
|
|
#
|
|
|
|
import torch
|
|
from torch import nn
|
|
import numpy as np
|
|
from utils.graphics_utils import getWorld2View2, getProjectionMatrix
|
|
from utils.general_utils import PILtoTorch
|
|
import cv2
|
|
|
|
class Camera(nn.Module):
|
|
def __init__(self, resolution, colmap_id, R, T, FoVx, FoVy, depth_params, image, invdepthmap,
|
|
image_name, uid,
|
|
trans=np.array([0.0, 0.0, 0.0]), scale=1.0, data_device = "cuda",
|
|
train_test_exp = False, is_test_dataset = False, is_test_view = False
|
|
):
|
|
super(Camera, self).__init__()
|
|
|
|
self.uid = uid
|
|
self.colmap_id = colmap_id
|
|
self.R = R
|
|
self.T = T
|
|
self.FoVx = FoVx
|
|
self.FoVy = FoVy
|
|
self.image_name = image_name
|
|
|
|
try:
|
|
self.data_device = torch.device(data_device)
|
|
except Exception as e:
|
|
print(e)
|
|
print(f"[Warning] Custom device {data_device} failed, fallback to default cuda device" )
|
|
self.data_device = torch.device("cuda")
|
|
|
|
resized_image_rgb = PILtoTorch(image, resolution)
|
|
gt_image = resized_image_rgb[:3, ...]
|
|
self.alpha_mask = None
|
|
if resized_image_rgb.shape[0] == 4:
|
|
self.alpha_mask = resized_image_rgb[3:4, ...].to(self.data_device)
|
|
else:
|
|
self.alpha_mask = torch.ones_like(resized_image_rgb[0:1, ...].to(self.data_device))
|
|
|
|
if train_test_exp and is_test_view:
|
|
if is_test_dataset:
|
|
self.alpha_mask[..., :self.alpha_mask.shape[-1] // 2] = 0
|
|
else:
|
|
self.alpha_mask[..., self.alpha_mask.shape[-1] // 2:] = 0
|
|
|
|
self.original_image = gt_image.clamp(0.0, 1.0).to(self.data_device)
|
|
self.image_width = self.original_image.shape[2]
|
|
self.image_height = self.original_image.shape[1]
|
|
|
|
self.invdepthmap = None
|
|
self.depth_reliable = False
|
|
if invdepthmap is not None:
|
|
self.depth_mask = torch.ones_like(self.alpha_mask)
|
|
self.invdepthmap = cv2.resize(invdepthmap, resolution)
|
|
self.invdepthmap[self.invdepthmap < 0] = 0
|
|
self.depth_reliable = True
|
|
|
|
if depth_params is not None:
|
|
if depth_params["scale"] < 0.2 * depth_params["med_scale"] or depth_params["scale"] > 5 * depth_params["med_scale"]:
|
|
self.depth_reliable = False
|
|
self.depth_mask *= 0
|
|
|
|
if depth_params["scale"] > 0:
|
|
self.invdepthmap = self.invdepthmap * depth_params["scale"] + depth_params["offset"]
|
|
|
|
if self.invdepthmap.ndim != 2:
|
|
self.invdepthmap = self.invdepthmap[..., 0]
|
|
self.invdepthmap = torch.from_numpy(self.invdepthmap[None]).to(self.data_device)
|
|
|
|
self.zfar = 100.0
|
|
self.znear = 0.01
|
|
|
|
self.trans = trans
|
|
self.scale = scale
|
|
|
|
self.world_view_transform = torch.tensor(getWorld2View2(R, T, trans, scale)).transpose(0, 1).cuda()
|
|
self.projection_matrix = getProjectionMatrix(znear=self.znear, zfar=self.zfar, fovX=self.FoVx, fovY=self.FoVy).transpose(0,1).cuda()
|
|
self.full_proj_transform = (self.world_view_transform.unsqueeze(0).bmm(self.projection_matrix.unsqueeze(0))).squeeze(0)
|
|
self.camera_center = self.world_view_transform.inverse()[3, :3]
|
|
|
|
class MiniCam:
|
|
def __init__(self, width, height, fovy, fovx, znear, zfar, world_view_transform, full_proj_transform):
|
|
self.image_width = width
|
|
self.image_height = height
|
|
self.FoVy = fovy
|
|
self.FoVx = fovx
|
|
self.znear = znear
|
|
self.zfar = zfar
|
|
self.world_view_transform = world_view_transform
|
|
self.full_proj_transform = full_proj_transform
|
|
view_inv = torch.inverse(self.world_view_transform)
|
|
self.camera_center = view_inv[3][:3]
|
|
|