def test(model, sample_num, input_mode, sample_method="axisAngle"): #print ("########TEST##########") with torch.no_grad(): model.eval() model.cuda() gt_rotation_matrix = [] if (sample_method == "axisAngle"): gt_rotation_matrix = tools.get_sampled_rotation_matrices_by_axisAngle( sample_num) #batch*3*3 elif (sample_method == "quaternion"): gt_rotation_matrix = tools.get_sampled_rotation_matrices_by_quat( sample_num) #batch*3*3 gt_poses = tools.compute_pose_from_rotation_matrix( model.T_pose, gt_rotation_matrix) #batch*3*3 if (input_mode == "pose"): out_rotation_matrix, out_poses = model(gt_poses) elif (input_mode == "r_matrix"): out_rotation_matrix, out_poses = model(gt_rotation_matrix) #print (out_rotation_matrix[0]) #print (out_poses[0]) #pose_errors = torch.pow(gt_poses-out_poses, 2).sum(2).mean(1) #batch #pose_error_order = np.argsort(np.array(pose_errors.data.tolist())) geodesic_errors = tools.compute_geodesic_distance_from_two_matrices( out_rotation_matrix, gt_rotation_matrix) geodesic_errors = geodesic_errors / np.pi * 180 geodesic_errors = np.array(geodesic_errors.data.tolist()) #geodesic_error_order = np.argsort(np.array(geodesic_errors.data.tolist())) return geodesic_errors
def test(pc_fn_lst, weight_fn, out_rotation_mode, regress_t, rotation_sample_num ):#, save_out_pc_folder): torch.cuda.set_device(2) print ("####Initiate model") model = Model_pointnet.Model(out_rotation_mode=out_rotation_mode, regress_t=regress_t) print ("Load "+ weight_fn) model.load_state_dict(torch.load( weight_fn)) model.cuda() model.eval() geodesic_errors_lst = np.array([]) #rmat_errors_lst = np.array([]) t_errors_lst = np.array([]) num_big_geodesic_error =0 for pc_fn in pc_fn_lst: batch=rotation_sample_num pc1_np = np.array(pts_loader.load(pc_fn)) point_num = int(pc1_np.shape[0]/2) pc1 = torch.autograd.Variable(torch.FloatTensor(pc1_np[0:point_num]).cuda()) #num*3 pc1 = pc1.view(1, point_num,3).expand(batch,point_num,3).contiguous() #batch*p_num*3 gt_rmat = tools.get_sampled_rotation_matrices_by_axisAngle(batch)#batch*3*3 gt_rmats = gt_rmat.contiguous().view(batch,1,3,3).expand(batch, point_num, 3,3 ).contiguous().view(-1,3,3) pc2 = torch.bmm(gt_rmats, pc1.view(-1,3,1))#(batch*point_num)*3*1 pc2 = pc2.view(batch, point_num, 3) ##batch*p_num*3 if(model.regress_t == True): gt_translation = torch.autograd.Variable(torch.FloatTensor(np.random.randn(batch,3)).cuda())/10.0 pc2 = pc2 + gt_translation.view(batch,1,3).expand(batch, point_num, 3) ###network forward######## out_rmat, out_translation, out_pc2 = model(pc1, pc2)#batch*3*3 else: out_rmat, out_pc2 = model(pc1,pc2) geodesic_errors = np.array( tools.compute_geodesic_distance_from_two_matrices(gt_rmat, out_rmat).data.tolist()) #batch geodesic_errors = geodesic_errors/np.pi*180 geodesic_errors_lst = np.append(geodesic_errors_lst, geodesic_errors) #rmat_errors = np.array(torch.pow(out_rmat - gt_rmat, 2).mean(2).mean(1).tolist()) #batch if(model.regress_t==True): t_errors = np.array(torch.sqrt( torch.pow(gt_translation - out_translation, 2).sum(1) ).data.tolist()) t_errors_lst=np.append(t_errors_lst, t_errors) return geodesic_errors_lst, t_errors_lst
def compute_geodesic_loss(self, gt_r_matrix, out_r_matrix): theta = tools.compute_geodesic_distance_from_two_matrices( gt_r_matrix, out_r_matrix) error = theta.mean() return error
def loss_geodesic(self, gt_rmat, predict_rmat): theta = tools.compute_geodesic_distance_from_two_matrices( gt_rmat, predict_rmat) error = theta.mean() return error
def test(model, sample_num, input_mode, histogram_bins_num, angle_group_num): print("########TEST##########") with torch.no_grad(): model.eval() gt_rotation_matrix = tools.get_sampled_rotation_matrices_by_axisAngle( sample_num) #batch*3*3 gt_poses = tools.compute_pose_from_rotation_matrix( model.T_pose, gt_rotation_matrix) #batch*3*3 if (input_mode == "pose"): out_rotation_matrix, out_poses = model(gt_poses) elif (input_mode == "r_matrix"): out_rotation_matrix, out_poses = model(gt_rotation_matrix) #print (out_rotation_matrix[0]) #print (out_poses[0]) pose_errors = torch.pow(gt_poses - out_poses, 2).sum(2).mean(1) #batch pose_error_order = np.argsort(np.array(pose_errors.data.tolist())) geodesic_errors = tools.compute_geodesic_distance_from_two_matrices( out_rotation_matrix, gt_rotation_matrix) geodesic_error_order = np.argsort( np.array(geodesic_errors.data.tolist())) print("avg pose error: " + str(pose_errors.mean().item())) print("max pose error: " + str(pose_errors.max().item())) print("avg geodesic error: " + str(geodesic_errors.mean().item())) print("max geodesic error: " + str(geodesic_errors.max().item())) ####compute the rotation angles thetas = tools.compute_angle_from_r_matrices(gt_rotation_matrix) ####print angles with worst errors###################### str_angles = "(" + str(pose_errors[pose_error_order[ sample_num - 20]].item()) + ", " + str( pose_errors[pose_error_order[sample_num - 1]].item()) + ")\n" for i in range(sample_num - 20, sample_num): str_angles = str_angles + str( int(thetas[pose_error_order[i]].item() / np.pi * 180)) + " " print("angles of max pose errors: " + str_angles) str_angles = "(" + str(geodesic_errors[geodesic_error_order[ sample_num - 20]].item()) + " " + str( geodesic_errors[geodesic_error_order[sample_num - 1]].item()) + ")\n" for i in range(sample_num - 20, sample_num): str_angles = str_angles + str( int(thetas[geodesic_error_order[i]].item() / np.pi * 180)) + " " print("angles of max pose errors: " + str_angles) ###visualize the error histogram###################### ####group errors by theta group_num = angle_group_num #angle_bins =[ [0,np.pi/32],[15.5*np.pi/32, 16.5*np.pi/32], [31*np.pi/32, np.pi]] #group_num=3 angle_bins = [[0, np.pi]] group_num = 1 pose_error_lst = [] geodesic_error_lst = [] for [min_angle, max_angle] in angle_bins: pose_error = [] geodesic_error = [] for j in range(sample_num): if (thetas[j] < max_angle) and (thetas[j] >= min_angle): pose_error = pose_error + [pose_errors[j].item()] geodesic_error = geodesic_error + [ geodesic_errors[j].item() ] pose_error_lst = pose_error_lst + [ np.array(pose_error).astype(float) ] geodesic_error_lst = geodesic_error_lst + [ np.array(geodesic_error).astype(float) ] for i in range(group_num): pose_error = pose_error_lst[i] print("group" + str(i) + " sample num:" + str(pose_error.shape[0])) min_angle = int(angle_bins[i][0] / np.pi * 180) max_angle = int(angle_bins[i][1] / np.pi * 180) plt.hist([pose_error], bins=histogram_bins_num, log=True, alpha=0.5, label=str(min_angle) + "_" + str(max_angle)) plt.ylabel('Pose_errors') plt.legend(loc='upper right') plt.show() plt.clf() for i in range(group_num): geodesic_error = geodesic_error_lst[i] print("group" + str(i) + " sample num:" + str(geodesic_error.shape[0])) min_angle = int(angle_bins[i][0] / np.pi * 180) max_angle = int(angle_bins[i][1] / np.pi * 180) plt.hist([geodesic_error], bins=histogram_bins_num, log=True, alpha=0.5, label=str(min_angle) + "-" + str(max_angle)) plt.ylabel('Geodesic_errors') plt.legend(loc='upper right') plt.show() plt.clf() model.train()
def test_all_dances(read_weight_path, out_rotation_mode, dance_lst, out_bvh_folder, error_threshold, loss_rmat_only_on_hip=1): torch.cuda.set_device(2) print("####Initiate model AE") model = Model.Model(joint_num=57, out_rotation_mode=out_rotation_mode) print("Load " + read_weight_path) model.load_state_dict(torch.load(read_weight_path)) model.cuda() model.initialize_skeleton_features("../data/standard.bvh") model.eval() error_lst = np.array([]) rotation_error_lst = np.array([]) frame_sum = 0 for dance_raw, framerate, dance_fn in dance_lst: for b in range(1): dance = get_augmented_dance_seq_from_quat_bvh(dance_raw) seq_len = dance.shape[0] frame_sum = seq_len + frame_sum gt_hip_poses = dance[:, 0:3] #seq_len*3 gt_quat = dance[:, 3:dance.shape[1]].contiguous().view( -1, 4) #(seq_len*joint_num*3) gt_rotation_matrices = tools.compute_rotation_matrix_from_quaternion( gt_quat) #(seq_len*joint_num)*3*3 gt_rotation_matrices = tools.get_44_rotation_matrix_from_33_rotation_matrix( gt_rotation_matrices).view(seq_len, -1, 4, 4) #seq_len*joint_num*4*4 gt_poses = model.rotation_seq2_pose_seq( gt_rotation_matrices) #seq_len*joint_num*3 hip's pose is fixed ###network forward######## predict_poses, predict_rotation_matrices = model( gt_poses) #seq_len*joint_num*3 pose_errors = torch.sqrt( torch.pow(predict_poses - gt_poses, 2).sum(2)).mean(1) #seq_len error_lst = np.append(error_lst, np.array(pose_errors.data.tolist())) if (loss_rmat_only_on_hip == 1): rotation_errors = tools.compute_geodesic_distance_from_two_matrices( predict_rotation_matrices[:, 0], gt_rotation_matrices[:, 0]) else: rotation_errors = tools.compute_geodesic_distance_from_two_matrices( predict_rotation_matrices.view(-1, 4, 4), gt_rotation_matrices.view(-1, 4, 4)).view(seq_len, Joint_num).mean(1) rotation_errors = rotation_errors * 180 / np.pi rotation_error_lst = np.append( rotation_error_lst, np.array(rotation_errors.data.tolist())) ###write the predicted motion with big error #if(rotation_errors.max()>error_threshold): if (pose_errors.max() > error_threshold): #worst_frame_id = rotation_errors.argmax().item() worst_frame_id = pose_errors.argmax().item() start_id = max(0, worst_frame_id - 20) end_id = min(gt_hip_poses.shape[0], worst_frame_id + 20) gt_hip_poses[:, 0] = gt_hip_poses[:, 0] * 0 gt_hip_poses[:, 2] = gt_hip_poses[:, 2] * 0 head, tail = ntpath.split(dance_fn) head2, tail2 = ntpath.split(dance_fn[0:len(dance_fn) - len(tail) - 1]) out_bvh_folder2 = out_bvh_folder + tail2 + "/" if not os.path.exists(out_bvh_folder2): os.makedirs(out_bvh_folder2) out_fn = out_bvh_folder2 + tail[0:len(tail) - 4] print(tail2 + "/" + tail[0:len(tail) - 4]) print("worst frame id: " + str(worst_frame_id)) print("error: " + str(pose_errors[start_id:end_id].max().item())) #print ("worst frame id: "+str(rotation_errors[start_id:end_id].argmax().item())) #print ("error: "+str(rotation_errors[start_id:end_id].max().item())) save_network_output_quat_data_to_bvh( gt_hip_poses[start_id:end_id], predict_rotation_matrices[start_id:end_id], out_fn + "_out.bvh") save_network_output_quat_data_to_bvh( gt_hip_poses[start_id:end_id], gt_rotation_matrices[start_id:end_id], out_fn + "_gt.bvh") avg_error = error_lst.mean() max_error = error_lst.max() print("avg error: " + str(avg_error)) print("max error: " + str(max_error)) avg_rotation_error = rotation_error_lst.mean() max_rotation_error = rotation_error_lst.max() print("avg rotation error: " + str(avg_rotation_error)) print("max rotation error: " + str(max_rotation_error)) return error_lst, rotation_error_lst