Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 3
0
 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
Esempio n. 4
0
 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
Esempio n. 5
0
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