示例#1
0
def compute_colmap_stats(res_dict, deprecated_images, cfg):
    '''Retrieve stats from Colmap and add them to the dictionary.'''

    track_length_list = []
    num_cameras_list = []
    is_fail_list = []
    num_3d_pts_list = []

    # For all the bags
    cfg_bag = deepcopy(cfg)
    for bag_id in range(get_num_in_bag(cfg_bag)):
        cfg_bag.bag_id = bag_id

        # Skip if bag contain deprecated images
        if not valid_bag(cfg_bag, deprecated_images):
            continue

        # Check if colmap output path exists. We compute stats for track
        # length, num_cameras, num 3d points, only when colmap succeeds
        if not os.path.exists(get_colmap_output_path(cfg_bag)):
            # track_length = 0
            # num_cameras = 0
            is_fail_list += [1]
            # num_3d_pts = 0

        else:
            is_fail_list += [0]

            # Get colmap output (binary files) path
            colmap_res_path = os.path.join(get_colmap_output_path(cfg_bag),
                                           str(get_best_colmap_index(cfg_bag)))

            # Read colmap models
            cameras, images, points = read_model(path=colmap_res_path,
                                                 ext='.bin')
            # Track length
            num_obs = []
            for idx in points:
                num_obs.append(len(np.unique(points[idx].image_ids)))
            if len(num_obs) == 0:
                num_obs = 0
            else:
                num_obs = np.array(num_obs)
                num_obs = num_obs.mean()
            track_length_list += [num_obs]
            # Number of cameras
            num_cameras_list += [len(list(images.keys()))]
            # Number of 3D points
            num_3d_pts_list += [len(points)]

    # Aggregate results for all bags
    res_dict['avg_track_length'] = float(
        np.mean(track_length_list)) if len(track_length_list) > 0 else 0.0
    res_dict['avg_num_cameras'] = float(
        np.mean(num_cameras_list)) if len(num_cameras_list) > 0 else 0.0
    res_dict['success_rate'] = float(1.0 - np.mean(is_fail_list))
    res_dict['avg_num_3d_points'] = float(
        np.mean(num_3d_pts_list)) if len(num_3d_pts_list) > 0 else 0.0
    res_dict['num_in_bag'] = float(get_num_in_bag(cfg_bag))
示例#2
0
def compute_ATE(res_dict, deprecated_images, cfg):
    '''Compute the Absolute Trajectory Error and add it to the dictionary.'''

    ate_list = []

    # For all the bags
    cfg_bag = deepcopy(cfg)
    data_dir = get_data_path(cfg)
    calib_list = get_fullpath_list(data_dir, 'calibration')
    calib_dict = load_calib(calib_list)
    for bag_id in range(get_num_in_bag(cfg_bag)):
        cfg_bag.bag_id = bag_id

        # Skip if bag contains deprecated images
        if not valid_bag(cfg_bag, deprecated_images):
            continue

        # Get colmap output (binary files) path
        colmap_res_path = os.path.join(get_colmap_output_path(cfg_bag),
                                       str(get_best_colmap_index(cfg_bag)))

        # Check if colmap output path exists. We compute stats for track
        # length, num_cameras, num 3d points, only when colmap succeeds
        if os.path.exists(colmap_res_path):
            # Read colmap models
            _, images, _ = read_model(path=colmap_res_path, ext='.bin')
            first_xyz, second_xyz = [], []
            for _, value in images.items():

                # Get ground truth translation
                t_gt = calib_dict[value.name.split('.')[0]]['T']
                r_gt = calib_dict[value.name.split('.')[0]]['R']
                first_xyz.append(-np.dot(r_gt.T, t_gt))

                # Get actual translation
                t = np.asarray(value.tvec).flatten().reshape((3, ))
                r = np.asarray(qvec2rotmat(value.qvec))
                second_xyz.append(-np.dot(r.T, t))

            first_xyz = np.asarray(first_xyz).transpose()
            second_xyz = np.asarray(second_xyz).transpose()
            num_points = first_xyz.shape[1]
            if num_points >= 3:
                prob_inlier = max(3 / num_points, 0.5)
                num_iter = int(calc_num_iter_ransac(prob_inlier))
                std = calc_std(first_xyz)
                max_trans_error = calc_max_trans_error(first_xyz)
                rot, trans, scale, trans_error, num_inlier = ate_ransac(
                    second_xyz, first_xyz, num_iter, std * 0.5)
                if trans_error > max_trans_error or \
                        num_inlier < 0.3 * num_points:
                    trans_error = max_trans_error
                ate_list += [trans_error]

    # Aggregate results for all bags
    res_dict['avg_ate'] = float(np.mean(ate_list))