コード例 #1
0
def load_scenes(scene_id, eval_args, depth=False):

    dataset_name = eval_args.get('DATA','DATASET')
    cam_type = eval_args.get('DATA','CAM_TYPE')

    p = dataset_params.get_dataset_params(dataset_name, model_type='', train_type='', test_type=cam_type, cam_type=cam_type)
    cam_p = inout.load_cam_params(p['cam_params_path'])
    noof_imgs = noof_scene_views(scene_id, eval_args)
    if depth:
        imgs = np.empty((noof_imgs,) + p['test_im_size'][::-1], dtype=np.float32)
        for view_id in xrange(noof_imgs):
            depth_path = p['test_depth_mpath'].format(scene_id, view_id)
            try:
                imgs[view_id,...] = inout.load_depth2(depth_path) * cam_p['depth_scale']
            except:
                print depth_path,' not found'
    
    else:    
        print (noof_imgs,) + p['test_im_size'][::-1] + (3,)
        imgs = np.empty((noof_imgs,) + p['test_im_size'][::-1] + (3,), dtype=np.uint8)
        print noof_imgs
        for view_id in xrange(noof_imgs):
            img_path = p['test_rgb_mpath'].format(scene_id, view_id)
            try:
                imgs[view_id,...] = cv2.imread(img_path)
            except:
                print img_path,' not found'

    return imgs
コード例 #2
0
def eval_calc_errors(eval_args, eval_dir):
    # Results for which the errors will be calculated
    #-------------------------------------------------------------------------------

    # result_base = '/path/to/results/'
    # result_paths = [
    #     pjoin(result_base, 'hodan-iros15_hinterstoisser'),
    #     # pjoin(result_base, 'hodan-iros15_tless_primesense'),
    # ]

    #[METHOD]
    method = eval_args.get('METHOD', 'METHOD')

    #[DATA]
    dataset = eval_args.get('DATA', 'DATASET')
    test_type = eval_args.get('DATA', 'CAM_TYPE')

    #[METRIC]
    # Top N pose estimates (with the highest score) to be evaluated for each
    # object in each image
    n_top = eval_args.getint(
        'EVALUATION', 'TOP_N_EVAL'
    )  # 0 = all estimates, -1 = given by the number of GT poses
    n_top_str = eval_args.getint('METRIC', 'TOP_N')
    # Pose error function
    error_types = eval(eval_args.get(
        'METRIC', 'ERROR_TYPE'))  # 'vsd', 'adi', 'add', 'cou', 're', 'te'
    # VSD parameters
    vsd_delta = eval_args.getint('METRIC', 'VSD_DELTA')
    vsd_tau = eval_args.getint('METRIC', 'VSD_TAU')
    vsd_cost = eval_args.get('METRIC', 'VSD_COST')  # 'step', 'tlinear'

    result_path = eval_dir
    print('Processing: ' + result_path)
    # Other paths
    #-------------------------------------------------------------------------------

    for error_type in error_types:

        # Mask of path to the output file with calculated errors
        # errors_mpath = pjoin('{result_path}', '..', '..', 'eval', '{result_name}',
        #                      '{error_sign}', 'errors_{scene_id:02d}.yml')
        errors_mpath = '{result_path}/{error_sign}/errors_{scene_id:02d}.yml'

        # Error signature
        error_sign = 'error=' + error_type + '_ntop=' + str(n_top_str)
        if error_type == 'vsd':
            error_sign += '_delta={}_tau={}_cost={}'.format(
                vsd_delta, vsd_tau, vsd_cost)

        # Error calculation
        #-------------------------------------------------------------------------------

        # Select data type
        if dataset == 'tless':
            cam_type = test_type
            if error_type in ['adi', 'add']:
                model_type = 'cad_subdivided'
            else:
                model_type = 'cad'
        else:
            model_type = ''
            cam_type = ''

        # Load dataset parameters
        dp = get_dataset_params(dataset,
                                model_type=model_type,
                                test_type=test_type,
                                cam_type=cam_type)

        # Load object models
        if error_type in ['vsd', 'add', 'adi', 'cou', 'proj', 'projamb']:
            print('Loading object models...')
            models = {}
            for obj_id in range(1, dp['obj_count'] + 1):
                models[obj_id] = inout.load_ply(
                    dp['model_mpath'].format(obj_id))

        test_sensor = pjoin(dp['base_path'], dp['test_dir'])
        # Directories with results for individual scenes
        scene_dirs = sorted([
            d for d in glob.glob(os.path.join(result_path, '*'))
            if os.path.isdir(d) and os.path.basename(d).isdigit()
        ])
        print scene_dirs

        for scene_dir in scene_dirs:
            scene_id = int(os.path.basename(scene_dir))

            # Load info and GT poses for the current scene
            scene_info = inout.load_info(
                dp['scene_info_mpath'].format(scene_id))
            scene_gt = inout.load_gt(dp['scene_gt_mpath'].format(scene_id))

            res_paths = sorted(glob.glob(os.path.join(scene_dir, '*.yml')))

            errs = []
            im_id = -1
            depth_im = None
            for res_id, res_path in enumerate(res_paths):
                # t = time.time()

                # Parse image ID and object ID from the filename
                filename = os.path.basename(res_path).split('.')[0]
                im_id_prev = im_id
                im_id, obj_id = map(int, filename.split('_'))

                if res_id % 10 == 0:
                    dataset_str = dataset
                    if test_type != '':
                        dataset_str += ' - {}'.format(test_type)
                    print('Calculating error: {}, {}, {}, {}, {}, {}'.format(
                        error_type, method, dataset_str, scene_id, im_id,
                        obj_id))

                # Load depth image if VSD is selected
                if error_type == 'vsd' and im_id != im_id_prev:
                    depth_path = dp['test_depth_mpath'].format(scene_id, im_id)
                    # depth_im = inout.load_depth(depth_path)
                    depth_im = inout.load_depth2(depth_path)  # Faster
                    depth_im *= dp['cam']['depth_scale']  # to [mm]

                # Load camera matrix
                if error_type in ['vsd', 'cou', 'proj', 'projamb']:
                    K = scene_info[im_id]['cam_K']

                # Load pose estimates
                res = inout.load_results_sixd17(res_path)
                ests = res['ests']

                # Sort the estimates by score (in descending order)
                ests_sorted = sorted(enumerate(ests),
                                     key=lambda x: x[1]['score'],
                                     reverse=True)

                # Select the required number of top estimated poses
                if n_top == 0:  # All estimates are considered
                    n_top_curr = None
                elif n_top == -1:  # Given by the number of GT poses
                    n_gt = sum(
                        [gt['obj_id'] == obj_id for gt in scene_gt[im_id]])
                    n_top_curr = n_gt
                else:
                    n_top_curr = n_top
                ests_sorted = ests_sorted[slice(0, n_top_curr)]

                for est_id, est in ests_sorted:
                    est_errs = []
                    R_e = est['R']
                    t_e = est['t']

                    errs_gts = {}  # Errors w.r.t. GT poses of the same object
                    for gt_id, gt in enumerate(scene_gt[im_id]):
                        if gt['obj_id'] != obj_id:
                            continue

                        e = -1.0
                        R_g = gt['cam_R_m2c']
                        t_g = gt['cam_t_m2c']

                        if error_type == 'vsd':
                            e = pose_error.vsd(R_e, t_e, R_g, t_g,
                                               models[obj_id], depth_im, K,
                                               vsd_delta, vsd_tau, vsd_cost)
                        elif error_type == 'add':
                            e = pose_error.add(R_e, t_e, R_g, t_g,
                                               models[obj_id])
                        elif error_type == 'adi':
                            e = pose_error.adi(R_e, t_e, R_g, t_g,
                                               models[obj_id])
                        elif error_type == 'proj':
                            e = pose_error.arp_2d(R_e, t_e, R_g, t_g,
                                                  models[obj_id], K)
                        elif error_type == 'projamb':
                            e = pose_error.arpi_2d(R_e, t_e, R_g, t_g,
                                                   models[obj_id], K)
                        elif error_type == 'cou':
                            e = pose_error.cou(R_e, t_e, R_g, t_g,
                                               models[obj_id],
                                               dp['test_im_size'], K)
                        elif error_type == 're':
                            e = pose_error.re(R_e, R_g)
                        elif error_type == 'te':
                            e = pose_error.te(t_e, t_g)

                        errs_gts[gt_id] = e

                    errs.append({
                        'im_id': im_id,
                        'obj_id': obj_id,
                        'est_id': est_id,
                        'score': est['score'],
                        'errors': errs_gts
                    })
                # print('Evaluation time: {}s'.format(time.time() - t))

            print('Saving errors...')
            errors_path = errors_mpath.format(result_path=result_path,
                                              error_sign=error_sign,
                                              scene_id=scene_id)

            misc.ensure_dir(os.path.dirname(errors_path))
            inout.save_errors(errors_path, errs)

            print('')
    print('Done.')
    return True