def __init__(self, opt, test=False): super().__init__(opt) self.init_fix() self.print_loss_info() self.git_repo_path = "https://github.com/ThibaultGROUEIX/CycleConsistentDeformation/commit/" self.init_save_dict(opt) self.ddn_config = config.load_config(self.opt.ddn_config, os.path.join(os.environ['DDN_HOME'], 'configs/default.yaml')) if test: self.ddn_config['training']['cycle_length'] = 1
def __init__(self, cfg_path, pointcloud_n, dataset=None, model_file=None): self.cfg = config.load_config(cfg_path, 'configs/default.yaml') self.pointcloud_n = pointcloud_n self.dataset = dataset self.model = config.get_model(self.cfg, dataset) # Output directory of psgn model out_dir = self.cfg['training']['out_dir'] # If model_file not specified, use the one from psgn model if model_file is None: model_file = self.cfg['test']['model_file'] # Load model self.checkpoint_io = CheckpointIO(model=model, checkpoint_dir=out_dir) self.checkpoint_io.load(model_file)
from im2mesh.checkpoints import CheckpointIO # Arguments parser = argparse.ArgumentParser( description='Train a 3D reconstruction model.') parser.add_argument('config', type=str, help='Path to config file.') parser.add_argument('--no-cuda', action='store_true', help='Do not use cuda.') parser.add_argument( '--exit-after', type=int, default=-1, help='Checkpoint and exit after specified number of seconds' 'with exit code 2.') args = parser.parse_args() cfg = config.load_config(args.config, 'configs/default.yaml') is_cuda = (torch.cuda.is_available() and not args.no_cuda) device = torch.device("cuda:1" if is_cuda else "cpu") # Set t0 t0 = time.time() # Shorthands out_dir = cfg['training']['out_dir'] batch_size = cfg['training']['batch_size'] backup_every = cfg['training']['backup_every'] exit_after = args.exit_after model_selection_metric = cfg['training']['model_selection_metric'] if cfg['training']['model_selection_mode'] == 'maximize': model_selection_sign = 1
import csv import warnings # Arguments parser = argparse.ArgumentParser( description='Train a 3D reconstruction model.') parser.add_argument('--no-cuda', action='store_true', help='Do not use cuda.') parser.add_argument( '--exit-after', type=int, default=-1, help='Checkpoint and exit after specified number of seconds' 'with exit code 2.') args = parser.parse_args() cfg = config.load_config('configs/semseg/onet.yaml', 'configs/default.yaml') is_cuda = (torch.cuda.is_available() and not args.no_cuda) device = torch.device("cuda" if is_cuda else "cpu") # Set t0 t0 = time.time() # Shorthands hardcoded root = "/visinf/projects_students/VCLabOccNet/test" out_dir = "out/semseg/onet" batch_size = 64 backup_every = 500 exit_after = args.exit_after epoch_limit = 100 model_selection_metric = 'iou_complete'
'--da', action='store_true', help= 'Generate using the target dataset, for unsupervised domain adaptation.') parser.add_argument( '--generation_dir', type=str, default="", help= 'path of generation dir. If omitted, will use the one in the config yaml') args = parser.parse_args() config_yaml_path = glob.glob(os.path.join(args.out_dir, "*.yaml")) if len(config_yaml_path) != 1: raise ValueError("no yaml, or more than one yaml") cfg = config.load_config(config_yaml_path[0], 'configs/default.yaml') is_cuda = (torch.cuda.is_available() and not args.no_cuda) device = torch.device("cuda:{}".format(args.gpu) if is_cuda else "cpu") # Shorthands out_dir = cfg['training']['out_dir'] if args.generation_dir == "": generation_dir = os.path.join(out_dir, cfg['generation']['generation_dir']) else: generation_dir = os.path.join(out_dir, args.generation_dir) if not args.eval_input: out_file = os.path.join(generation_dir, 'eval_meshes_full.pkl') out_file_class = os.path.join(generation_dir, 'eval_meshes.csv') else:
from collections import defaultdict import pandas as pd import tensorflow as tf from im2mesh import config from im2mesh.checkpoints import CheckpointIO from im2mesh.utils.io import export_pointcloud from im2mesh.utils.visualize import visualize_data from im2mesh.utils.voxels import VoxelGrid parser = argparse.ArgumentParser( description="Extract meshes from occupancy process.") parser.add_argument("config", type=str, help="Path to config file.") parser.add_argument("--no-cuda", action="store_true", help="Do not use cuda.") args = parser.parse_args() cfg = config.load_config(args.config, "configs/default.yaml") out_dir = cfg["training"]["out_dir"] generation_dir = os.path.join(out_dir, cfg["generation"]["generation_dir"]) out_time_file = os.path.join(generation_dir, "time_generation_full.pkl") out_time_file_class = os.path.join(generation_dir, "time_generation.pkl") batch_size = cfg["generation"]["batch_size"] input_type = cfg["data"]["input_type"] vis_n_outputs = cfg["generation"]["vis_n_outputs"] if vis_n_outputs is None: vis_n_outputs = -1 # Model # Dataset dataset = config.get_dataset('test',
help="Do not use cuda.", default=True) parser.add_argument( "--exit-after", type=int, default=-1, help= "Checkpoint and exit after specified number of seconds with exit code 2." ) args = parser.parse_args() return args if __name__ == "__main__": args = get_args() cfg = config.load_config(args.config, "configs/shapenet_singleview.yaml") is_cuda = (torch.cuda.is_available() and not args.no_cuda) device = torch.device("cuda" if is_cuda else "cpu") # Set t0 t0 = time.time() # Shorthands out_dir = cfg['training']['out_dir'] batch_size = cfg['training']['batch_size'] backup_every = cfg['training']['backup_every'] exit_after = args.exit_after model_selection_metric = cfg['training']['model_selection_metric'] if cfg['training']['model_selection_mode'] == 'maximize': model_selection_sign = 1
from im2mesh import config, data from im2mesh.checkpoints import CheckpointIO # Arguments parser = argparse.ArgumentParser( description='Train a 3D reconstruction model.' ) parser.add_argument('config', type=str, help='Path to config file.') parser.add_argument('--no-cuda', action='store_true', help='Do not use cuda.') parser.add_argument('--exit-after', type=int, default=-1, help='Checkpoint and exit after specified number of seconds' 'with exit code 2.') args = parser.parse_args() cfg = config.load_config(args.config, '/home/hpclab/kyg/occupancy_networks/configs/default.yaml') is_cuda = (torch.cuda.is_available() and not args.no_cuda) device = torch.device("cuda" if is_cuda else "cpu") # Set t0 t0 = time.time() # Shorthands out_dir = cfg['training']['out_dir'] batch_size = cfg['training']['batch_size'] backup_every = cfg['training']['backup_every'] exit_after = args.exit_after model_selection_metric = cfg['training']['model_selection_metric'] if cfg['training']['model_selection_mode'] == 'maximize': model_selection_sign = 1
def SMPLD_register(args): cfg = config.load_config(args.config, 'configs/default.yaml') out_dir = cfg['training']['out_dir'] generation_dir = os.path.join(out_dir, cfg['generation']['generation_dir']) is_cuda = (torch.cuda.is_available() and not args.no_cuda) device = torch.device("cuda" if is_cuda else "cpu") if args.subject_idx >= 0 and args.sequence_idx >= 0: logger, _ = create_logger(generation_dir, phase='reg_subject{}_sequence{}'.format(args.subject_idx, args.sequence_idx), create_tf_logs=False) else: logger, _ = create_logger(generation_dir, phase='reg_all', create_tf_logs=False) # Get dataset if args.subject_idx >= 0 and args.sequence_idx >= 0: dataset = config.get_dataset('test', cfg, sequence_idx=args.sequence_idx, subject_idx=args.subject_idx) else: dataset = config.get_dataset('test', cfg) batch_size = cfg['generation']['batch_size'] # Loader test_loader = torch.utils.data.DataLoader( dataset, batch_size=batch_size, num_workers=1, shuffle=False) model_counter = defaultdict(int) # Set optimization hyper parameters iterations, pose_iterations, steps_per_iter, pose_steps_per_iter = 3, 2, 30, 30 inner_dists = [] outer_dists = [] for it, data in enumerate(tqdm(test_loader)): idxs = data['idx'].cpu().numpy() loc = data['points.loc'].cpu().numpy() batch_size = idxs.shape[0] # Directories to load corresponding informations mesh_dir = os.path.join(generation_dir, 'meshes') # directory for posed and (optionally) unposed implicit outer/inner meshes label_dir = os.path.join(generation_dir, 'labels') # directory for part labels register_dir = os.path.join(generation_dir, 'registrations') # directory for part labels if args.use_raw_scan: scan_dir = dataset.dataset_folder # this is the folder that contains CAPE raw scans else: scan_dir = None all_posed_minimal_meshes = [] all_posed_cloth_meshes = [] all_posed_vertices = [] all_unposed_vertices = [] scan_part_labels = [] for idx in idxs: model_dict = dataset.get_model_dict(idx) subset = model_dict['subset'] subject = model_dict['subject'] sequence = model_dict['sequence'] gender = model_dict['gender'] filebase = os.path.basename(model_dict['data_path'])[:-4] folder_name = os.path.join(subset, subject, sequence) # TODO: we assume batch size stays the same if one resumes the job # can be more flexible to support different batch sizes before and # after resume register_file = os.path.join(register_dir, folder_name, filebase + 'minimal.registered.ply') if os.path.exists(register_file): # batch already computed, break break # points_dict = np.load(model_dict['data_path']) # gender = str(points_dict['gender']) mesh_dir_ = os.path.join(mesh_dir, folder_name) label_dir_ = os.path.join(label_dir, folder_name) if scan_dir is not None: scan_dir_ = os.path.join(scan_dir, subject, sequence) # Load part labels and vertex translations label_file_name = filebase + '.minimal.npz' label_dict = dict(np.load(os.path.join(label_dir_, label_file_name))) labels = torch.tensor(label_dict['part_labels'].astype(np.int64)).to(device) # part labels for each vertex (14 or 24) scan_part_labels.append(labels) # Load minimal implicit surfaces mesh_file_name = filebase + '.minimal.posed.ply' # posed_mesh = Mesh(filename=os.path.join(mesh_dir_, mesh_file_name)) posed_mesh = trimesh.load(os.path.join(mesh_dir_, mesh_file_name), process=False) posed_vertices = np.array(posed_mesh.vertices) all_posed_vertices.append(posed_vertices) posed_mesh = tm.from_tensors(torch.tensor(posed_mesh.vertices.astype('float32'), requires_grad=False, device=device), torch.tensor(posed_mesh.faces.astype('int64'), requires_grad=False, device=device)) all_posed_minimal_meshes.append(posed_mesh) mesh_file_name = filebase + '.minimal.unposed.ply' if os.path.exists(os.path.join(mesh_dir_, mesh_file_name)) and args.init_pose: # unposed_mesh = Mesh(filename=os.path.join(mesh_dir_, mesh_file_name)) unposed_mesh = trimesh.load(os.path.join(mesh_dir_, mesh_file_name), process=False) unposed_vertices = np.array(unposed_mesh.vertices) all_unposed_vertices.append(unposed_vertices) if args.use_raw_scan: # Load raw scans mesh_file_name = filebase + '.ply' # posed_mesh = Mesh(filename=os.path.join(scan_dir_, mesh_file_name)) posed_mesh = trimesh.load(os.path.join(scan_dir_, mesh_file_name), process=False) posed_mesh = tm.from_tensors(torch.tensor(posed_mesh.vertices.astype('float32') / 1000, requires_grad=False, device=device), torch.tensor(posed_mesh.faces.astype('int64'), requires_grad=False, device=device)) all_posed_cloth_meshes.append(posed_mesh) else: # Load clothed implicit surfaces mesh_file_name = filebase + '.cloth.posed.ply' # posed_mesh = Mesh(filename=os.path.join(mesh_dir_, mesh_file_name)) posed_mesh = trimesh.load(os.path.join(mesh_dir_, mesh_file_name), process=False) posed_mesh = tm.from_tensors(torch.tensor(posed_mesh.vertices.astype('float32'), requires_grad=False, device=device), torch.tensor(posed_mesh.faces.astype('int64'), requires_grad=False, device=device)) all_posed_cloth_meshes.append(posed_mesh) if args.num_joints == 24: bm = BodyModel(bm_path='body_models/smpl/male/model.pkl', num_betas=10, batch_size=batch_size).to(device) parents = bm.kintree_table[0].detach().cpu().numpy() labels = bm.weights.argmax(1) # Convert 24 parts to 14 parts smpl2ipnet = torch.from_numpy(SMPL2IPNET_IDX).to(device) labels = smpl2ipnet[labels].clone().unsqueeze(0) del bm elif args.num_joints == 14: with open('body_models/misc/smpl_parts_dense.pkl', 'rb') as f: part_labels = pkl.load(f) labels = np.zeros((6890,), dtype=np.int64) for n, k in enumerate(part_labels): labels[part_labels[k]] = n labels = torch.tensor(labels).to(device).unsqueeze(0) else: raise ValueError('Got {} joints but umber of joints can only be either 14 or 24'.format(args.num_joints)) th_faces = torch.tensor(smpl_faces.astype('float32'), dtype=torch.long).to(device) # We assume loaded meshes are properly scaled and offsetted to the orignal SMPL space, if len(all_posed_minimal_meshes) > 0 and len(all_unposed_vertices) == 0: # IPNet optimization without vertex traslation # raise NotImplementedError('Optimization for IPNet is not implemented yet.') if args.num_joints == 24: for idx in range(len(scan_part_labels)): scan_part_labels[idx] = smpl2ipnet[scan_part_labels[idx]].clone() prior = get_prior(gender=gender, precomputed=True) pose_init = torch.zeros((batch_size, 72)) pose_init[:, 3:] = prior.mean betas, pose, trans = torch.zeros((batch_size, 10)), pose_init, torch.zeros((batch_size, 3)) # Init SMPL, pose with mean smpl pose, as in ch.registration smpl = th_batch_SMPL(batch_size, betas, pose, trans, faces=th_faces, gender=gender).to(device) smpl_part_labels = torch.cat([labels] * batch_size, axis=0) # Optimize pose first optimize_pose_only(all_posed_minimal_meshes, smpl, pose_iterations, pose_steps_per_iter, scan_part_labels, smpl_part_labels, None, args) # Optimize pose and shape optimize_pose_shape(all_posed_minimal_meshes, smpl, iterations, steps_per_iter, scan_part_labels, smpl_part_labels, None, args) inner_vertices, _, _, _ = smpl() # Optimize vertices for SMPLD init_smpl_meshes = [tm.from_tensors(vertices=v.clone().detach(), faces=smpl.faces) for v in inner_vertices] optimize_offsets(all_posed_cloth_meshes, smpl, init_smpl_meshes, 5, 10, args) outer_vertices, _, _, _ = smpl() elif len(all_posed_minimal_meshes) > 0: # NASA+PTFs optimization with vertex traslations # Compute poses from implicit surfaces and correspondences # TODO: we could also compute bone-lengths if we train PTFs to predict A-pose with a global translation # that equals to the centroid of the pointcloud poses = compute_poses(all_posed_vertices, all_unposed_vertices, scan_part_labels, parents, args) # Convert 24 parts to 14 parts for idx in range(len(scan_part_labels)): scan_part_labels[idx] = smpl2ipnet[scan_part_labels[idx]].clone() pose_init = torch.from_numpy(poses).float() betas, pose, trans = torch.zeros((batch_size, 10)), pose_init, torch.zeros((batch_size, 3)) # Init SMPL, pose with mean smpl pose, as in ch.registration smpl = th_batch_SMPL(batch_size, betas, pose, trans, faces=th_faces, gender=gender).to(device) smpl_part_labels = torch.cat([labels] * batch_size, axis=0) # Optimize pose first optimize_pose_only(all_posed_minimal_meshes, smpl, pose_iterations, pose_steps_per_iter, scan_part_labels, smpl_part_labels, None, args) # Optimize pose and shape optimize_pose_shape(all_posed_minimal_meshes, smpl, iterations, steps_per_iter, scan_part_labels, smpl_part_labels, None, args) inner_vertices, _, _, _ = smpl() # Optimize vertices for SMPLD init_smpl_meshes = [tm.from_tensors(vertices=v.clone().detach(), faces=smpl.faces) for v in inner_vertices] optimize_offsets(all_posed_cloth_meshes, smpl, init_smpl_meshes, 5, 10, args) outer_vertices, _, _, _ = smpl() else: inner_vertices = outer_vertices = None if args.use_raw_scan: for i, idx in enumerate(idxs): model_dict = dataset.get_model_dict(idx) subset = model_dict['subset'] subject = model_dict['subject'] sequence = model_dict['sequence'] filebase = os.path.basename(model_dict['data_path'])[:-4] folder_name = os.path.join(subset, subject, sequence) register_dir_ = os.path.join(register_dir, folder_name) if not os.path.exists(register_dir_): os.makedirs(register_dir_) if not os.path.exists(os.path.join(register_dir_, filebase + 'minimal.registered.ply')): registered_mesh = trimesh.Trimesh(inner_vertices[i].detach().cpu().numpy().astype(np.float64), smpl_faces, process=False) registered_mesh.export(os.path.join(register_dir_, filebase + 'minimal.registered.ply')) if not os.path.exists(os.path.join(register_dir_, filebase + 'cloth.registered.ply')): registered_mesh = trimesh.Trimesh(outer_vertices[i].detach().cpu().numpy().astype(np.float64), smpl_faces, process=False) registered_mesh.export(os.path.join(register_dir_, filebase + 'cloth.registered.ply')) else: # Evaluate registered mesh gt_smpl_mesh = data['points.minimal_smpl_vertices'].to(device) gt_smpld_mesh = data['points.smpl_vertices'].to(device) if inner_vertices is None: # if vertices are None, we assume they already exist due to previous runs inner_vertices = [] outer_vertices = [] for i, idx in enumerate(idxs): model_dict = dataset.get_model_dict(idx) subset = model_dict['subset'] subject = model_dict['subject'] sequence = model_dict['sequence'] filebase = os.path.basename(model_dict['data_path'])[:-4] folder_name = os.path.join(subset, subject, sequence) register_dir_ = os.path.join(register_dir, folder_name) # registered_mesh = Mesh(filename=os.path.join(register_dir_, filebase + 'minimal.registered.ply')) registered_mesh = trimesh.load(os.path.join(register_dir_, filebase + 'minimal.registered.ply'), process=False) registered_v = torch.tensor(registered_mesh.vertices.astype(np.float32), requires_grad=False, device=device) inner_vertices.append(registered_v) # registered_mesh = Mesh(filename=os.path.join(register_dir_, filebase + 'cloth.registered.ply')) registered_mesh = trimesh.load(os.path.join(register_dir_, filebase + 'cloth.registered.ply'), process=False) registered_v = torch.tensor(registered_mesh.vertices.astype(np.float32), requires_grad=False, device=device) outer_vertices.append(registered_v) inner_vertices = torch.stack(inner_vertices, dim=0) outer_vertices = torch.stack(outer_vertices, dim=0) inner_dist = torch.norm(gt_smpl_mesh - inner_vertices, dim=2).mean(-1) outer_dist = torch.norm(gt_smpld_mesh - outer_vertices, dim=2).mean(-1) for i, idx in enumerate(idxs): model_dict = dataset.get_model_dict(idx) subset = model_dict['subset'] subject = model_dict['subject'] sequence = model_dict['sequence'] filebase = os.path.basename(model_dict['data_path'])[:-4] folder_name = os.path.join(subset, subject, sequence) register_dir_ = os.path.join(register_dir, folder_name) if not os.path.exists(register_dir_): os.makedirs(register_dir_) logger.info('Inner distance for input {}: {} cm'.format(filebase, inner_dist[i].item())) logger.info('Outer distance for input {}: {} cm'.format(filebase, outer_dist[i].item())) if not os.path.exists(os.path.join(register_dir_, filebase + 'minimal.registered.ply')): registered_mesh = trimesh.Trimesh(inner_vertices[i].detach().cpu().numpy().astype(np.float64), smpl_faces, process=False) registered_mesh.export(os.path.join(register_dir_, filebase + 'minimal.registered.ply')) if not os.path.exists(os.path.join(register_dir_, filebase + 'cloth.registered.ply')): registered_mesh = trimesh.Trimesh(outer_vertices[i].detach().cpu().numpy().astype(np.float64), smpl_faces, process=False) registered_mesh.export(os.path.join(register_dir_, filebase + 'cloth.registered.ply')) inner_dists.extend(inner_dist.detach().cpu().numpy()) outer_dists.extend(outer_dist.detach().cpu().numpy()) logger.info('Mean inner distance: {} cm'.format(np.mean(inner_dists))) logger.info('Mean outer distance: {} cm'.format(np.mean(outer_dists)))