def testBIWI(model,modelin=args.model,outfile=args.out,feature_transform=args.feat_trans): if modelin != "": model.load_state_dict(torch.load(modelin)) model.eval() # load 3dmm data data3dmm = dataloader.SyntheticLoader() mu_lm = torch.from_numpy(data3dmm.mu_lm).float() lm_eigenvec = torch.from_numpy(data3dmm.lm_eigenvec).float() shape = mu_lm shape[:,2] = shape[:,2] * -1 loader = dataloader.BIWILoader() seterror_3d = [] seterror_rel3d = [] seterror_relf = [] seterror_2d = [] for sub in range(len(loader)): batch = loader[sub] x_cam_gt = batch['x_cam_gt'] x_w_gt = batch['x_w_gt'] f_gt = batch['f_gt'] x_img = batch['x_img'] x_img_gt = batch['x_img_gt'] M = x_img_gt.shape[0] one = torch.ones(M,1,68) x_img_one = torch.cat([x_img,one],dim=1) # run the model out, trans, transfeat = model(x_img_one) alphas = out[:,:199].mean(0) f = torch.relu(out[:,199]).mean() K = torch.zeros((3,3)).float() K[0,0] = f; K[1,1] = f; K[2,2] = 1; K[0,2] = 320; K[1,2] = 240; Xc,R,T = util.EPnP(x_img,shape,K) # apply 3DMM model from predicted parameters reproj_errors2 = util.getReprojError2(x_img,shape,R,T,K) reproj_errors3 = util.getReprojError3(x_cam_gt,shape,R,T) rel_errors = util.getRelReprojError3(x_cam_gt,shape,R,T) reproj_error = reproj_errors2.mean() reconstruction_error = reproj_errors3.mean() rel_error = rel_errors.mean() f_error = torch.abs(f_gt - f) / f_gt seterror_2d.append(reproj_error.cpu().data.item()) seterror_3d.append(reconstruction_error.cpu().data.item()) seterror_rel3d.append(rel_error.cpu().data.item()) seterror_relf.append(f_error.cpu().data.item()) print(f"fgt: {f_gt.mean().item():.3f} | f_error_rel: {f_error.item():.4f} | rmse: {reconstruction_error.item():.4f} | rel rmse: {rel_error.item():.4f} | 2d error: {reproj_error.item():.4f}") #end for matdata = {} matdata['seterror_2d'] = np.array(seterror_2d) matdata['seterror_3d'] = np.array(seterror_3d) matdata['seterror_rel3d'] = np.array(seterror_rel3d) matdata['seterror_relf'] = np.array(seterror_relf) scipy.io.savemat(outfile,matdata) print(f"MEAN seterror_2d: {np.mean(seterror_2d)}") print(f"MEAN seterror_3d: {np.mean(seterror_3d)}") print(f"MEAN seterror_rel3d: {np.mean(seterror_rel3d)}") print(f"MEAN seterror_relf: {np.mean(seterror_relf)}")
def test(model, modelin=args.model,outfile=args.out,feature_transform=args.feat_trans): # define model, dataloader, 3dmm eigenvectors, optimization method if modelin != "": model.load_state_dict(torch.load(modelin)) model.eval() # mean shape and eigenvectors for 3dmm M = 100 data3dmm = dataloader.SyntheticLoader() mu_lm = torch.from_numpy(data3dmm.mu_lm).float() lm_eigenvec = torch.from_numpy(data3dmm.lm_eigenvec).float() shape = mu_lm # sample from f testing set allerror_2d = [] allerror_3d = [] allerror_rel3d = [] allerror_relf = [] all_f = [] all_depth = [] seterror_3d = [] seterror_rel3d = [] seterror_relf = [] seterror_2d = [] f_vals = [i*100 for i in range(4,21)] for f_test in f_vals: # create dataloader data = dataloader.TestLoader(f_test) error_2d = [] error_3d = [] error_rel3d = [] error_relf = [] M = 100; N = 68; batch_size = 1; for k in range(len(data)): batch = data[k] x_cam_gt = batch['x_cam_gt'] x_w_gt = batch['x_w_gt'] f_gt = batch['f_gt'] x_img = batch['x_img'].unsqueeze(0) x_img_gt = batch['x_img_gt'] T_gt = batch['T_gt'] sequence = batch['x_img'].reshape((M,N,2)).permute(0,2,1) all_depth.append(np.mean(T_gt[:,2])) all_f.append(f_gt.numpy()[0]) one = torch.ones(batch_size,M*N,1) x_img_one = torch.cat([x_img,one],dim=2) # run the model out,_,_ = model(x_img_one.permute(0,2,1)) betas = out[:,:199] fout = torch.relu(out[:,199]) if torch.any(fout < 1): fout = fout+1 # apply 3DMM model from predicted parameters alpha_matrix = torch.diag(betas.squeeze()) shape_cov = torch.mm(lm_eigenvec,alpha_matrix) s = shape_cov.sum(1).view(68,3) #shape = (mu_lm + s) #shape = mu_lm #shape[:,2] = shape[:,2]*-1 # run epnp using predicted shape and intrinsics K = torch.zeros((3,3)) K[0,0] = fout; K[1,1] = fout; K[2,2] = 1; K[0,2] = 0; K[1,2] = 0; Xc,R,T = util.EPnP(sequence,shape,K) # get errors reproj_errors2 = util.getReprojError2(sequence,shape,R,T,K) reproj_errors3 = util.getReprojError3(x_cam_gt,shape,R,T) rel_errors = util.getRelReprojError3(x_cam_gt,shape,R,T) reproj_error = reproj_errors2.mean() reconstruction_error = reproj_errors3.mean() rel_error = rel_errors.mean() f_error = torch.abs(f_gt - fout) / f_gt allerror_3d.append(reproj_error.data.numpy()) allerror_2d.append(reconstruction_error.data.numpy()) allerror_rel3d.append(rel_error.data.numpy()) error_2d.append(reproj_error.cpu().data.item()) error_3d.append(reconstruction_error.cpu().data.item()) error_rel3d.append(rel_error.cpu().data.item()) error_relf.append(f_error.cpu().data.item()) print(f"f/sequence: {f_test}/{k} | f/fgt: {fout[0].item():.3f}/{f_gt.item():.3f} | f_error_rel: {f_error.item():.4f} | rmse: {reconstruction_error.item():.4f} | rel rmse: {rel_error.item():.4f} | 2d error: {reproj_error.item():.4f}") #end for avg_2d = np.mean(error_2d) avg_rel3d = np.mean(error_rel3d) avg_3d = np.mean(error_3d) avg_relf = np.mean(error_relf) seterror_2d.append(avg_2d) seterror_3d.append(avg_3d) seterror_rel3d.append(avg_rel3d) seterror_relf.append(avg_relf) #end for all_f = np.stack(all_f).flatten() all_d = np.stack(all_depth).flatten() allerror_2d = np.stack(allerror_2d).flatten() allerror_3d = np.stack(allerror_3d).flatten() allerror_rel3d = np.stack(allerror_rel3d).flatten() matdata = {} matdata['fvals'] = np.array(f_vals) matdata['all_f'] = np.array(all_f) matdata['all_d'] = np.array(all_depth) matdata['error_2d'] = allerror_2d matdata['error_3d'] = allerror_3d matdata['error_rel3d'] = allerror_rel3d matdata['seterror_2d'] = np.array(seterror_2d) matdata['seterror_3d'] = np.array(seterror_3d) matdata['seterror_rel3d'] = np.array(seterror_rel3d) matdata['seterror_relf'] = np.array(seterror_relf) scipy.io.savemat(outfile,matdata) print(f"MEAN seterror_2d: {np.mean(seterror_2d)}") print(f"MEAN seterror_3d: {np.mean(seterror_3d)}") print(f"MEAN seterror_rel3d: {np.mean(seterror_rel3d)}") print(f"MEAN seterror_relf: {np.mean(seterror_relf)}")
def test(modelin=args.model,outfile=args.out,feature_transform=args.feat_trans): # define model, dataloader, 3dmm eigenvectors, optimization method #if modelin != "": # model.load_state_dict(torch.load(modelin)) #model.eval() #model.cuda() # mean shape and eigenvectors for 3dmm M = 100 N = 68 data3dmm = dataloader.SyntheticLoader() mu_lm = torch.from_numpy(data3dmm.mu_lm).float() mu_lm[:,2] = mu_lm[:,2]*-1 lm_eigenvec = torch.from_numpy(data3dmm.lm_eigenvec).float() #optimizer = torch.optim.Adam(model.parameters(),lr=1e-2) # sample from f testing set allerror_2d = [] allerror_3d = [] allerror_rel3d = [] allerror_relf = [] all_f = [] all_depth = [] seterror_3d = [] seterror_rel3d = [] seterror_relf = [] seterror_2d = [] f_vals = [400 + i*100 for i in range(4)] # set random seed for reproducibility of test set np.random.seed(0) for f_test in f_vals: f_test = 1400 # create dataloader loader = dataloader.TestLoader(f_test) error_2d = [] error_3d = [] error_rel3d = [] error_relf = [] M = 100; N = 68; batch_size = 1; for j, data in enumerate(loader): # create a model and optimizer for it theta1 = (1.1*torch.randn(4)).requires_grad() optimizer = torch.optim.SGD({theta},lr=0.00001) model2 = Model1(k=199,feature_transform=False) model2.apply(util.init_weights) model = Model1(k=1, feature_transform=False) model.apply(util.init_weights) optimizer = torch.optim.Adam(list(model.parameters()) + list(model2.parameters()),lr=1) # load the data x_cam_gt = data['x_cam_gt'] shape_gt = data['x_w_gt'] fgt = data['f_gt'] x_img = data['x_img'] x_img_gt = data['x_img_gt'] T_gt = data['T_gt'] all_depth.append(np.mean(T_gt[:,2])) all_f.append(fgt.numpy()[0]) ptsI = x_img.reshape((M,N,2)).permute(0,2,1) x2d = x_img.view((M,N,2)) x_img_pts = x_img.reshape((M,N,2)).permute(0,2,1) one = torch.ones(M*N,1) x_img_one = torch.cat([x_img,one],dim=1) x = x_img_one.permute(1,0) ini_pose = torch.zeros((M,6)) ini_pose[:,5] = 99 pre_loss = 99 for iter in itertools.count(): optimizer.zero_grad() # shape prediction betas,_,_ = model2(x.unsqueeze(0)) shape = torch.sum(betas * lm_eigenvec,1) shape = shape.reshape(68,3) + mu_lm #shape = shape_gt # RMSE between GT and predicted shape rmse = torch.norm(shape_gt - shape,dim=1).mean().detach() # focal length prediction f,_,_ = model(x.unsqueeze(0)) f = f + 300 K = torch.zeros((3,3)).float() K[0,0] = f K[1,1] = f K[2,2] = 1 # differentiable PnP pose estimation pose = bpnp(x2d,shape,K,ini_pose) pred = BPnP.batch_project(pose,shape,K) # loss #loss = torch.mean(torch.abs(pred - x2d)) loss = torch.mean(torch.norm(pred - x2d,dim=2)) loss.backward() optimizer.step() print(f"iter: {iter} | error: {loss.item():.3f} | f/fgt: {f.item():.1f}/{fgt[0].item():.1f} | rmse: {rmse.item():.2f}") if iter == 200: break ini_pose = pose.detach() # get errors km,c_w,scaled_betas, alphas = util.EPnP(ptsI,shape,K) Xc, R, T, mask = util.optimizeGN(km,c_w,scaled_betas,alphas,shape,ptsI,K) # get errors reproj_errors2 = util.getReprojError2(ptsI,shape,R,T,K) reproj_errors3 = util.getReprojError3(x_cam_gt,shape,R,T) rel_errors = util.getRelReprojError3(x_cam_gt,shape,R,T) reproj_error = reproj_errors2.mean() reconstruction_error = reproj_errors3.mean() rel_error = rel_errors.mean() f_error = torch.abs(fgt - f) / fgt allerror_3d.append(reproj_error.data.numpy()) allerror_2d.append(reconstruction_error.data.numpy()) allerror_rel3d.append(rel_error.data.numpy()) error_2d.append(reproj_error.cpu().data.item()) error_3d.append(reconstruction_error.cpu().data.item()) error_rel3d.append(rel_error.cpu().data.item()) error_relf.append(f_error.cpu().data.item()) print(f"f/sequence: {f_test}/{j} | f/fgt: {f[0].item():.3f}/{fgt.item():.3f} | f_error_rel: {f_error.item():.4f} | rmse: {reconstruction_error.item():.4f} | rel rmse: {rel_error.item():.4f} | 2d error: {reproj_error.item():.4f}") #end for avg_2d = np.mean(error_2d) avg_rel3d = np.mean(error_rel3d) avg_3d = np.mean(error_3d) avg_relf = np.mean(error_relf) seterror_2d.append(avg_2d) seterror_3d.append(avg_3d) seterror_rel3d.append(avg_rel3d) seterror_relf.append(avg_relf) #end for break all_f = np.stack(all_f).flatten() all_d = np.stack(all_depth).flatten() allerror_2d = np.stack(allerror_2d).flatten() allerror_3d = np.stack(allerror_3d).flatten() allerror_rel3d = np.stack(allerror_rel3d).flatten() matdata = {} matdata['fvals'] = np.array(f_vals) matdata['all_f'] = np.array(all_f) matdata['all_d'] = np.array(all_depth) matdata['error_2d'] = allerror_2d matdata['error_3d'] = allerror_3d matdata['error_rel3d'] = allerror_rel3d matdata['seterror_2d'] = np.array(seterror_2d) matdata['seterror_3d'] = np.array(seterror_3d) matdata['seterror_rel3d'] = np.array(seterror_rel3d) matdata['seterror_relf'] = np.array(seterror_relf) scipy.io.savemat(outfile,matdata) print(f"MEAN seterror_2d: {np.mean(seterror_2d)}") print(f"MEAN seterror_3d: {np.mean(seterror_3d)}") print(f"MEAN seterror_rel3d: {np.mean(seterror_rel3d)}") print(f"MEAN seterror_relf: {np.mean(seterror_relf)}")
def train(modelin=args.model, modelout=args.out): # define logger #torch.manual_seed(6) #if log: # logger = Logger(logname) # define model, dataloader, 3dmm eigenvectors, optimization method torch.manual_seed(2) calib_net = Model1(k=1, feature_transform=False) sfm_net = Model1(k=199, feature_transform=False) #if modelin != "": # model.load_state_dict(torch.load(modelin)) opt1 = torch.optim.Adam(calib_net.parameters(), lr=1e-1) opt2 = torch.optim.Adam(sfm_net.parameters(), lr=1e-1) # dataloader #data = dataloader.Data() #loader = data.batchloader #loader = dataloader.BIWILoader() loader = dataloader.SyntheticLoader() # mean shape and eigenvectors for 3dmm mu_lm = torch.from_numpy(loader.mu_lm).float() #mu_lm[:,2] = mu_lm[:,2] * -1 shape = mu_lm lm_eigenvec = torch.from_numpy(loader.lm_eigenvec).float() # main training loop for epoch in itertools.count(): for j, data in enumerate(loader): M = loader.M N = loader.N # get the input and gt values x_cam_gt = data['x_cam_gt'] shape_gt = data['x_w_gt'] fgt = data['f_gt'] x_img = data['x_img'] x_img_gt = data['x_img_gt'] x_img_pts = x_img.reshape((M, N, 2)).permute(0, 2, 1) one = torch.ones(M * N, 1) x_img_one = torch.cat([x_img, one], dim=1) x_cam_pt = x_cam_gt.permute(0, 2, 1).reshape(M * N, 3) x = x_img_one.permute(1, 0) # get initial values for betas and alphas of EPNP ptsI = x_img.reshape((M, N, 2)).permute(0, 2, 1) fvals = [] errors = [] for outerloop in itertools.count(): # calibration shape = shape.detach() for iter in itertools.count(): opt1.zero_grad() # focal length prediction f, _, _ = calib_net(x.unsqueeze(0)) f = f + 300 K = torch.zeros((3, 3)).float() K[0, 0] = f K[1, 1] = f K[2, 2] = 1 # RMSE between GT and predicted shape rmse = torch.norm(shape_gt - shape, dim=1).mean().detach() # error f error_f = torch.mean(torch.abs(f - fgt)) # differentiable PnP pose estimation km, c_w, scaled_betas, alphas = util.EPnP(ptsI, shape, K) Xc, R, T, mask = util.optimizeGN(km, c_w, scaled_betas, alphas, shape, ptsI, K) error2d = util.getReprojError2(ptsI, shape, R, T, K, show=False, loss='l1') loss = error2d.mean() + error_f if iter > 20 and prev_loss < loss: break else: prev_loss = loss loss.backward() opt1.step() print( f"iter: {iter} | error: {loss.item():.3f} | f/fgt: {f.item():.1f}/{fgt[0].item():.1f} | rmse: {rmse.item():.2f}" ) # sfm f = f.detach() for iter in itertools.count(): opt2.zero_grad() # shape prediction betas, _, _ = sfm_net(x.unsqueeze(0)) shape = torch.sum(betas * lm_eigenvec, 1) shape = shape.reshape(68, 3) + mu_lm K = torch.zeros((3, 3)).float() K[0, 0] = f K[1, 1] = f K[2, 2] = 1 # RMSE between GT and predicted shape rmse = torch.norm(shape_gt - shape, dim=1).mean().detach() # differentiable PnP pose estimation km, c_w, scaled_betas, alphas = util.EPnP(ptsI, shape, K) Xc, R, T, mask = util.optimizeGN(km, c_w, scaled_betas, alphas, shape, ptsI, K) error2d = util.getReprojError2(ptsI, shape, R, T, K, show=False, loss='l2') loss = error2d.mean() if iter > 20 and prev_loss < loss: break else: prev_loss = loss loss.backward() opt2.step() print( f"iter: {iter} | error: {loss.item():.3f} | f/fgt: {f.item():.1f}/{fgt[0].item():.1f} | rmse: {rmse.item():.2f}" ) if outerloop == 2: break # get errors reproj_errors2 = util.getReprojError2(ptsI, shape, R, T, K) reproj_errors3 = util.getReprojError3(x_cam_gt, shape, R, T) rel_errors = util.getRelReprojError3(x_cam_gt, shape, R, T) reproj_error = reproj_errors2.mean() reconstruction_error = reproj_errors3.mean() rel_error = rel_errors.mean() f_error = torch.abs(fgt - f) / fgt print( f"f/fgt: {f[0].item():.3f}/{fgt.item():.3f} | f_error_rel: {f_error.item():.4f} | rmse: {reconstruction_error.item():.4f} | rel rmse: {rel_error.item():.4f} | 2d error: {reproj_error.item():.4f}" ) #end for torch.save(sfm_net.state_dict(), os.path.join('model', 'sfm_' + modelout)) torch.save(calib_net.state_dict(), os.path.join('model', 'calib_' + modelout))
def test(modelin=args.model, outfile=args.out, feature_transform=args.feat_trans): # define model, dataloader, 3dmm eigenvectors, optimization method #if modelin != "": # model.load_state_dict(torch.load(modelin)) #model.eval() #model.cuda() # mean shape and eigenvectors for 3dmm M = 100 N = 68 data3dmm = dataloader.SyntheticLoader() mu_lm = torch.from_numpy(data3dmm.mu_lm).float() mu_lm[:, 2] = mu_lm[:, 2] * -1 shape = mu_lm.detach() lm_eigenvec = torch.from_numpy(data3dmm.lm_eigenvec).float() #optimizer = torch.optim.Adam(model.parameters(),lr=1e-2) # sample from f testing set allerror_2d = [] allerror_3d = [] allerror_rel3d = [] allerror_relf = [] all_f = [] all_depth = [] seterror_3d = [] seterror_rel3d = [] seterror_relf = [] seterror_2d = [] f_vals = [i * 100 for i in range(4, 21)] for f_test in f_vals: f_test = 1400 # create dataloader loader = dataloader.TestLoader(f_test) error_2d = [] error_3d = [] error_rel3d = [] error_relf = [] M = 100 N = 68 batch_size = 1 for j, data in enumerate(loader): # create a model and optimizer for it model = Model2(k=1, feature_transform=False) model.apply(util.init_weights) optimizer = torch.optim.Adam(model.parameters(), lr=1e-1) M = loader.M N = loader.N # load the data T_gt = data['T_gt'] x_cam_gt = data['x_cam_gt'] x_w_gt = data['x_w_gt'] fgt = data['f_gt'] x_img = data['x_img'] x_img_gt = data['x_img_gt'] x_img_pts = x_img.reshape((M, N, 2)).permute(0, 2, 1) one = torch.ones(M * N, 1) x_img_one = torch.cat([x_img, one], dim=1) x_cam_pt = x_cam_gt.permute(0, 2, 1).reshape(M * N, 3) all_depth.append(np.mean(T_gt[:, 2])) all_f.append(fgt.numpy()[0]) # create the input b = 10 x = x_img_one.reshape(M, N, 3).reshape(b, M // b, N, 3).reshape(b, M // b * N, 3) x = x.permute(0, 2, 1) ptsI = x_img.reshape((M, N, 2)).permute(0, 2, 1) # optimize using EPNP+GN fvals = [] errors = [] for iter in itertools.count(): optimizer.zero_grad() f, _, _ = model(x) #f = f + 1000 f = torch.nn.functional.leaky_relu(f) + 300 K = torch.zeros((b, 3, 3)).float() K[:, 0, 0] = f.squeeze() K[:, 1, 1] = f.squeeze() K[:, 2, 2] = 1 # differentiable pose estimation losses = [] for i in range(b): j = i + 1 km, c_w, scaled_betas, alphas = util.EPnP( ptsI[i:j * b], shape, K[i]) Xc, R, T, _ = util.optimizeGN(km, c_w, scaled_betas, alphas, shape, ptsI[i:j * b], K[i]) error2d = util.getReprojError2(ptsI[i:j * b], shape, R, T, K[i]).mean() losses.append(error2d) loss = torch.stack(losses).mean() loss.backward() optimizer.step() print( f"iter: {iter} | error: {loss.item():.3f} | f/fgt: {f.mean().item():.1f}/{fgt[0].item():.1f}" ) if iter == 100: break # get overall poses f = f.mean() K = torch.zeros((3, 3)).float() K[0, 0] = f K[1, 1] = f K[2, 2] = 1 km, c_w, scaled_betas, alphas = util.EPnP(ptsI, shape, K) Xc, R, T, _ = util.optimizeGN(km, c_w, scaled_betas, alphas, shape, ptsI, K) # get errors reproj_errors2 = util.getReprojError2(ptsI, shape, R, T, K) reproj_errors3 = util.getReprojError3(x_cam_gt, shape, R, T) rel_errors = util.getRelReprojError3(x_cam_gt, shape, R, T) reproj_error = reproj_errors2.mean() reconstruction_error = reproj_errors3.mean() rel_error = rel_errors.mean() f_error = torch.abs(fgt - f) / fgt allerror_3d.append(reproj_error.data.numpy()) allerror_2d.append(reconstruction_error.data.numpy()) allerror_rel3d.append(rel_error.data.numpy()) error_2d.append(reproj_error.cpu().data.item()) error_3d.append(reconstruction_error.cpu().data.item()) error_rel3d.append(rel_error.cpu().data.item()) error_relf.append(f_error.cpu().data.item()) print( f"f/sequence: {f_test}/{j} | f/fgt: {f.item():.3f}/{fgt.item():.3f} | f_error_rel: {f_error.item():.4f} | rmse: {reconstruction_error.item():.4f} | rel rmse: {rel_error.item():.4f} | 2d error: {reproj_error.item():.4f}" ) #end for avg_2d = np.mean(error_2d) avg_rel3d = np.mean(error_rel3d) avg_3d = np.mean(error_3d) avg_relf = np.mean(error_relf) seterror_2d.append(avg_2d) seterror_3d.append(avg_3d) seterror_rel3d.append(avg_rel3d) seterror_relf.append(avg_relf) #end for break all_f = np.stack(all_f).flatten() all_d = np.stack(all_depth).flatten() allerror_2d = np.stack(allerror_2d).flatten() allerror_3d = np.stack(allerror_3d).flatten() allerror_rel3d = np.stack(allerror_rel3d).flatten() matdata = {} matdata['fvals'] = np.array(f_vals) matdata['all_f'] = np.array(all_f) matdata['all_d'] = np.array(all_depth) matdata['error_2d'] = allerror_2d matdata['error_3d'] = allerror_3d matdata['error_rel3d'] = allerror_rel3d matdata['seterror_2d'] = np.array(seterror_2d) matdata['seterror_3d'] = np.array(seterror_3d) matdata['seterror_rel3d'] = np.array(seterror_rel3d) matdata['seterror_relf'] = np.array(seterror_relf) scipy.io.savemat(outfile, matdata) print(f"MEAN seterror_2d: {np.mean(seterror_2d)}") print(f"MEAN seterror_3d: {np.mean(seterror_3d)}") print(f"MEAN seterror_rel3d: {np.mean(seterror_rel3d)}") print(f"MEAN seterror_relf: {np.mean(seterror_relf)}")
def test(modelin=args.model, outfile=args.out, feature_transform=args.feat_trans): # define model, dataloader, 3dmm eigenvectors, optimization method #if modelin != "": # model.load_state_dict(torch.load(modelin)) #model.eval() #model.cuda() # mean shape and eigenvectors for 3dmm M = 100 N = 68 data3dmm = dataloader.SyntheticLoader() mu_lm = torch.from_numpy(data3dmm.mu_lm).float() mu_lm[:, 2] = mu_lm[:, 2] * -1 shape = mu_lm.detach() lm_eigenvec = torch.from_numpy(data3dmm.lm_eigenvec).float() #optimizer = torch.optim.Adam(model.parameters(),lr=1e-2) # sample from f testing set allerror_2d = [] allerror_3d = [] allerror_rel3d = [] allerror_relf = [] all_f = [] all_depth = [] seterror_3d = [] seterror_rel3d = [] seterror_relf = [] seterror_2d = [] f_vals = [i * 100 for i in range(4, 21)] np.random.seed(0) for f_test in f_vals: f_test = 1200 # create dataloader loader = dataloader.TestLoader(f_test) error_2d = [] error_3d = [] error_rel3d = [] error_relf = [] M = 100 N = 68 batch_size = 1 for j, data in enumerate(loader): # create a model and optimizer for it #model2 = Model1(k=199,feature_transform=False) #model2.apply(util.init_weights) model = Model1(k=1, feature_transform=False) model.apply(util.init_weights) optimizer = torch.optim.Adam(model.parameters(), lr=2e-1) #data = loader[67] x_cam_gt = data['x_cam_gt'] shape = data['x_w_gt'] fgt = data['f_gt'] x_img = data['x_img'] x_img_gt = data['x_img_gt'] T_gt = data['T_gt'] all_depth.append(np.mean(T_gt[:, 2])) all_f.append(fgt.numpy()[0]) x_img_pts = x_img.reshape((M, N, 2)).permute(0, 2, 1) one = torch.ones(M * N, 1) x_img_one = torch.cat([x_img, one], dim=1) x_cam_pt = x_cam_gt.permute(0, 2, 1).reshape(M * N, 3) x = x_img_one.permute(1, 0) ptsI = x_img.reshape((M, N, 2)).permute(0, 2, 1) for iter in itertools.count(): optimizer.zero_grad() #betas,_,_ = model2(x.unsqueeze(0)) #shape = torch.sum(betas * lm_eigenvec,1) #shape = shape.reshape(68,3) + mu_lm f, _, _ = model(x.unsqueeze(0)) #f = f + 300 #f = (torch.nn.functional.tanh(f)+1)*850 + 300 f = f + 300 #f = torch.nn.functional.sigmoid(f) K = torch.zeros((3, 3)).float() K[0, 0] = f K[1, 1] = f K[2, 2] = 1 # differentiable pose estimation km, c_w, scaled_betas, alphas = util.EPnP(ptsI, shape, K) Xc, R, T, mask = util.optimizeGN(km, c_w, scaled_betas, alphas, shape, ptsI, K) error2d = util.getReprojError2(ptsI, shape, R, T, K, show=False, loss='l1') loss = error2d.mean() loss.backward() if torch.any(model.fc2.weight.grad != model.fc2.weight.grad): print("oh oh something broke") break optimizer.step() print( f"iter: {iter} | error: {loss.item():.3f} | f/fgt: {f.item():.1f}/{fgt[0].item():.1f}" ) if iter == 200: break # get errors reproj_errors2 = util.getReprojError2(ptsI, shape, R, T, K) reproj_errors3 = util.getReprojError3(x_cam_gt, shape, R, T) rel_errors = util.getRelReprojError3(x_cam_gt, shape, R, T) reproj_error = reproj_errors2.mean() reconstruction_error = reproj_errors3.mean() rel_error = rel_errors.mean() f_error = torch.abs(fgt - f) / fgt allerror_3d.append(reproj_error.data.numpy()) allerror_2d.append(reconstruction_error.data.numpy()) allerror_rel3d.append(rel_error.data.numpy()) error_2d.append(reproj_error.cpu().data.item()) error_3d.append(reconstruction_error.cpu().data.item()) error_rel3d.append(rel_error.cpu().data.item()) error_relf.append(f_error.cpu().data.item()) print( f"f/sequence: {f_test}/{j} | f/fgt: {f[0].item():.3f}/{fgt.item():.3f} | f_error_rel: {f_error.item():.4f} | rmse: {reconstruction_error.item():.4f} | rel rmse: {rel_error.item():.4f} | 2d error: {reproj_error.item():.4f}" ) #end for avg_2d = np.mean(error_2d) avg_rel3d = np.mean(error_rel3d) avg_3d = np.mean(error_3d) avg_relf = np.mean(error_relf) seterror_2d.append(avg_2d) seterror_3d.append(avg_3d) seterror_rel3d.append(avg_rel3d) seterror_relf.append(avg_relf) #end for break all_f = np.stack(all_f).flatten() all_d = np.stack(all_depth).flatten() allerror_2d = np.stack(allerror_2d).flatten() allerror_3d = np.stack(allerror_3d).flatten() allerror_rel3d = np.stack(allerror_rel3d).flatten() matdata = {} matdata['fvals'] = np.array(f_vals) matdata['all_f'] = np.array(all_f) matdata['all_d'] = np.array(all_depth) matdata['error_2d'] = allerror_2d matdata['error_3d'] = allerror_3d matdata['error_rel3d'] = allerror_rel3d matdata['seterror_2d'] = np.array(seterror_2d) matdata['seterror_3d'] = np.array(seterror_3d) matdata['seterror_rel3d'] = np.array(seterror_rel3d) matdata['seterror_relf'] = np.array(seterror_relf) scipy.io.savemat(outfile, matdata) print(f"MEAN seterror_2d: {np.mean(seterror_2d)}") print(f"MEAN seterror_3d: {np.mean(seterror_3d)}") print(f"MEAN seterror_rel3d: {np.mean(seterror_rel3d)}") print(f"MEAN seterror_relf: {np.mean(seterror_relf)}")
def testBIWI(model,modelin=args.model,outfile=args.out,feature_transform=args.feat_trans): if modelin != "": model.load_state_dict(torch.load(modelin)) model.cuda() # load 3dmm data data3dmm = dataloader.SyntheticLoader() mu_lm = torch.from_numpy(data3dmm.mu_lm).float().cuda() lm_eigenvec = torch.from_numpy(data3dmm.lm_eigenvec).float().cuda() loader = dataloader.BIWILoader() seterror_3d = [] seterror_rel3d = [] seterror_relf = [] seterror_2d = [] for sub in range(len(loader)): batch = loader[sub] x_cam_gt = batch['x_cam_gt'].cuda() x_w_gt = batch['x_w_gt'].cuda() f_gt = batch['f_gt'].cuda() x_img = batch['x_img'].cuda() x_img_gt = batch['x_img_gt'].cuda() M = x_img_gt.shape[0] one = torch.ones(M,1,68).cuda() x_img_one = torch.cat([x_img,one],dim=1) # run the model out, trans, transfeat = model(x_img_one) alphas = out[:,:199].mean(0) f = torch.relu(out[:,199]).mean() K = torch.zeros((3,3)).float().cuda() K[0,0] = f; K[1,1] = f; K[2,2] = 1; K[0,2] = 320; K[1,2] = 240; # apply 3DMM model from predicted parameters alpha_matrix = torch.diag(alphas) shape_cov = torch.mm(lm_eigenvec,alpha_matrix) s = shape_cov.sum(1).view(68,3) shape = (mu_lm + s) shae[:,2] = shape[:,2]*-1 # run epnp algorithm # get control points c_w = util.getControlPoints(shape) # solve alphas alphas = util.solveAlphas(shape,c_w) # setup M px = 320; py = 240; Matrix = util.setupM(alphas,x_img.permute(0,2,1),px,py,f) # get eigenvectors of M for each view u,d,v = torch.svd(Matrix) #solve N=1 c_c_n1 = v[:,:,-1].reshape((M,4,3)).permute(0,2,1) _ , x_c_n1, _ = util.scaleControlPoints(c_c_n1,c_w[:3,:],alphas,shape) Rn1,Tn1 = util.getExtrinsics(x_c_n1,shape) reproj_error2_n1 = util.getReprojError2(x_img,shape,Rn1,Tn1,K) reproj_error3_n1 = util.getReprojError3(x_cam_gt,shape,Rn1,Tn1) rel_error_n1 = util.getRelReprojError3(x_cam_gt,shape,Rn1,Tn1) # solve N=2 # get distance contraints d12,d13,d14,d23,d24,d34 = util.getDistances(c_w) distances = torch.stack([d12,d13,d14,d23,d24,d34])**2 beta_n2 = util.getBetaN2(v[:,:,-2:],distances) c_c_n2 = util.getControlPointsN2(v[:,:,-2:],beta_n2) _,x_c_n2,_ = util.scaleControlPoints(c_c_n2,c_w[:3,:],alphas,shape) Rn2,Tn2 = util.getExtrinsics(x_c_n2,shape) reproj_error2_n2 = util.getReprojError2(x_img,shape,Rn2,Tn2,K) reproj_error3_n2 = util.getReprojError3(x_cam_gt,shape,Rn2,Tn2) rel_error_n2 = util.getRelReprojError3(x_cam_gt,shape,Rn1,Tn1) mask = reproj_error2_n1 < reproj_error2_n2 reproj_errors = torch.cat((reproj_error2_n1[mask],reproj_error2_n2[~mask])) rmse_errors = torch.cat((reproj_error3_n1[mask],reproj_error3_n2[~mask])) rel_errors = torch.cat((rel_error_n2[~mask],rel_error_n1[mask])) # errors reproj_error = torch.mean(reproj_errors) reconstruction_error = torch.mean(rmse_errors) rel_error = torch.mean(rel_errors) f_error = torch.abs(f_gt - f) / f_gt seterror_2d.append(reproj_error.cpu().data.item()) seterror_3d.append(reconstruction_error.cpu().data.item()) seterror_rel3d.append(rel_error.cpu().data.item()) seterror_relf.append(f_error.cpu().data.item()) print(f"fgt: {f_gt.mean().item():.3f} | f_error_rel: {f_error.item():.4f} | rmse: {reconstruction_error.item():.4f} | rel rmse: {rel_error.item():.4f} | 2d error: {reproj_error.item():.4f}") #end for matdata = {} matdata['seterror_2d'] = np.array(seterror_2d) matdata['seterror_3d'] = np.array(seterror_3d) matdata['seterror_rel3d'] = np.array(seterror_rel3d) matdata['seterror_relf'] = np.array(seterror_relf) scipy.io.savemat(outfile,matdata) print(f"MEAN seterror_2d: {np.mean(seterror_2d)}") print(f"MEAN seterror_3d: {np.mean(seterror_3d)}") print(f"MEAN seterror_rel3d: {np.mean(seterror_rel3d)}") print(f"MEAN seterror_relf: {np.mean(seterror_relf)}")
def test(model, modelin=args.model,outfile=args.out,feature_transform=args.feat_trans): # define model, dataloader, 3dmm eigenvectors, optimization method if modelin != "": model.load_state_dict(torch.load(modelin)) model.cuda() # mean shape and eigenvectors for 3dmm M = 100 data3dmm = dataloader.SyntheticLoader() mu_lm = torch.from_numpy(data3dmm.mu_lm).float().cuda() lm_eigenvec = torch.from_numpy(data3dmm.lm_eigenvec).float().cuda() # sample from f testing set allerror_2d = [] allerror_3d = [] allerror_rel3d = [] allerror_relf = [] allerror_f = [] allerror_d = [] seterror_3d = [] seterror_rel3d = [] seterror_relf = [] seterror_2d = [] f_vals = [i*100 for i in range(4,21)] for f_test in f_vals: # create dataloader data = dataloader.TestLoader(f_test) error_2d = [] error_3d = [] error_rel3d = [] error_relf = [] for k in range(len(data)): batch = data[k] x_cam_gt = batch['x_cam_gt'].cuda() x_w_gt = batch['x_w_gt'].cuda() f_gt = batch['f_gt'].cuda() x_img = batch['x_img'].cuda() x_img_gt = batch['x_img_gt'].cuda() T_gt = batch['T_gt'] allerror_d.append(T_gt[:,2]) one = torch.ones(M,1,68).cuda() x_img_one = torch.cat([x_img,one],dim=1) # run the model out, trans, transfeat = model(x_img_one) alphas = out[:,:199].mean(0) f = torch.relu(out[:,199]).mean() K = torch.zeros((3,3)).float().cuda() for f = np.linspace(-200,200,100): K[0,0] = f; K[1,1] = f; K[2,2] = 1; K[0,2] = 320; K[1,2] = 240; # apply 3DMM model from predicted parameters alpha_matrix = torch.diag(alphas) shape_cov = torch.mm(lm_eigenvec,alpha_matrix) s = shape_cov.sum(1).view(68,3) #shape = (mu_lm + s) shape = mu_lm shape[:,2] = shape[:,2]*-1 # run epnp algorithm # get control points c_w = util.getControlPoints(shape) # solve alphas alphas = util.solveAlphas(shape,c_w) # setup M px = 320; py = 240; Matrix = util.setupM(alphas,x_img.permute(0,2,1),px,py,f) # get eigenvectors of M for each view u,d,v = torch.svd(Matrix) #solve N=1 c_c_n1 = v[:,:,-1].reshape((100,4,3)).permute(0,2,1) _ , x_c_n1, _ = util.scaleControlPoints(c_c_n1,c_w[:3,:],alphas,shape) Rn1,Tn1 = util.getExtrinsics(x_c_n1,shape) reproj_error2_n1 = util.getReprojError2(x_img,shape,Rn1,Tn1,K) reproj_error3_n1 = util.getReprojError3(x_cam_gt,shape,Rn1,Tn1) rel_error_n1 = util.getRelReprojError3(x_cam_gt,shape,Rn1,Tn1) # solve N=2 # get distance contraints d12,d13,d14,d23,d24,d34 = util.getDistances(c_w) distances = torch.stack([d12,d13,d14,d23,d24,d34])**2 beta_n2 = util.getBetaN2(v[:,:,-2:],distances) c_c_n2 = util.getControlPointsN2(v[:,:,-2:],beta_n2) _,x_c_n2,_ = util.scaleControlPoints(c_c_n2,c_w[:3,:],alphas,shape) Rn2,Tn2 = util.getExtrinsics(x_c_n2,shape) reproj_error2_n2 = util.getReprojError2(x_img,shape,Rn2,Tn2,K) reproj_error3_n2 = util.getReprojError3(x_cam_gt,shape,Rn2,Tn2) rel_error_n2 = util.getRelReprojError3(x_cam_gt,shape,Rn1,Tn1) mask = reproj_error2_n1 < reproj_error2_n2 reproj_errors = torch.cat((reproj_error2_n1[mask],reproj_error2_n2[~mask])) rmse_errors = torch.cat((reproj_error3_n1[mask],reproj_error3_n2[~mask])) rel_errors = torch.cat((rel_error_n2[~mask],rel_error_n1[mask])) print(rel_errors.mean()) quit() # errors allerror_3d.append(reproj_errors.cpu().data.numpy()) allerror_2d.append(rmse_errors.cpu().data.numpy()) allerror_rel3d.append(rel_errors.cpu().data.numpy()) reproj_error = torch.mean(reproj_errors) reconstruction_error = torch.mean(rmse_errors) rel_error = torch.mean(rel_errors) f_error = torch.abs(f_gt - f) / f_gt error_2d.append(reproj_error.cpu().data.item()) error_3d.append(reconstruction_error.cpu().data.item()) error_rel3d.append(rel_error.cpu().data.item()) error_relf.append(f_error.cpu().data.item()) print(f"f/sequence: {f_test}/{k} | f_error_rel: {f_error.item():.4f} | rmse: {reconstruction_error.item():.4f} | rel rmse: {rel_error.item():.4f} | 2d error: {reproj_error.item():.4f}") #end for avg_2d = np.mean(error_2d) avg_rel3d = np.mean(error_rel3d) avg_3d = np.mean(error_3d) avg_relf = np.mean(error_relf) seterror_2d.append(avg_2d) seterror_3d.append(avg_3d) seterror_rel3d.append(avg_rel3d) seterror_relf.append(avg_relf)
def test(modelin=args.model, outfile=args.out, feature_transform=args.feat_trans): # define model, dataloader, 3dmm eigenvectors, optimization method #if modelin != "": # model.load_state_dict(torch.load(modelin)) #model.eval() #model.cuda() # mean shape and eigenvectors for 3dmm M = 100 N = 68 data3dmm = dataloader.SyntheticLoader() mu_lm = torch.from_numpy(data3dmm.mu_lm).float().detach() mu_lm[:, 2] = mu_lm[:, 2] * -1 lm_eigenvec = torch.from_numpy(data3dmm.lm_eigenvec).float() #optimizer = torch.optim.Adam(model.parameters(),lr=1e-2) # sample from f testing set allerror_2d = [] allerror_3d = [] allerror_rel3d = [] allerror_relf = [] all_f = [] all_depth = [] seterror_3d = [] seterror_rel3d = [] seterror_relf = [] seterror_2d = [] f_vals = [400 + i * 100 for i in range(4)] # set random seed for reproducibility of test set np.random.seed(0) torch.manual_seed(0) for f_test in f_vals: f_test = 1400 # create dataloader loader = dataloader.TestLoader(f_test) error_2d = [] error_3d = [] error_rel3d = [] error_relf = [] M = 100 N = 68 batch_size = 1 for j, data in enumerate(loader): # create a model and optimizer for it model2 = Model1(k=199, feature_transform=False) model2.apply(util.init_weights) model = Model1(k=1, feature_transform=False) model.apply(util.init_weights) opt1 = torch.optim.Adam(model2.parameters(), lr=1e-1) opt2 = torch.optim.Adam(model.parameters(), lr=1e-1) # load the data x_cam_gt = data['x_cam_gt'] shape_gt = data['x_w_gt'] fgt = data['f_gt'] x_img = data['x_img'] x_img_gt = data['x_img_gt'] T_gt = data['T_gt'] all_depth.append(np.mean(T_gt[:, 2])) all_f.append(fgt.numpy()[0]) x_img_pts = x_img.reshape((M, N, 2)).permute(0, 2, 1) one = torch.ones(M * N, 1) x_img_one = torch.cat([x_img, one], dim=1) x_cam_pt = x_cam_gt.permute(0, 2, 1).reshape(M * N, 3) x = x_img_one.permute(1, 0) ptsI = x_img.reshape((M, N, 2)).permute(0, 2, 1) # multi objective optimization shape = mu_lm for outerloop in itertools.count(): # calibration alg3 shape = shape.detach() for iter2 in itertools.count(): opt2.zero_grad() # focal length prediction curf, _, _ = model(x.unsqueeze(0)) curf = curf + 300 K = torch.zeros((3, 3)).float() K[0, 0] = curf K[1, 1] = curf K[2, 2] = 1 # RMSE between GT and predicted shape rmse = torch.norm(shape_gt - shape, dim=1).mean().detach() # differentiable PnP pose estimation km, c_w, scaled_betas, alphas = util.EPnP(ptsI, shape, K) Xc, R, T, mask = util.optimizeGN(km, c_w, scaled_betas, alphas, shape, ptsI, K) error2d = util.getReprojError2(ptsI, shape, R, T, K, show=False, loss='l2') loss = error2d.mean() if iter2 > 20 and prev_loss < loss: break else: prev_loss = loss loss.backward() opt2.step() print( f"iter: {iter2} | error: {loss.item():.3f} | f/fgt: {curf.item():.1f}/{fgt[0].item():.1f} | rmse: {rmse.item():.2f}" ) # sfm alg2 curf = curf.detach() for iter1 in itertools.count(): opt1.zero_grad() # shape prediction betas, _, _ = model2(x.unsqueeze(0)) shape = torch.sum(betas * lm_eigenvec, 1) shape = shape.reshape(68, 3) + mu_lm K = torch.zeros((3, 3)).float() K[0, 0] = curf K[1, 1] = curf K[2, 2] = 1 # RMSE between GT and predicted shape rmse = torch.norm(shape_gt - shape, dim=1).mean().detach() # differentiable PnP pose estimation km, c_w, scaled_betas, alphas = util.EPnP(ptsI, shape, K) Xc, R, T, mask = util.optimizeGN(km, c_w, scaled_betas, alphas, shape, ptsI, K) error2d = util.getReprojError2(ptsI, shape, R, T, K, show=False, loss='l2') loss = error2d.mean() if iter1 > 20 and prev_loss < loss: break else: prev_loss = loss loss.backward() opt1.step() print( f"iter: {iter1} | error: {loss.item():.3f} | f/fgt: {curf.item():.1f}/{fgt[0].item():.1f} | rmse: {rmse.item():.2f}" ) # closing condition for outerloop on dual objective if outerloop == 4: break f = curf # get errors reproj_errors2 = util.getReprojError2(ptsI, shape, R, T, K) reproj_errors3 = util.getReprojError3(x_cam_gt, shape, R, T) rel_errors = util.getRelReprojError3(x_cam_gt, shape, R, T) reproj_error = reproj_errors2.mean() reconstruction_error = reproj_errors3.mean() rel_error = rel_errors.mean() f_error = torch.abs(fgt - f) / fgt allerror_3d.append(reproj_error.data.numpy()) allerror_2d.append(reconstruction_error.data.numpy()) allerror_rel3d.append(rel_error.data.numpy()) error_2d.append(reproj_error.cpu().data.item()) error_3d.append(reconstruction_error.cpu().data.item()) error_rel3d.append(rel_error.cpu().data.item()) error_relf.append(f_error.cpu().data.item()) print( f"f/sequence: {f_test}/{j} | f/fgt: {f[0].item():.3f}/{fgt.item():.3f} | f_error_rel: {f_error.item():.4f} | rmse: {reconstruction_error.item():.4f} | rel rmse: {rel_error.item():.4f} | 2d error: {reproj_error.item():.4f}" ) #end for avg_2d = np.mean(error_2d) avg_rel3d = np.mean(error_rel3d) avg_3d = np.mean(error_3d) avg_relf = np.mean(error_relf) seterror_2d.append(avg_2d) seterror_3d.append(avg_3d) seterror_rel3d.append(avg_rel3d) seterror_relf.append(avg_relf) #end for break all_f = np.stack(all_f).flatten() all_d = np.stack(all_depth).flatten() allerror_2d = np.stack(allerror_2d).flatten() allerror_3d = np.stack(allerror_3d).flatten() allerror_rel3d = np.stack(allerror_rel3d).flatten() matdata = {} matdata['fvals'] = np.array(f_vals) matdata['all_f'] = np.array(all_f) matdata['all_d'] = np.array(all_depth) matdata['error_2d'] = allerror_2d matdata['error_3d'] = allerror_3d matdata['error_rel3d'] = allerror_rel3d matdata['seterror_2d'] = np.array(seterror_2d) matdata['seterror_3d'] = np.array(seterror_3d) matdata['seterror_rel3d'] = np.array(seterror_rel3d) matdata['seterror_relf'] = np.array(seterror_relf) scipy.io.savemat(outfile, matdata) print(f"MEAN seterror_2d: {np.mean(seterror_2d)}") print(f"MEAN seterror_3d: {np.mean(seterror_3d)}") print(f"MEAN seterror_rel3d: {np.mean(seterror_rel3d)}") print(f"MEAN seterror_relf: {np.mean(seterror_relf)}")