''' render using frames in GS inpaint with fooocus ''' import os import torch import numpy as np from PIL import Image from copy import deepcopy from ops.utils import * from ops.sky import Sky_Seg_Tool from ops.visual_check import Check from ops.gs.train import GS_Train_Tool from pipe.lvm_inpaint import Inpaint_Tool from pipe.reconstruct import Reconstruct_Tool from ops.trajs import _generate_trajectory from ops.connect import Occlusion_Removal from ops.gs.basic import Frame,Gaussian_Scene from ops.mcs import HackSD_MCS from pipe.refine_mvdps import Refinement_Tool_MCS class Pipeline(): def __init__(self,cfg) -> None: self.device = 'cuda' self.cfg = cfg self.sky_value = cfg.model.sky.value self.sky_segor = Sky_Seg_Tool(cfg) self.rgb_inpaintor = Inpaint_Tool(cfg) self.reconstructor = Reconstruct_Tool(cfg) # temp self.removalor = Occlusion_Removal() self.checkor = Check() def _mkdir(self,dir): if not os.path.exists(dir): os.makedirs(dir) def _resize_input(self,fn): resize_long_edge = int(self.cfg.scene.input.resize_long_edge) print(f'[Preprocess...] Resize the long edge of input image to {resize_long_edge}.') spl = str.rfind(fn,'.') backup_fn = fn[:spl] + '.original' + fn[spl:] rgb = Image.open(fn) rgb.save(backup_fn) # back up original image rgb = np.array(rgb)[:,:,:3]/255. H,W = rgb.shape[0:2] if H>W: W = int(W*resize_long_edge/H) H = resize_long_edge else: H = int(H*resize_long_edge/W) W = resize_long_edge rgb = cv2.resize(rgb,(W,H)) pic = (rgb * 255.0).clip(0, 255) pic_save = Image.fromarray(pic.astype(np.uint8)) pic_save.save(fn) def _initialization(self,rgb): rgb = np.array(rgb)[:,:,:3] # conduct outpainting on rgb and change cu,cv outpaint_frame :Frame = self.rgb_inpaintor(Frame(rgb=rgb), outpaint_selections=self.outpaint_selections, outpaint_extend_times=self.outpaint_extend_times) # conduct reconstruction on outpaint results _,intrinsic,_ = self.reconstructor._ProDpt_(rgb) # estimate focal on input view metric_dpt,intrinsic,edge_msk = self.reconstructor._ProDpt_(outpaint_frame.rgb) outpaint_frame.intrinsic = deepcopy(intrinsic) # split to input and outpaint areas input_frame = Frame(H=rgb.shape[0], W=rgb.shape[1], rgb=rgb, intrinsic=deepcopy(intrinsic), extrinsic=np.eye(4)) input_frame.intrinsic[0,-1] = input_frame.W/2. input_frame.intrinsic[1,-1] = input_frame.H/2. # others input_area = ~outpaint_frame.inpaint input_edg = edge_msk[input_area].reshape(input_frame.H,input_frame.W) input_dpt = metric_dpt[input_area].reshape(input_frame.H,input_frame.W) sky = self.sky_segor(input_frame.rgb) input_frame.sky = sky input_dpt[sky] = self.sky_value input_frame.dpt = input_dpt input_frame.inpaint = np.ones_like(input_edg,bool) & (~sky) input_frame.inpaint_wo_edge = (~input_edg) & (~sky) input_frame.ideal_dpt = deepcopy(input_dpt) input_frame.prompt = outpaint_frame.prompt # outpaint frame sky = self.sky_segor(outpaint_frame.rgb) outpaint_frame.sky = sky metric_dpt[sky] = self.sky_value outpaint_frame.dpt = metric_dpt outpaint_frame.ideal_dpt = deepcopy(metric_dpt) outpaint_frame.inpaint = (outpaint_frame.inpaint)&(~sky) outpaint_frame.inpaint_wo_edge = (outpaint_frame.inpaint)&(~edge_msk) # add init frame self.scene._add_trainable_frame(input_frame,require_grad=True) self.scene._add_trainable_frame(outpaint_frame,require_grad=True) self.scene = GS_Train_Tool(self.scene,iters=100)(self.scene.frames) def _generate_traj(self): self.dense_trajs = _generate_trajectory(self.cfg,self.scene) def _pose_to_frame(self,extrinsic,margin=32): H = self.scene.frames[0].H + margin W = self.scene.frames[0].W + margin prompt = self.scene.frames[-1].prompt intrinsic = deepcopy(self.scene.frames[0].intrinsic) intrinsic[0,-1], intrinsic[1,-1] = W/2, H/2 frame = Frame(H=H,W=W,intrinsic=intrinsic,extrinsic=extrinsic,prompt=prompt) frame = self.scene._render_for_inpaint(frame) return frame def _next_frame(self,margin=32): # select the frame with largest holes but less than 60% inpaint_area_ratio = [] for pose in self.dense_trajs: temp_frame = self._pose_to_frame(pose,margin) inpaint_mask = temp_frame.inpaint inpaint_area_ratio.append(np.mean(inpaint_mask)) inpaint_area_ratio = np.array(inpaint_area_ratio) inpaint_area_ratio[inpaint_area_ratio > 0.6] = 0. # remove adjustancy frames for s in self.select_frames: inpaint_area_ratio[s] = 0. if s-1>-1: inpaint_area_ratio[s-1] = 0. if s+1