| | import os |
| | import glob |
| | import random |
| |
|
| | import yaml |
| |
|
| | import torch |
| | from torch.utils import data |
| |
|
| | import numpy as np |
| | import json |
| |
|
| | from PIL import Image |
| |
|
| | import h5py |
| | import torch.distributed as dist |
| | import open3d as o3d |
| | o3d.utility.set_verbosity_level(o3d.utility.VerbosityLevel.Error) |
| | import pickle as p |
| | import time |
| | import cv2 |
| | from torchvision import transforms |
| | import copy |
| | from datasets.taxonomy import category_map_from_synthetic as category_ids |
| | class Object_Occ(data.Dataset): |
| | def __init__(self, dataset_folder, split, categories=['03001627', "future_chair", 'ABO_chair'], transform=None, |
| | sampling=True, |
| | num_samples=4096, return_surface=True, surface_sampling=True, surface_size=2048, replica=16): |
| |
|
| | self.pc_size = surface_size |
| |
|
| | self.transform = transform |
| | self.num_samples = num_samples |
| | self.sampling = sampling |
| | self.split = split |
| |
|
| | self.dataset_folder = dataset_folder |
| | self.return_surface = return_surface |
| | self.surface_sampling = surface_sampling |
| |
|
| | self.dataset_folder = dataset_folder |
| | self.point_folder = os.path.join(self.dataset_folder, 'occ_data') |
| | self.mesh_folder = os.path.join(self.dataset_folder, 'other_data') |
| |
|
| | if categories is None: |
| | categories = os.listdir(self.point_folder) |
| | categories = [c for c in categories if |
| | os.path.isdir(os.path.join(self.point_folder, c)) and c.startswith('0')] |
| | categories.sort() |
| |
|
| | print(categories) |
| |
|
| | self.models = [] |
| | for c_idx, c in enumerate(categories): |
| | subpath = os.path.join(self.point_folder, c) |
| | print(subpath) |
| | assert os.path.isdir(subpath) |
| |
|
| | split_file = os.path.join(subpath, split + '.lst') |
| | with open(split_file, 'r') as f: |
| | models_c = f.readlines() |
| | models_c = [item.rstrip('\n') for item in models_c] |
| |
|
| | for m in models_c[:]: |
| | if len(m)<=1: |
| | continue |
| | if m.endswith('.npz'): |
| | model_id = m[:-4] |
| | else: |
| | model_id = m |
| | self.models.append({ |
| | 'category': c, 'model': model_id |
| | }) |
| | self.replica = replica |
| |
|
| | def __getitem__(self, idx): |
| | if self.replica >= 1: |
| | idx = idx % len(self.models) |
| | else: |
| | random_segment = random.randint(0, int(1 / self.replica) - 1) |
| | idx = int(random_segment * self.replica * len(self.models) + idx) |
| |
|
| | category = self.models[idx]['category'] |
| | model = self.models[idx]['model'] |
| |
|
| | point_path = os.path.join(self.point_folder, category, model + '.npz') |
| | |
| | try: |
| | start_t = time.time() |
| | with np.load(point_path) as data: |
| | vol_points = data['vol_points'] |
| | vol_label = data['vol_label'] |
| | near_points = data['near_points'] |
| | near_label = data['near_label'] |
| | end_t = time.time() |
| | |
| | except Exception as e: |
| | print(e) |
| | print(point_path) |
| |
|
| | with open(point_path.replace('.npz', '.npy'), 'rb') as f: |
| | scale = np.load(f).item() |
| | |
| |
|
| | if self.return_surface: |
| | pc_path = os.path.join(self.mesh_folder, category, '4_pointcloud', model + '.npz') |
| | with np.load(pc_path) as data: |
| | try: |
| | surface = data['points'].astype(np.float32) |
| | except: |
| | print(pc_path,"has problems") |
| | raise AttributeError |
| | surface = surface * scale |
| | if self.surface_sampling: |
| | ind = np.random.default_rng().choice(surface.shape[0], self.pc_size, replace=False) |
| | surface = surface[ind] |
| | surface = torch.from_numpy(surface) |
| |
|
| | if self.sampling: |
| | '''need to conduct label balancing''' |
| | vol_ind=np.random.default_rng().choice(vol_points.shape[0], self.num_samples, |
| | replace=(vol_points.shape[0]<self.num_samples)) |
| | near_ind=np.random.default_rng().choice(near_points.shape[0], self.num_samples, |
| | replace=(near_points.shape[0]<self.num_samples)) |
| | vol_points=vol_points[vol_ind] |
| | vol_label=vol_label[vol_ind] |
| | near_points=near_points[near_ind] |
| | near_label=near_label[near_ind] |
| |
|
| | vol_points = torch.from_numpy(vol_points) |
| | vol_label = torch.from_numpy(vol_label).float() |
| |
|
| | if self.split == 'train': |
| | near_points = torch.from_numpy(near_points) |
| | near_label = torch.from_numpy(near_label).float() |
| |
|
| | points = torch.cat([vol_points, near_points], dim=0) |
| | labels = torch.cat([vol_label, near_label], dim=0) |
| | else: |
| | points = vol_points |
| | labels = vol_label |
| |
|
| | tran_mat=np.eye(4) |
| | if self.transform: |
| | surface, points, _,_, tran_mat = self.transform(surface, points) |
| |
|
| | data_dict = { |
| | "points": points, |
| | "labels": labels, |
| | "category_ids": category_ids[category], |
| | "model_id": model, |
| | "tran_mat":tran_mat, |
| | "category":category, |
| | } |
| | if self.return_surface: |
| | data_dict["surface"] = surface |
| |
|
| | return data_dict |
| |
|
| | def __len__(self): |
| | if self.split != 'train': |
| | return len(self.models) |
| | else: |
| | return int(len(self.models) * self.replica) |
| |
|
| | class Object_PartialPoints_MultiImg(data.Dataset): |
| | def __init__(self, dataset_folder, split, split_filename, categories=['03001627', 'future_chair', 'ABO_chair'], |
| | transform=None, sampling=True, num_samples=4096, |
| | return_surface=True, ret_sample=True,surface_sampling=True, |
| | surface_size=20000,par_pc_size=2048, par_point_aug=None,par_prefix="aug7_", |
| | load_proj_mat=False,load_image=False,load_org_img=False,max_img_length=5,load_triplane=True,replica=2, |
| | eval_multiview=False,scene_id=None,num_objects=-1): |
| |
|
| | self.surface_size = surface_size |
| | self.par_pc_size=par_pc_size |
| | self.transform = transform |
| | self.num_samples = num_samples |
| | self.sampling = sampling |
| | self.split = split |
| | self.par_point_aug=par_point_aug |
| | self.par_prefix=par_prefix |
| |
|
| | self.dataset_folder = dataset_folder |
| | self.return_surface = return_surface |
| | self.ret_sample=ret_sample |
| | self.surface_sampling = surface_sampling |
| | self.load_proj_mat=load_proj_mat |
| | self.load_img=load_image |
| | self.load_org_img=load_org_img |
| | self.load_triplane=load_triplane |
| | self.max_img_length=max_img_length |
| | self.eval_multiview=eval_multiview |
| |
|
| | self.dataset_folder = dataset_folder |
| | self.point_folder = os.path.join(self.dataset_folder, 'occ_data') |
| | self.mesh_folder = os.path.join(self.dataset_folder, 'other_data') |
| |
|
| | if scene_id is not None: |
| | scene_model_map_path=os.path.join(self.dataset_folder,"modelid_in_sceneid.json") |
| | with open(scene_model_map_path,'r') as f: |
| | scene_model_map=json.load(f) |
| | valid_modelid=scene_model_map[scene_id] |
| |
|
| | if categories is None: |
| | categories = os.listdir(self.point_folder) |
| | categories = [c for c in categories if |
| | os.path.isdir(os.path.join(self.point_folder, c)) and c.startswith('0')] |
| | categories.sort() |
| |
|
| | print(categories) |
| | self.models = [] |
| | self.model_images_names = {} |
| | for c_idx, c in enumerate(categories): |
| | cat_count=0 |
| | subpath = os.path.join(self.point_folder, c) |
| | print(subpath) |
| | assert os.path.isdir(subpath) |
| |
|
| | split_file = os.path.join(subpath, split_filename) |
| | with open(split_file, 'r') as f: |
| | splits = json.load(f) |
| | for item in splits: |
| | |
| | model_id = item['model_id'] |
| | if scene_id is not None and model_id not in valid_modelid: |
| | continue |
| | image_filenames = item['image_filenames'] |
| | partial_filenames = item['partial_filenames'] |
| | if len(image_filenames)==0 or len(partial_filenames)==0: |
| | continue |
| | self.model_images_names[model_id] = image_filenames |
| | if split=="train": |
| | self.models += [ |
| | {'category': c, 'model': model_id, "partial_filenames": partial_filenames, |
| | "image_filenames": image_filenames} |
| | ] |
| | else: |
| | if self.eval_multiview: |
| | for length in range(0,len(image_filenames)): |
| | self.models+=[ |
| | {'category': c, 'model': model_id, "partial_filenames": partial_filenames[0:1], |
| | "image_filenames": image_filenames[0:length+1]} |
| | ] |
| | self.models += [ |
| | {'category': c, 'model': model_id, "partial_filenames": partial_filenames[0:1], |
| | "image_filenames": image_filenames} |
| | ] |
| | if num_objects!=-1: |
| | indexes=np.linspace(0,len(self.models)-1,num=num_objects).astype(np.int32) |
| | self.models = [self.models[i] for i in indexes] |
| |
|
| | self.replica = replica |
| |
|
| | def load_samples(self,point_path): |
| | try: |
| | start_t = time.time() |
| | with np.load(point_path) as data: |
| | vol_points = data['vol_points'] |
| | vol_label = data['vol_label'] |
| | near_points = data['near_points'] |
| | near_label = data['near_label'] |
| | end_t = time.time() |
| | |
| | except Exception as e: |
| | print(e) |
| | print(point_path) |
| | return vol_points,vol_label,near_points,near_label |
| |
|
| | def load_surface(self,surface_path,scale): |
| | with np.load(surface_path) as data: |
| | surface = data['points'].astype(np.float32) |
| | surface = surface * scale |
| | if self.surface_sampling: |
| | ind = np.random.default_rng().choice(surface.shape[0], self.surface_size, replace=False) |
| | surface = surface[ind] |
| | surface = torch.from_numpy(surface).float() |
| | return surface |
| |
|
| | def load_par_points(self,partial_path,scale): |
| | |
| | par_point_o3d = o3d.io.read_point_cloud(partial_path) |
| | par_points = np.asarray(par_point_o3d.points) |
| | par_points = par_points * scale |
| | replace = par_points.shape[0] < self.par_pc_size |
| | ind = np.random.default_rng().choice(par_points.shape[0], self.par_pc_size, replace=replace) |
| | par_points = par_points[ind] |
| | par_points = torch.from_numpy(par_points).float() |
| | return par_points |
| |
|
| | def process_samples(self,vol_points,vol_label,near_points,near_label): |
| | if self.sampling: |
| | ind = np.random.default_rng().choice(vol_points.shape[0], self.num_samples, replace=False) |
| | vol_points = vol_points[ind] |
| | vol_label = vol_label[ind] |
| |
|
| | ind = np.random.default_rng().choice(near_points.shape[0], self.num_samples, replace=False) |
| | near_points = near_points[ind] |
| | near_label = near_label[ind] |
| | vol_points = torch.from_numpy(vol_points) |
| | vol_label = torch.from_numpy(vol_label).float() |
| | if self.split == 'train': |
| | near_points = torch.from_numpy(near_points) |
| | near_label = torch.from_numpy(near_label).float() |
| |
|
| | points = torch.cat([vol_points, near_points], dim=0) |
| | labels = torch.cat([vol_label, near_label], dim=0) |
| | else: |
| | ind = np.random.default_rng().choice(vol_points.shape[0], 100000, replace=False) |
| | points = vol_points[ind] |
| | labels = vol_label[ind] |
| | return points,labels |
| |
|
| | def __getitem__(self, idx): |
| | if self.replica >= 1: |
| | idx = idx % len(self.models) |
| | else: |
| | random_segment = random.randint(0, int(1 / self.replica) - 1) |
| | idx = int(random_segment * self.replica * len(self.models) + idx) |
| | category = self.models[idx]['category'] |
| | model = self.models[idx]['model'] |
| | |
| | image_filenames = self.models[idx]["image_filenames"] |
| | if self.split=="train": |
| | n_frames = np.random.randint(min(2,len(image_filenames)), min(len(image_filenames) + 1, self.max_img_length + 1)) |
| | img_indexes = np.random.choice(len(image_filenames), n_frames, |
| | replace=(n_frames > len(image_filenames))).tolist() |
| | else: |
| | if self.eval_multiview: |
| | '''use all images''' |
| | n_frames=len(image_filenames) |
| | img_indexes=[i for i in range(n_frames)] |
| | else: |
| | n_frames = min(len(image_filenames),self.max_img_length) |
| | img_indexes=np.linspace(start=0,stop=len(image_filenames)-1,num=n_frames).astype(np.int32) |
| |
|
| | partial_filenames = self.models[idx]['partial_filenames'] |
| | par_index = np.random.choice(len(partial_filenames), 1)[0] |
| | partial_name = partial_filenames[par_index] |
| |
|
| | vol_points,vol_label,near_points,near_label=None,None,None,None |
| | points,labels=None,None |
| | point_path = os.path.join(self.point_folder, category, model + '.npz') |
| | if self.ret_sample: |
| | vol_points,vol_label,near_points,near_label=self.load_samples(point_path) |
| | points,labels = self.process_samples(vol_points, vol_label, near_points,near_label) |
| |
|
| | with open(point_path.replace('.npz', '.npy'), 'rb') as f: |
| | scale = np.load(f).item() |
| |
|
| | surface=None |
| | pc_path = os.path.join(self.mesh_folder, category, '4_pointcloud', model + '.npz') |
| | if self.return_surface: |
| | surface=self.load_surface(pc_path,scale) |
| |
|
| | partial_path = os.path.join(self.mesh_folder, category, "5_partial_points", model, partial_name) |
| | if self.par_point_aug is not None and random.random()<self.par_point_aug: |
| | par_aug_path=os.path.join(self.mesh_folder, category, "5_partial_points", model, self.par_prefix+partial_name) |
| | |
| | if os.path.exists(par_aug_path): |
| | partial_path=par_aug_path |
| | else: |
| | raise FileNotFoundError |
| | par_points=self.load_par_points(partial_path,scale) |
| |
|
| | image_list=[] |
| | valid_frames=[] |
| | image_namelist=[] |
| | if self.load_img: |
| | for img_index in img_indexes: |
| | image_name=image_filenames[img_index] |
| | image_feat_path=os.path.join(self.mesh_folder,category,"7_img_features",model,image_name[:-4]+'.npz') |
| | image=np.load(image_feat_path)["img_features"] |
| | image_list.append(torch.from_numpy(image).float()) |
| | valid_frames.append(True) |
| | image_namelist.append(image_name) |
| | while len(image_list)<self.max_img_length: |
| | image_list.append(torch.from_numpy(np.zeros(image_list[0].shape).astype(np.float32)).float()) |
| | valid_frames.append(False) |
| | org_img_list=[] |
| | if self.load_org_img: |
| | for img_index in img_indexes: |
| | image_name = image_filenames[img_index] |
| | image_path = os.path.join(self.mesh_folder, category, "6_images", model, |
| | image_name) |
| | org_image = cv2.imread(image_path) |
| | org_image = cv2.resize(org_image,dsize=(224,224),interpolation=cv2.INTER_LINEAR) |
| | org_img_list.append(org_image) |
| |
|
| | proj_mat=None |
| | proj_mat_list=[] |
| | if self.load_proj_mat: |
| | for img_index in img_indexes: |
| | image_name = image_filenames[img_index] |
| | proj_mat_path = os.path.join(self.mesh_folder, category, "8_proj_matrix", model, image_name[:-4]+".npy") |
| | proj_mat=np.load(proj_mat_path) |
| | proj_mat_list.append(proj_mat) |
| | while len(proj_mat_list)<self.max_img_length: |
| | proj_mat_list.append(np.eye(4)) |
| | tran_mat=None |
| | if self.load_triplane: |
| | triplane_folder=os.path.join(self.mesh_folder,category,'9_triplane_kl25_64',model) |
| | triplane_list=os.listdir(triplane_folder) |
| | select_index=np.random.randint(0,len(triplane_list)) |
| | triplane_path=os.path.join(triplane_folder,triplane_list[select_index]) |
| | |
| | triplane_content=np.load(triplane_path) |
| | triplane_mean,triplane_logvar,tran_mat=triplane_content['mean'],triplane_content['logvar'],triplane_content['tran_mat'] |
| | tran_mat=torch.from_numpy(tran_mat).float() |
| |
|
| | if self.transform: |
| | if not self.load_triplane: |
| | surface, points, par_points,proj_mat,tran_mat = self.transform(surface, points, par_points,proj_mat_list) |
| | tran_mat=torch.from_numpy(tran_mat).float() |
| | else: |
| | surface, points, par_points, proj_mat = self.transform(surface, points, par_points, proj_mat_list,tran_mat) |
| |
|
| | category_id=category_ids[category] |
| | one_hot=torch.zeros((6)).float() |
| | one_hot[category_id]=1.0 |
| | ret_dict = { |
| | "category_ids": category_ids[category], |
| | "category":category, |
| | "category_code":one_hot, |
| | "model_id": model, |
| | "partial_name": partial_name[:-4], |
| | "class_name": category, |
| | } |
| | if tran_mat is not None: |
| | ret_dict["tran_mat"]=tran_mat |
| | if self.ret_sample: |
| | ret_dict["points"]=points |
| | ret_dict["labels"]=labels |
| | if self.return_surface: |
| | ret_dict["surface"] = surface |
| | ret_dict["par_points"] = par_points |
| | if self.load_img: |
| | ret_dict["image"] = torch.stack(image_list,dim=0) |
| | ret_dict["valid_frames"]= torch.tensor(valid_frames).bool() |
| | if self.load_org_img: |
| | ret_dict["org_image"]=org_img_list |
| | ret_dict["image_namelist"]=image_namelist |
| | if self.load_proj_mat: |
| | ret_dict["proj_mat"]=torch.stack([torch.from_numpy(mat) for mat in proj_mat_list],dim=0) |
| | if self.load_triplane: |
| | ret_dict['triplane_mean']=torch.from_numpy(triplane_mean).float() |
| | ret_dict['triplane_logvar'] = torch.from_numpy(triplane_logvar).float() |
| | return ret_dict |
| |
|
| | def __len__(self): |
| | if self.split != 'train': |
| | return len(self.models) |
| | else: |
| | return int(len(self.models) * self.replica) |