import os
import random
import json
import torch
from utils.system_utils import searchForMaxIteration
from scene.dataset_readers import sceneLoadTypeCallbacks, storePly
from scene.gaussian_model import GaussianModel
from arguments import ModelParams
from utils.camera_utils import cameraList_from_camInfos, camera_to_JSON
class Scene:
gaussians : GaussianModel
def __init__(self, args : ModelParams, gaussians : GaussianModel, load_iteration=None, shuffle=True, resolution_scales=[1.0], ply_path=None, logger=None):
"""
:param path: Path to colmap scene main folder.
"""
self.model_path = args.model_path
self.loaded_iter = None
self.gaussians = gaussians
self.resolution_scales = resolution_scales
if load_iteration:
if load_iteration == -1:
self.loaded_iter = searchForMaxIteration(os.path.join(self.model_path, "point_cloud"))
else:
self.loaded_iter = load_iteration
print("Loading trained model at iteration {}".format(self.loaded_iter))
self.train_cameras = {}
self.test_cameras = {}
if os.path.exists(os.path.join(args.source_path, "sparse")):
scene_info = sceneLoadTypeCallbacks["Colmap"](args.source_path, args.images, args.eval, args.ds)
elif os.path.exists(os.path.join(args.source_path, "transforms_train.json")):
scene_info = sceneLoadTypeCallbacks["Blender"](args.source_path, args.random_background, args.white_background, args.eval, ply_path=ply_path)
else:
scene_info = sceneLoadTypeCallbacks["City"](args.source_path, args.random_background, args.white_background, args.eval, args.ds, undistorted=args.undistorted)
self.gaussians.set_appearance(len(scene_info.train_cameras))
if not self.loaded_iter:
points = self.save_ply(scene_info.point_cloud, args.ratio, os.path.join(self.model_path, "input.ply"))
json_cams = []
camlist = []
if scene_info.test_cameras:
camlist.extend(scene_info.test_cameras)
if scene_info.train_cameras:
camlist.extend(scene_info.train_cameras)
for id, cam in enumerate(camlist):
json_cams.append(camera_to_JSON(id, cam))
with open(os.path.join(self.model_path, "cameras.json"), 'w') as file:
json.dump(json_cams, file)
if shuffle:
random.shuffle(scene_info.train_cameras)
random.shuffle(scene_info.test_cameras)
self.cameras_extent = scene_info.nerf_normalization["radius"]
for resolution_scale in self.resolution_scales:
print("Loading Training Cameras")
self.train_cameras[resolution_scale] = cameraList_from_camInfos(scene_info.train_cameras, resolution_scale, args)
print("Loading Test Cameras")
self.test_cameras[resolution_scale] = cameraList_from_camInfos(scene_info.test_cameras, resolution_scale, args)
if self.loaded_iter:
self.gaussians.load_ply_sparse_gaussian(os.path.join(self.model_path,
"point_cloud",
"iteration_" + str(self.loaded_iter),
"point_cloud.ply"))
self.gaussians.load_mlp_checkpoints(os.path.join(self.model_path,
"point_cloud",
"iteration_" + str(self.loaded_iter)))
print("Load Voxel Size: ", self.gaussians.voxel_size)
print("Load Standard Dist: ", self.gaussians.standard_dist)
else:
if args.random_background:
logger.info("Using random background")
elif args.white_background:
logger.info("Using white background")
else:
logger.info("Using black background")
points = torch.unique(points, dim=0)
self.gaussians.set_level(points, self.train_cameras, self.resolution_scales, args.dist_ratio, args.init_level, args.levels)
self.gaussians.create_from_pcd(points, self.cameras_extent, logger)
def save_ply(self, pcd, ratio, path):
points = torch.tensor(pcd.points[::ratio]).float().cuda()
colors = torch.tensor(pcd.colors[::ratio]).float().cuda()
storePly(path, points.cpu().numpy(), colors.cpu().numpy())
return points
def save(self, iteration):
point_cloud_path = os.path.join(self.model_path, "point_cloud/iteration_{}".format(iteration))
self.gaussians.save_ply(os.path.join(point_cloud_path, "point_cloud.ply"))
self.gaussians.save_mlp_checkpoints(point_cloud_path)
def getTrainCameras(self):
all_cams = []
for scale in self.resolution_scales:
all_cams.extend(self.train_cameras[scale])
return all_cams
def getTestCameras(self):
all_cams = []
for scale in self.resolution_scales:
all_cams.extend(self.test_cameras[scale])
return all_cams