Ejemplo n.º 1
0
def run_kitti_native_script_with_05_iou(checkpoint_name,
                                        score_threshold,
                                        global_step,
                                        output_dir=None):
    """Runs the kitti native code script."""

    if output_dir is None:
        output_dir = avod.root_dir() + '/data/outputs/'

    eval_script_dir = os.path.join(output_dir,checkpoint_name) + \
        '/predictions'
    make_script = eval_script_dir + \
        '/kitti_native_eval/run_eval_05_iou.sh'
    script_folder = eval_script_dir + \
        '/kitti_native_eval/'

    if output_dir is None:
        results_dir = avod.top_dir() + '/scripts/offline_eval/results_05_iou/'
    else:
        results_dir = os.path.join(
            output_dir, checkpoint_name) + '/offline_eval/results_05_iou/'

    # Round this because protobuf encodes default values as full decimal
    score_threshold = round(score_threshold, 3)

    subprocess.call([
        make_script, script_folder,
        str(score_threshold),
        str(global_step),
        str(checkpoint_name),
        str(results_dir)
    ])
Ejemplo n.º 2
0
def copy_kitti_native_code(checkpoint_name):
    """Copies and compiles kitti native code.

    It also creates neccessary directories for storing the results
    of the kitti native evaluation code.
    """

    avod_root_dir = avod.root_dir()
    kitti_native_code_copy = avod_root_dir + '/data/outputs/' + \
        checkpoint_name + '/predictions/kitti_native_eval/'

    # Only copy if the code has not been already copied over
    if not os.path.exists(kitti_native_code_copy):

        os.makedirs(kitti_native_code_copy)
        original_kitti_native_code = avod.top_dir() + \
            '/scripts/offline_eval/kitti_native_eval/'

        predictions_dir = avod_root_dir + '/data/outputs/' + \
            checkpoint_name + '/predictions/'
        # create dir for it first
        dir_util.copy_tree(original_kitti_native_code, kitti_native_code_copy)
        # run the script to compile the c++ code
        script_folder = predictions_dir + \
            '/kitti_native_eval/'
        make_script = script_folder + 'run_make.sh'
        subprocess.call([make_script, script_folder])

    # Set up the results folders if they don't exist
    results_dir = avod.top_dir() + '/scripts/offline_eval/results'
    results_05_dir = avod.top_dir() + '/scripts/offline_eval/results_05_iou'
    if not os.path.exists(results_dir):
        os.makedirs(results_dir)
    if not os.path.exists(results_05_dir):
        os.makedirs(results_05_dir)
Ejemplo n.º 3
0
def get_configs_from_pipeline_file(pipeline_config_path, is_training):
    """Reads model configuration from a pipeline_pb2.NetworkPipelineConfig.
    Args:
        pipeline_config_path: A path directory to the network pipeline config
        is_training: A boolean flag to indicate training stage, used for
            creating the checkpoint directory which must be created at the
            first training iteration.
    Returns:
        model_config: A model_pb2.ModelConfig
        train_config: A train_pb2.TrainConfig
        eval_config: A eval_pb2.EvalConfig
        dataset_config: A kitti_dataset_pb2.KittiDatasetConfig
    """

    pipeline_config = pipeline_pb2.NetworkPipelineConfig()
    with open(pipeline_config_path, 'r') as f:
        text_format.Merge(f.read(), pipeline_config)  #解析config文件

    model_config = pipeline_config.model_config

    # Make sure the checkpoint name matches the config filename
    config_file_name = \
        os.path.split(pipeline_config_path)[1].split('.')[0]
    checkpoint_name = model_config.checkpoint_name
    if config_file_name != checkpoint_name:
        raise ValueError('Config and checkpoint names must match.')

    output_root_dir = avod.root_dir() + '/data/outputs/' + checkpoint_name

    # Construct paths
    paths_config = model_config.paths_config
    if not paths_config.checkpoint_dir:
        checkpoint_dir = output_root_dir + '/checkpoints'

        if is_training:
            if not os.path.exists(checkpoint_dir):
                os.makedirs(checkpoint_dir)

        paths_config.checkpoint_dir = checkpoint_dir

    if not paths_config.logdir:
        paths_config.logdir = output_root_dir + '/logs/'

    if not paths_config.pred_dir:
        paths_config.pred_dir = output_root_dir + '/predictions'

    train_config = pipeline_config.train_config
    eval_config = pipeline_config.eval_config
    dataset_config = pipeline_config.dataset_config

    if is_training:
        # Copy the config to the experiments folder
        experiment_config_path = output_root_dir + '/' +\
            model_config.checkpoint_name
        experiment_config_path += '.config'
        # Copy this even if the config exists, in case some parameters
        # were modified
        shutil.copy(pipeline_config_path, experiment_config_path)

    return model_config, train_config, eval_config, dataset_config
Ejemplo n.º 4
0
    def test_get_clusters(self):

        # classes = ['Car', 'Pedestrian', 'Cyclist']
        num_clusters = [2, 1, 1]

        label_cluster_utils = LabelClusterUtils(self.dataset)
        clusters, std_devs = label_cluster_utils.get_clusters()

        # Check that correct number of clusters are returned
        clusters_per_class = [len(cls_clusters) for cls_clusters in clusters]
        std_devs_per_class = [len(cls_std_devs) for cls_std_devs in std_devs]

        self.assertEqual(clusters_per_class, num_clusters)
        self.assertEqual(std_devs_per_class, num_clusters)

        # Check that text files were saved
        txt_folder_exists = os.path.isdir(
            avod.root_dir() + "/data/label_clusters/unittest-kitti")
        self.assertTrue(txt_folder_exists)

        # Calling get_clusters again should read from files
        read_clusters, read_std_devs = label_cluster_utils.get_clusters()

        # Check that read values are the same as generated ones
        np.testing.assert_allclose(np.vstack(clusters),
                                   np.vstack(read_clusters))
        np.testing.assert_allclose(np.vstack(std_devs),
                                   np.vstack(read_std_devs))
Ejemplo n.º 5
0
def main(_):
    parser = argparse.ArgumentParser()

    # Example usage
    # --checkpoint_name='avod_cars_example'
    # --data_split='test'
    # --ckpt_indices=50 100 112
    # Optional arg:
    # --device=0

    parser.add_argument('--checkpoint_name',
                        type=str,
                        dest='checkpoint_name',
                        required=True,
                        help='Checkpoint name must be specified as a str\
                        and must match the experiment config file name.')

    parser.add_argument('--data_split',
                        type=str,
                        dest='data_split',
                        required=True,
                        help='Data split must be specified e.g. val or test')

    parser.add_argument('--ckpt_indices',
                        type=int,
                        nargs='+',
                        dest='ckpt_indices',
                        required=True,
                        help='Checkpoint indices must be a set of \
        integers with space in between -> 0 10 20 etc')

    parser.add_argument('--device',
                        type=str,
                        dest='device',
                        default='0',
                        help='CUDA device id')

    args = parser.parse_args()
    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(1)

    experiment_config = args.checkpoint_name + '.config'

    # Read the config from the experiment folder
    experiment_config_path = avod.root_dir() + '/data/outputs/' +\
        args.checkpoint_name + '/' + experiment_config

    model_config, _, eval_config, dataset_config = \
        config_builder.get_configs_from_pipeline_file(
            experiment_config_path, is_training=False)

    os.environ['CUDA_VISIBLE_DEVICES'] = args.device
    inference(model_config, eval_config, dataset_config, args.data_split,
              args.ckpt_indices)

    # Visualize
    show_predictions_2d_jhuang.main(args.checkpoint_name)
Ejemplo n.º 6
0
    def setUpClass(cls):
        pipeline_config = pipeline_pb2.NetworkPipelineConfig()
        dataset_config = pipeline_config.dataset_config
        config_path = avod.root_dir() + '/configs/unittest_model.config'

        cls.model_config = config_build.get_model_config_from_file(config_path)

        dataset_config.MergeFrom(DatasetBuilder.KITTI_UNITTEST)
        cls.dataset = DatasetBuilder.build_kitti_dataset(dataset_config)
Ejemplo n.º 7
0
    def __init__(self, dataset):

        self._dataset = dataset

        self.cluster_split = dataset.cluster_split

        self.data_dir = avod.root_dir() + "/data/label_clusters"
        self.clusters = []
        self.std_devs = []
Ejemplo n.º 8
0
def main(_):

    experiment_config = 'avod_cars_example.config'

    # Read the config from the experiment folder
    experiment_config_path = avod.root_dir() + '/data/outputs/' +\
        'avod_cars_example' + '/' + experiment_config

    model_config, _, eval_config, dataset_config = \
        config_builder.get_configs_from_pipeline_file(
            experiment_config_path, is_training=False)

    os.environ['CUDA_VISIBLE_DEVICES'] = '0'
    test(model_config, eval_config, dataset_config, 'val', -1)
Ejemplo n.º 9
0
    def setUp(self):
        tf.test.TestCase.setUp(self)

        test_pipeline_config_path = avod.root_dir() + \
            '/configs/unittest_pipeline.config'

        self.model_config, self.train_config, _,  dataset_config = \
            config_builder.get_configs_from_pipeline_file(
                test_pipeline_config_path, is_training=True)

        # Generate dataset
        self.dataset = DatasetBuilder.build_kitti_dataset(
            DatasetBuilder.KITTI_UNITTEST, use_defaults=False,
            new_cfg=dataset_config)
Ejemplo n.º 10
0
def main(_):
    parser = argparse.ArgumentParser()

    default_pipeline_config_path = avod.root_dir() + \
        '/configs/avod_cars_example.config'

    default_output_dir = '/data/kitti_avod/object/outputs'

    parser.add_argument('--pipeline_config',
                        type=str,
                        dest='pipeline_config_path',
                        default=default_pipeline_config_path,
                        help='Path to the pipeline config')

    parser.add_argument('--data_split',
                        type=str,
                        dest='data_split',
                        default='val',
                        help='Data split for evaluation')

    parser.add_argument('--device',
                        type=str,
                        dest='device',
                        default=None,
                        help='CUDA device id')

    parser.add_argument('--output_dir',
                        type=str,
                        dest='output_dir',
                        default=default_output_dir,
                        help='output dir to save checkpoints')

    args = parser.parse_args()

    # Parse pipeline config
    model_config, _, eval_config, dataset_config = \
        config_builder.get_configs_from_pipeline_file(
            args.pipeline_config_path,
            is_training=False,
            output_dir=args.output_dir)

    # Overwrite data split
    dataset_config.data_split = args.data_split

    # Set CUDA device id
    if args.device:
        os.environ['CUDA_VISIBLE_DEVICES'] = args.device

    evaluate(model_config, eval_config, dataset_config,
             output_dir=args.output_dir)
Ejemplo n.º 11
0
def main(_):
    parser = argparse.ArgumentParser()

    # Defaults
    default_pipeline_config_path = avod.root_dir() + \
        '/configs/avod_cars_example.config'
    default_data_split = 'train'
    default_device = '1'

    parser.add_argument('--pipeline_config',
                        type=str,
                        dest='pipeline_config_path',
                        default=default_pipeline_config_path,
                        help='Path to the pipeline config')

    parser.add_argument('--data_split',
                        type=str,
                        dest='data_split',
                        default=default_data_split,
                        help='Data split for training')

    parser.add_argument('--device',
                        type=str,
                        dest='device',
                        default=default_device,
                        help='CUDA device id')

    parser.add_argument('--output_dir',
                        type=str,
                        help='out dir')


    args = parser.parse_args()

    # Parse pipeline config
    output = args.output_dir
    is_training=True
    model_config, train_config, _, dataset_config = \
        config_builder.get_configs_from_pipeline_file(
            args.pipeline_config_path, is_training, output)

    # Overwrite data split
    dataset_config.data_split = args.data_split

    # Set CUDA device id
    os.environ['CUDA_VISIBLE_DEVICES'] = args.device

    train(model_config, train_config, dataset_config)
Ejemplo n.º 12
0
def run_kitti_native_script(checkpoint_name, score_threshold, global_step):
    """Runs the kitti native code script."""

    eval_script_dir = avod.root_dir() + '/data/outputs/' + \
        checkpoint_name + '/predictions'
    make_script = eval_script_dir + \
        '/kitti_native_eval/run_eval.sh'
    script_folder = eval_script_dir + \
        '/kitti_native_eval/'

    results_dir = avod.top_dir() + '/scripts/offline_eval/results/'

    # Round this because protobuf encodes default values as full decimal
    score_threshold = round(score_threshold, 3)

    subprocess.call([make_script, script_folder,
                     str(score_threshold),
                     str(global_step),
                     str(checkpoint_name),
                     str(results_dir)])
Ejemplo n.º 13
0
def main(_):
    parser = argparse.ArgumentParser()

    default_pipeline_config_path = avod.root_dir() + \
        '/configs/avod_cars_example.config'

    parser.add_argument('--pipeline_config',
                        type=str,
                        dest='pipeline_config_path',
                        default=default_pipeline_config_path,
                        help='Path to the pipeline config')

    parser.add_argument('--data_split',
                        type=str,
                        dest='data_split',
                        default='val',
                        help='Data split for evaluation')

    parser.add_argument('--device',
                        type=str,
                        dest='device',
                        default='0',
                        help='CUDA device id')

    args = parser.parse_args()

    # Parse pipeline config
    model_config, _, eval_config, dataset_config = \
        config_builder.get_configs_from_pipeline_file(
            args.pipeline_config_path,
            is_training=False)

    # Overwrite data split
    dataset_config.data_split = args.data_split

    # Set CUDA device id
    os.environ['CUDA_VISIBLE_DEVICES'] = args.device

    evaluate(model_config, eval_config, dataset_config)
Ejemplo n.º 14
0
def infer_main(checkpoint_name,
               ckpt_indices,
               additional_cls,
               start_perspective=0):
    experiment_config = checkpoint_name + '.config'

    # Read the config from the experiment folder
    experiment_config_path = avod.root_dir() + '/data/outputs/' +\
        checkpoint_name + '/' + experiment_config

    model_config, _, eval_config, dataset_config = \
        config_builder.get_configs_from_pipeline_file(
            experiment_config_path, is_training=False)

    base_dir = os.path.split(cfg.DATASET_DIR)[0] + '/'

    os.environ['CUDA_VISIBLE_DEVICES'] = cfg.CUDA_DEVICE
    inference(model_config,
              eval_config,
              dataset_config,
              base_dir,
              ckpt_indices,
              additional_cls,
              start_perspective=start_perspective)
def main():
    parser = argparse.ArgumentParser()

    # Example usage
    # --checkpoint_name='avod_exp_example'
    # --base_dir='/home/<username>/GTAData/'

    parser.add_argument('--checkpoint_name',
                        type=str,
                        dest='checkpoint_name',
                        required=True,
                        help='Checkpoint name must be specified as a str\
                        and must match the experiment config file name.')

    parser.add_argument('--base_dir',
                        type=str,
                        dest='base_dir',
                        required=True,
                        help='Base data directory must be specified')

    args = parser.parse_args()
    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(1)

    experiment_config = args.checkpoint_name + '.config'

    # Read the config from the experiment folder
    experiment_config_path = avod.root_dir() + '/data/outputs/' +\
        args.checkpoint_name + '/' + experiment_config

    model_config, _, eval_config, dataset_config = \
        config_builder.get_configs_from_pipeline_file(
            experiment_config_path, is_training=False)

    filter_gt_labels(dataset_config, args.base_dir)
Ejemplo n.º 16
0
def main():
    """ Converts a set of network predictions into text files required for
    KITTI evaluation.
    """

    ##############################
    # Options
    ##############################
    checkpoint_name = 'fpn_people_dual_NHSP_train'#'fpn_people_dual_SHPL_train'#'pyramid_people_with_NHSP_example_train'#'pyramid_people_with_NHSP_example'

    data_split = 'val'#'test'#'val'

    global_steps = None
    # global_steps = [28000, 19000, 33000, 34000]

    score_threshold = 0.1

    save_2d = False  # Save 2D predictions
    save_3d = True   # Save 2D and 3D predictions together
    save_alphas = True  # Save alphas (observation angles)

    # Checkpoints below this are skipped
    min_step = 20000

    ##############################
    # End of Options
    ##############################

    # Parse experiment config
    pipeline_config_file = \
        avod.root_dir() + '/data/outputs/' + checkpoint_name + \
        '/' + checkpoint_name + '.config'
    _, _, _, dataset_config = \
        config_builder_util.get_configs_from_pipeline_file(
            pipeline_config_file, is_training=False)

    # Overwrite defaults
    dataset_config = config_builder_util.proto_to_obj(dataset_config)
    dataset_config.data_split = data_split
    dataset_config.aug_list = []

    if data_split == 'test':
        dataset_config.data_split_dir = 'testing'

    dataset = DatasetBuilder.build_kitti_dataset(dataset_config,
                                                 use_defaults=False)

    # Get available prediction folders
    predictions_root_dir = avod.root_dir() + '/data/outputs/' + \
        checkpoint_name + '/predictions'

    final_predictions_root_dir = predictions_root_dir + \
        '/final_predictions_and_scores/' + dataset.data_split

    print('Converting detections from', final_predictions_root_dir)

    if not global_steps:
        global_steps = os.listdir(final_predictions_root_dir)
        global_steps.sort(key=int)
        print('Checkpoints found ', global_steps)

    for step_idx in range(len(global_steps)):

        global_step = global_steps[step_idx]

        # Skip first checkpoint
        if int(global_step) < min_step:
            continue

        final_predictions_dir = final_predictions_root_dir + \
            '/' + str(global_step)

        # 2D and 3D prediction directories
        kitti_predictions_2d_dir = predictions_root_dir + \
            '/kitti_predictions_2d/' + \
            dataset.data_split + '/' + \
            str(score_threshold) + '/' + \
            str(global_step) + '/data'
        kitti_predictions_3d_dir = predictions_root_dir + \
            '/kitti_predictions_3d/' + \
            dataset.data_split + '/' + \
            str(score_threshold) + '/' + \
            str(global_step) + '/data'

        if save_2d and not os.path.exists(kitti_predictions_2d_dir):
            os.makedirs(kitti_predictions_2d_dir)
        if save_3d and not os.path.exists(kitti_predictions_3d_dir):
            os.makedirs(kitti_predictions_3d_dir)

        # Do conversion
        num_samples = dataset.num_samples
        num_valid_samples = 0

        print('\nGlobal step:', global_step)
        print('Converting detections from:', final_predictions_dir)

        if save_2d:
            print('2D Detections saved to:', kitti_predictions_2d_dir)
        if save_3d:
            print('3D Detections saved to:', kitti_predictions_3d_dir)

        for sample_idx in range(num_samples):

            # Print progress
            sys.stdout.write('\rConverting {} / {}'.format(
                sample_idx + 1, num_samples))
            sys.stdout.flush()

            sample_name = dataset.sample_names[sample_idx]

            prediction_file = sample_name + '.txt'

            kitti_predictions_2d_file_path = kitti_predictions_2d_dir + \
                '/' + prediction_file
            kitti_predictions_3d_file_path = kitti_predictions_3d_dir + \
                '/' + prediction_file

            predictions_file_path = final_predictions_dir + \
                '/' + prediction_file

            # If no predictions, skip to next file
            if not os.path.exists(predictions_file_path):
                if save_2d:
                    np.savetxt(kitti_predictions_2d_file_path, [])
                if save_3d:
                    np.savetxt(kitti_predictions_3d_file_path, [])
                continue

            all_predictions = np.loadtxt(predictions_file_path)

            # # Swap l, w for predictions where w > l
            # swapped_indices = all_predictions[:, 4] > all_predictions[:, 3]
            # fixed_predictions = np.copy(all_predictions)
            # fixed_predictions[swapped_indices, 3] = all_predictions[
            #     swapped_indices, 4]
            # fixed_predictions[swapped_indices, 4] = all_predictions[
            #     swapped_indices, 3]

            score_filter = all_predictions[:, 7] >= score_threshold
            all_predictions = all_predictions[score_filter]

            # If no predictions, skip to next file
            if len(all_predictions) == 0:
                if save_2d:
                    np.savetxt(kitti_predictions_2d_file_path, [])
                if save_3d:
                    np.savetxt(kitti_predictions_3d_file_path, [])
                continue

            # Project to image space
            sample_name = prediction_file.split('.')[0]
            img_idx = int(sample_name)

            # Load image for truncation
            image = Image.open(dataset.get_rgb_image_path(sample_name))

            stereo_calib_p2 = calib_utils.read_calibration(dataset.calib_dir,
                                                           img_idx).p2

            boxes = []
            image_filter = []
            for i in range(len(all_predictions)):
                box_3d = all_predictions[i, 0:7]
                img_box = box_3d_projector.project_to_image_space(
                    box_3d, stereo_calib_p2,
                    truncate=True, image_size=image.size)

                # Skip invalid boxes (outside image space)
                if img_box is None:
                    image_filter.append(False)
                else:
                    image_filter.append(True)
                    boxes.append(img_box)

            boxes = np.asarray(boxes)
            all_predictions = all_predictions[image_filter]

            # If no predictions, skip to next file
            if len(boxes) == 0:
                if save_2d:
                    np.savetxt(kitti_predictions_2d_file_path, [])
                if save_3d:
                    np.savetxt(kitti_predictions_3d_file_path, [])
                continue

            num_valid_samples += 1

            # To keep each value in its appropriate position, an array of zeros
            # (N, 16) is allocated but only values [4:16] are used
            kitti_predictions = np.zeros([len(boxes), 16])

            # Get object types
            all_pred_classes = all_predictions[:, 8].astype(np.int32)
            obj_types = [dataset.classes[class_idx]
                         for class_idx in all_pred_classes]

            # Truncation and Occlusion are always empty (see below)

            # Alpha
            if not save_alphas:
                kitti_predictions[:, 3] = -10 * \
                    np.ones((len(kitti_predictions)), dtype=np.int32)
            else:
                alphas = all_predictions[:, 6] - \
                    np.arctan2(all_predictions[:, 0], all_predictions[:, 2])
                kitti_predictions[:, 3] = alphas

            # 2D predictions
            kitti_predictions[:, 4:8] = boxes[:, 0:4]

            # 3D predictions
            # (l, w, h)
            kitti_predictions[:, 8] = all_predictions[:, 5]
            kitti_predictions[:, 9] = all_predictions[:, 4]
            kitti_predictions[:, 10] = all_predictions[:, 3]
            # (x, y, z)
            kitti_predictions[:, 11:14] = all_predictions[:, 0:3]
            # (ry, score)
            kitti_predictions[:, 14:16] = all_predictions[:, 6:8]

            # Round detections to 3 decimal places
            kitti_predictions = np.round(kitti_predictions, 3)

            # Empty Truncation, Occlusion
            kitti_empty_1 = -1 * np.ones((len(kitti_predictions), 2),
                                         dtype=np.int32)
            # Empty 3D (x, y, z)
            kitti_empty_2 = -1 * np.ones((len(kitti_predictions), 3),
                                         dtype=np.int32)
            # Empty 3D (h, w, l)
            kitti_empty_3 = -1000 * np.ones((len(kitti_predictions), 3),
                                            dtype=np.int32)
            # Empty 3D (ry)
            kitti_empty_4 = -10 * np.ones((len(kitti_predictions), 1),
                                          dtype=np.int32)

            # Stack 2D predictions text
            kitti_text_2d = np.column_stack([obj_types,
                                             kitti_empty_1,
                                             kitti_predictions[:, 3:8],
                                             kitti_empty_2,
                                             kitti_empty_3,
                                             kitti_empty_4,
                                             kitti_predictions[:, 15]])

            # Stack 3D predictions text
            kitti_text_3d = np.column_stack([obj_types,
                                             kitti_empty_1,
                                             kitti_predictions[:, 3:16]])

            # Save to text files
            if save_2d:
                np.savetxt(kitti_predictions_2d_file_path, kitti_text_2d,
                           newline='\r\n', fmt='%s')
            if save_3d:
                np.savetxt(kitti_predictions_3d_file_path, kitti_text_3d,
                           newline='\r\n', fmt='%s')

        print('\nNum valid:', num_valid_samples)
        print('Num samples:', num_samples)
Ejemplo n.º 17
0
def save_predictions_in_kitti_format(model,
                                     checkpoint_name,
                                     data_split,
                                     score_threshold,
                                     global_step,
                                     output_dir=None,
                                     do_eval_sin=False,
                                     do_eval_ain=False,
                                     sin_type='rand',
                                     sin_level=5,
                                     sin_repeat=10,
                                     sin_input_name=None,
                                     idx_repeat=None):
    """ Converts a set of network predictions into text files required for
    KITTI evaluation.
    """

    if output_dir is None:
        output_dir = avod.root_dir() + '/data/outputs/'

    dataset = model.dataset
    # Round this because protobuf encodes default values as full decimal
    score_threshold = round(score_threshold, 3)

    # Get available prediction folders
    predictions_root_dir = os.path.join(output_dir,checkpoint_name) + \
        '/predictions'
    if do_eval_sin:
        predictions_root_dir += '_sin_{}_{}_{}/{}'.format(
            sin_type, sin_level, sin_repeat, sin_input_name)
    elif do_eval_ain:
        predictions_root_dir += '_ain_{}_{}_{}'.format(sin_type, sin_level,
                                                       sin_repeat)

    final_predictions_root_dir = predictions_root_dir + \
        '/final_predictions_and_scores/' + dataset.data_split

    final_predictions_dir = final_predictions_root_dir + \
        '/' + str(global_step)

    # 3D prediction directories
    if idx_repeat is None:
        kitti_predictions_3d_dir = predictions_root_dir + \
            '/kitti_native_eval/' + \
            str(score_threshold) + '_' + data_split + '/' + \
            str(global_step)  + '/data'
    else:
        kitti_predictions_3d_dir = predictions_root_dir + \
            '/kitti_native_eval/' + \
            str(score_threshold) + '_' + data_split + '_{}_rep/'.format(idx_repeat) + \
            str(global_step) + '/data'

    if not os.path.exists(kitti_predictions_3d_dir):
        os.makedirs(kitti_predictions_3d_dir)

    # Do conversion
    num_samples = dataset.num_samples
    num_valid_samples = 0

    print('\nGlobal step:', global_step)
    print('Converting detections from:', final_predictions_dir)

    print('3D Detections being saved to:', kitti_predictions_3d_dir)

    for sample_idx in range(num_samples):

        # Print progress
        sys.stdout.write('\rConverting {} / {}'.format(sample_idx + 1,
                                                       num_samples))
        sys.stdout.flush()

        sample_name = dataset.sample_names[sample_idx]

        prediction_file = sample_name + '.txt'

        kitti_predictions_3d_file_path = kitti_predictions_3d_dir + \
            '/' + prediction_file

        predictions_file_path = final_predictions_dir + \
            '/' + prediction_file

        # If no predictions, skip to next file
        if not os.path.exists(predictions_file_path):
            np.savetxt(kitti_predictions_3d_file_path, [])
            continue

        all_predictions = np.loadtxt(predictions_file_path)

        # # Swap l, w for predictions where w > l
        # swapped_indices = all_predictions[:, 4] > all_predictions[:, 3]
        # fixed_predictions = np.copy(all_predictions)
        # fixed_predictions[swapped_indices, 3] = all_predictions[
        #     swapped_indices, 4]
        # fixed_predictions[swapped_indices, 4] = all_predictions[
        #     swapped_indices, 3]

        score_filter = all_predictions[:, 7] >= score_threshold
        all_predictions = all_predictions[score_filter]

        # If no predictions, skip to next file
        if len(all_predictions) == 0:
            np.savetxt(kitti_predictions_3d_file_path, [])
            continue

        # Project to image space
        sample_name = prediction_file.split('.')[0]
        img_idx = int(sample_name)

        # Load image for truncation
        image = Image.open(dataset.get_rgb_image_path(sample_name))

        stereo_calib_p2 = calib_utils.read_calibration(dataset.calib_dir,
                                                       img_idx).p2

        boxes = []
        image_filter = []
        for i in range(len(all_predictions)):
            box_3d = all_predictions[i, 0:7]
            img_box = box_3d_projector.project_to_image_space(
                box_3d, stereo_calib_p2, truncate=True, image_size=image.size)

            # Skip invalid boxes (outside image space)
            if img_box is None:
                image_filter.append(False)
                continue

            image_filter.append(True)
            boxes.append(img_box)

        boxes = np.asarray(boxes)
        all_predictions = all_predictions[image_filter]

        # If no predictions, skip to next file
        if len(boxes) == 0:
            np.savetxt(kitti_predictions_3d_file_path, [])
            continue

        num_valid_samples += 1

        # To keep each value in its appropriate position, an array of zeros
        # (N, 16) is allocated but only values [4:16] are used
        kitti_predictions = np.zeros([len(boxes), 16])

        # Get object types
        all_pred_classes = all_predictions[:, 8].astype(np.int32)
        obj_types = [
            dataset.classes[class_idx] for class_idx in all_pred_classes
        ]

        # Truncation and Occlusion are always empty (see below)

        # Alpha (Not computed)
        kitti_predictions[:, 3] = -10 * np.ones(
            (len(kitti_predictions)), dtype=np.int32)

        # 2D predictions
        kitti_predictions[:, 4:8] = boxes[:, 0:4]

        # 3D predictions
        # (l, w, h)
        kitti_predictions[:, 8] = all_predictions[:, 5]
        kitti_predictions[:, 9] = all_predictions[:, 4]
        kitti_predictions[:, 10] = all_predictions[:, 3]
        # (x, y, z)
        kitti_predictions[:, 11:14] = all_predictions[:, 0:3]
        # (ry, score)
        kitti_predictions[:, 14:16] = all_predictions[:, 6:8]

        # Round detections to 3 decimal places
        kitti_predictions = np.round(kitti_predictions, 3)

        # Empty Truncation, Occlusion
        kitti_empty_1 = -1 * np.ones(
            (len(kitti_predictions), 2), dtype=np.int32)

        # Stack 3D predictions text
        kitti_text_3d = np.column_stack(
            [obj_types, kitti_empty_1, kitti_predictions[:, 3:16]])

        # Save to text files
        np.savetxt(kitti_predictions_3d_file_path,
                   kitti_text_3d,
                   newline='\r\n',
                   fmt='%s')

    print('\nNum valid:', num_valid_samples)
    print('Num samples:', num_samples)
Ejemplo n.º 18
0
def save_predictions_in_kitti_format(model,
                                     checkpoint_name,
                                     data_split,
                                     score_threshold,
                                     global_step):
    """ Converts a set of network predictions into text files required for
    KITTI evaluation.
    """

    dataset = model.dataset
    # Round this because protobuf encodes default values as full decimal
    score_threshold = round(score_threshold, 3)

    # Get available prediction folders
    predictions_root_dir = avod.root_dir() + '/data/outputs/' + \
        checkpoint_name + '/predictions'


    final_predictions_root_dir = predictions_root_dir + \
        '/final_predictions_and_scores/' + dataset.data_split

    final_predictions_dir = final_predictions_root_dir + \
        '/' + str(global_step)

    # 3D prediction directories
    kitti_predictions_3d_dir = predictions_root_dir + \
        '/kitti_native_eval/' + \
        str(score_threshold) + '/' + \
        str(global_step) + '/data'

    if not os.path.exists(kitti_predictions_3d_dir):
        os.makedirs(kitti_predictions_3d_dir)

    # Do conversion
    num_samples = dataset.num_samples
    num_valid_samples = 0

    print('\nGlobal step:', global_step)
    print('Converting detections from:', final_predictions_dir)

    print('3D Detections being saved to:', kitti_predictions_3d_dir)

    for sample_idx in range(num_samples):

        # Print progress
        sys.stdout.write('\rConverting {} / {}'.format(
            sample_idx + 1, num_samples))
        sys.stdout.flush()

        sample_name = dataset.sample_names[sample_idx]

        prediction_file = sample_name + '.txt'

        kitti_predictions_3d_file_path = kitti_predictions_3d_dir + \
            '/' + prediction_file

        predictions_file_path = final_predictions_dir + \
            '/' + prediction_file

        # If no predictions, skip to next file
        if not os.path.exists(predictions_file_path):
            np.savetxt(kitti_predictions_3d_file_path, [])
            continue

        all_predictions = np.loadtxt(predictions_file_path)

        # # Swap l, w for predictions where w > l
        # swapped_indices = all_predictions[:, 4] > all_predictions[:, 3]
        # fixed_predictions = np.copy(all_predictions)
        # fixed_predictions[swapped_indices, 3] = all_predictions[
        #     swapped_indices, 4]
        # fixed_predictions[swapped_indices, 4] = all_predictions[
        #     swapped_indices, 3]

        score_filter = all_predictions[:, 7] >= score_threshold
        all_predictions = all_predictions[score_filter]

        # If no predictions, skip to next file
        if len(all_predictions) == 0:
            np.savetxt(kitti_predictions_3d_file_path, [])
            continue

        # Project to image space
        sample_name = prediction_file.split('.')[0]
        img_idx = int(sample_name)

        # Load image for truncation
        image = Image.open(dataset.get_rgb_image_path(sample_name))

        #stereo_calib_p2 = calib_utils.read_calibration(dataset.calib_dir,
                                                       #img_idx).p2

        # Get calibration
        calib = moose_load_calibration.load_calibration(dataset.calib_dir)

        if img_idx < 100:

            T_IMG_CAM = np.eye(4);  # identity matrix
            T_IMG_CAM[0:3, 0:3] = np.array(calib['CAM00']['camera_matrix']['data']).reshape(-1,
                                                                                            3)  # camera to image #intrinsic matrix

            # T_IMG_CAM : 4 x 4 matrix
            T_IMG_CAM = T_IMG_CAM[0:3, 0:4];  # remove last row, #choose the first 3 rows and get rid of the last column

            stereo_calib_p2 = T_IMG_CAM

        elif (img_idx >= 100 and img_idx < 200):
            T_IMG_CAM = np.eye(4);  # identity matrix
            T_IMG_CAM[0:3, 0:3] = np.array(calib['CAM01']['camera_matrix']['data']).reshape(-1,
                                                                                            3)  # camera to image #intrinsic matrix

            # T_IMG_CAM : 4 x 4 matrix
            T_IMG_CAM = T_IMG_CAM[0:3, 0:4];  # remove last row, #choose the first 3 rows and get rid of the last column

            stereo_calib_p2 = T_IMG_CAM

        elif (img_idx >= 200 and img_idx < 300):
            T_IMG_CAM = np.eye(4);  # identity matrix
            T_IMG_CAM[0:3, 0:3] = np.array(calib['CAM02']['camera_matrix']['data']).reshape(-1,
                                                                                            3)  # camera to image #intrinsic matrix

            # T_IMG_CAM : 4 x 4 matrix
            T_IMG_CAM = T_IMG_CAM[0:3, 0:4];  # remove last row, #choose the first 3 rows and get rid of the last column

            stereo_calib_p2 = T_IMG_CAM

        elif (img_idx >= 300 and img_idx < 400):
            T_IMG_CAM = np.eye(4);  # identity matrix
            T_IMG_CAM[0:3, 0:3] = np.array(calib['CAM03']['camera_matrix']['data']).reshape(-1,
                                                                                            3)  # camera to image #intrinsic matrix

            # T_IMG_CAM : 4 x 4 matrix
            T_IMG_CAM = T_IMG_CAM[0:3, 0:4];  # remove last row, #choose the first 3 rows and get rid of the last column

            stereo_calib_p2 = T_IMG_CAM

        elif (img_idx >= 400 and img_idx < 500):
            T_IMG_CAM = np.eye(4);  # identity matrix
            T_IMG_CAM[0:3, 0:3] = np.array(calib['CAM04']['camera_matrix']['data']).reshape(-1,
                                                                                            3)  # camera to image #intrinsic matrix

            # T_IMG_CAM : 4 x 4 matrix
            T_IMG_CAM = T_IMG_CAM[0:3, 0:4];  # remove last row, #choose the first 3 rows and get rid of the last column

            stereo_calib_p2 = T_IMG_CAM

        elif (img_idx >= 500 and img_idx < 600):
            T_IMG_CAM = np.eye(4);  # identity matrix
            T_IMG_CAM[0:3, 0:3] = np.array(calib['CAM05']['camera_matrix']['data']).reshape(-1,
                                                                                            3)  # camera to image #intrinsic matrix

            # T_IMG_CAM : 4 x 4 matrix
            T_IMG_CAM = T_IMG_CAM[0:3, 0:4];  # remove last row, #choose the first 3 rows and get rid of the last column

            stereo_calib_p2 = T_IMG_CAM

        elif (img_idx >= 600 and img_idx < 700):
            T_IMG_CAM = np.eye(4);  # identity matrix
            T_IMG_CAM[0:3, 0:3] = np.array(calib['CAM06']['camera_matrix']['data']).reshape(-1,
                                                                                            3)  # camera to image #intrinsic matrix

            # T_IMG_CAM : 4 x 4 matrix
            T_IMG_CAM = T_IMG_CAM[0:3, 0:4];  # remove last row, #choose the first 3 rows and get rid of the last column

            stereo_calib_p2 = T_IMG_CAM

        elif (img_idx >= 700 and img_idx < 800):
            T_IMG_CAM = np.eye(4);  # identity matrix
            T_IMG_CAM[0:3, 0:3] = np.array(calib['CAM07']['camera_matrix']['data']).reshape(-1,
                                                                                            3)  # camera to image #intrinsic matrix

            # T_IMG_CAM : 4 x 4 matrix
            T_IMG_CAM = T_IMG_CAM[0:3, 0:4];  # remove last row, #choose the first 3 rows and get rid of the last column

            stereo_calib_p2 = T_IMG_CAM

        else:
            print("YOLO")

        boxes = []
        image_filter = []
        for i in range(len(all_predictions)):
            box_3d = all_predictions[i, 0:7]
            img_box = box_3d_projector.project_to_image_space(
                box_3d, stereo_calib_p2,
                truncate=True, image_size=image.size)

            # Skip invalid boxes (outside image space)
            if img_box is None:
                image_filter.append(False)
                continue

            image_filter.append(True)
            boxes.append(img_box)

        boxes = np.asarray(boxes)
        all_predictions = all_predictions[image_filter]

        # If no predictions, skip to next file
        if len(boxes) == 0:
            np.savetxt(kitti_predictions_3d_file_path, [])
            continue

        num_valid_samples += 1

        # To keep each value in its appropriate position, an array of zeros
        # (N, 16) is allocated but only values [4:16] are used
        kitti_predictions = np.zeros([len(boxes), 16])

        # Get object types
        all_pred_classes = all_predictions[:, 8].astype(np.int32)
        obj_types = [dataset.classes[class_idx]
                     for class_idx in all_pred_classes]

        # Truncation and Occlusion are always empty (see below)

        # Alpha (Not computed)
        kitti_predictions[:, 3] = -10 * np.ones((len(kitti_predictions)),
                                                dtype=np.int32)

        # 2D predictions
        kitti_predictions[:, 4:8] = boxes[:, 0:4]

        # 3D predictions
        # (l, w, h)
        kitti_predictions[:, 8] = all_predictions[:, 5]
        kitti_predictions[:, 9] = all_predictions[:, 4]
        kitti_predictions[:, 10] = all_predictions[:, 3]
        # (x, y, z)
        kitti_predictions[:, 11:14] = all_predictions[:, 0:3]
        # (ry, score)
        kitti_predictions[:, 14:16] = all_predictions[:, 6:8]

        # Round detections to 3 decimal places
        kitti_predictions = np.round(kitti_predictions, 3)

        # Empty Truncation, Occlusion
        kitti_empty_1 = -1 * np.ones((len(kitti_predictions), 2),
                                     dtype=np.int32)

        # Stack 3D predictions text
        kitti_text_3d = np.column_stack([obj_types,
                                         kitti_empty_1,
                                         kitti_predictions[:, 3:16]])

        # Save to text files
        np.savetxt(kitti_predictions_3d_file_path, kitti_text_3d,
                   newline='\r\n', fmt='%s')

    print('\nNum valid:', num_valid_samples)
    print('Num samples:', num_samples)
Ejemplo n.º 19
0
def copy_kitti_native_code(checkpoint_name,
                           output_dir=None,
                           do_eval_sin=False,
                           do_eval_ain=False,
                           sin_type='rand',
                           sin_level=5,
                           sin_repeat=10,
                           sin_input_names=None):
    """Copies and compiles kitti native code.

    It also creates neccessary directories for storing the results
    of the kitti native evaluation code.
    """

    if output_dir is None:
        output_dir = avod.root_dir() + '/data/outputs/'

    if do_eval_sin:
        if sin_input_names is None:
            raise ValueError('{} must have list of sin input names.'.format(
                sin_input_names))
        kitti_native_code_copies = [os.path.join(output_dir,checkpoint_name) + \
                '/predictions_sin_{}_{}_{}/{}/kitti_native_eval/'.format(
                    sin_type, sin_level, sin_repeat,sin_input_name) \
                for sin_input_name in sin_input_names]
    elif do_eval_ain:
        kitti_native_code_copies = [os.path.join(output_dir,checkpoint_name) + \
            '/predictions_ain_{}_{}_{}/kitti_native_eval/'.format(
                sin_type, sin_level, sin_repeat)]
    else:
        kitti_native_code_copies = [os.path.join(output_dir,checkpoint_name) + \
            '/predictions/kitti_native_eval/']

    # Only copy if the code has not been already copied over
    for (idx, kitti_native_code_copy) in enumerate(kitti_native_code_copies):
        if not os.path.exists(kitti_native_code_copy):
            os.makedirs(kitti_native_code_copy)
            original_kitti_native_code = avod.top_dir() + \
                '/scripts/offline_eval/kitti_native_eval/'

            if do_eval_sin:
                predictions_dir = os.path.join(output_dir,checkpoint_name) + \
                    '/predictions_sin_{}_{}_{}/{}/'.format(
                        sin_type, sin_level, sin_repeat,sin_input_names[idx])
            elif do_eval_ain:
                predictions_dir = os.path.join(output_dir,checkpoint_name) + \
                    '/predictions_ain_{}_{}_{}/'.format(
                        sin_type, sin_level, sin_repeat)
            else:
                predictions_dir = os.path.join(output_dir,checkpoint_name) + \
                    '/predictions/'
            # create dir for it first
            dir_util.copy_tree(original_kitti_native_code,
                               kitti_native_code_copy)
            # run the script to compile the c++ code
            script_folder = predictions_dir + \
                'kitti_native_eval/'
            make_script = script_folder + 'run_make.sh'
            subprocess.call([make_script, script_folder])

        # Set up the results folders if they don't exist
        if output_dir is None:
            results_dir = avod.top_dir() + '/scripts/offline_eval/results'
            results_05_dir = avod.top_dir(
            ) + '/scripts/offline_eval/results_05_iou'
        else:
            results_dir = os.path.join(
                output_dir, checkpoint_name) + '/offline_eval/results'
            results_05_dir = os.path.join(
                output_dir, checkpoint_name) + '/offline_eval/results_05_iou'
        if do_eval_sin:
            results_dir += '_sin_{}_{}_{}/{}'.format(sin_type, sin_level,
                                                     sin_repeat,
                                                     sin_input_names[idx])
            results_05_dir += '_sin_{}_{}_{}/{}'.format(
                sin_type, sin_level, sin_repeat, sin_input_names[idx])
        elif do_eval_ain:
            results_dir += '_ain_{}_{}_{}'.format(sin_type, sin_level,
                                                  sin_repeat)
            results_05_dir += '_ain_{}_{}_{}'.format(sin_type, sin_level,
                                                     sin_repeat)

        if not os.path.exists(results_dir):
            os.makedirs(results_dir)
        if not os.path.exists(results_05_dir):
            os.makedirs(results_05_dir)
Ejemplo n.º 20
0
def run_kitti_native_script_with_05_iou(checkpoint_name,
                                        score_threshold,
                                        global_step,
                                        output_dir=None,
                                        do_eval_sin=False,
                                        do_eval_ain=False,
                                        sin_type='rand',
                                        sin_level=5,
                                        sin_repeat=10,
                                        sin_input_name=None,
                                        idx_repeat=None,
                                        data_split=None):
    """Runs the kitti native code script."""

    if output_dir is None:
        output_dir = avod.root_dir() + '/data/outputs/'

    eval_script_dir = os.path.join(output_dir,checkpoint_name) + \
        '/predictions'
    if do_eval_sin:
        eval_script_dir += '_sin_{}_{}_{}/{}'.format(sin_type, sin_level,
                                                     sin_repeat,
                                                     sin_input_name)
    elif do_eval_ain:
        eval_script_dir += '_ain_{}_{}_{}'.format(sin_type, sin_level,
                                                  sin_repeat)
    make_script = eval_script_dir + \
        '/kitti_native_eval/run_eval_05_iou.sh'
    script_folder = eval_script_dir + \
        '/kitti_native_eval/'

    if output_dir is None:
        if do_eval_sin:
            results_dir = avod.top_dir() + \
                '/scripts/offline_eval/results_05_iou_sin_{}_{}_{}/{}/'.format(
                    sin_type, sin_level, sin_repeat, sin_input_name)
        elif do_eval_ain:
            results_dir = avod.top_dir() + \
                '/scripts/offline_eval/results_05_iou_ain_{}_{}_{}/'.format(
                    sin_type, sin_level, sin_repeat)
        else:
            results_dir = avod.top_dir() + \
                '/scripts/offline_eval/results_05_iou/'
    else:
        if do_eval_sin:
            results_dir = os.path.join(output_dir,checkpoint_name) + \
                '/offline_eval/results_05_iou_sin_{}_{}_{}/{}/'.format(
                    sin_type, sin_level, sin_repeat, sin_input_name)
        elif do_eval_ain:
            results_dir = os.path.join(output_dir,checkpoint_name) + \
                '/offline_eval/results_05_iou_ain_{}_{}_{}/'.format(
                    sin_type, sin_level, sin_repeat)
        else:
            results_dir = os.path.join(output_dir,checkpoint_name) + \
                '/offline_eval/results_05_iou/'

    # Round this because protobuf encodes default values as full decimal
    score_threshold = round(score_threshold, 3)

    if idx_repeat is None:
        offline_res_name = str(score_threshold) + '_' + data_split
    else:
        # result dir is different
        offline_res_name = str(score_threshold)+ '_' + data_split + \
                           '_{}_rep'.format(idx_repeat)

    subprocess.call([
        make_script, script_folder, offline_res_name,
        str(global_step),
        str(checkpoint_name),
        str(results_dir)
    ])
Ejemplo n.º 21
0
def main():

    parser = argparse.ArgumentParser()

    default_pipeline_config_path = avod.root_dir() + \
        '/configs/avod_ssd_cars_example.config'

    parser.add_argument('--pipeline_config',
                        type=str,
                        dest='pipeline_config_path',
                        default=default_pipeline_config_path,
                        help='Path to the pipeline config')

    parser.add_argument('--data_split',
                        type=str,
                        dest='data_split',
                        default='test',
                        help='Data split for evaluation')

    parser.add_argument('--device',
                        type=str,
                        dest='device',
                        default='0',
                        help='CUDA device id')

    parser.add_argument('--output',
                        type=str,
                        dest='output',
                        default='model_timeline.json',
                        help='CUDA device id')

    args = parser.parse_args()

    model = set_up_model(args.pipeline_config_path, args.data_split)

    prediction_dict = model.build()

    # Set CUDA device id
    os.environ['CUDA_VISIBLE_DEVICES'] = args.device

    # Set session config
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True

    # Set run options
    run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
    run_metadata = tf.RunMetadata()

    # Create session
    sess = tf.Session(config=config)

    init_op = tf.global_variables_initializer()
    sess.run(init_op)

    all_feed_dict_times = []
    all_inference_times = []

    # Run sess a few times since it is usually slow at the start
    for i in range(5):
        sys.stdout.write('\r{}'.format(i))
        feed_dict = model.create_feed_dict()
        sess.run(prediction_dict, feed_dict)

    for i in range(95):
        sys.stdout.write('\r{}'.format(i + 5))
        feed_dict_start_time = time.time()
        feed_dict = model.create_feed_dict()
        all_feed_dict_times.append(time.time() - feed_dict_start_time)

        inference_start_time = time.time()
        sess.run(prediction_dict, feed_dict)
        all_inference_times.append(time.time() - inference_start_time)

    print('\n')
    print('feed_dict mean', np.mean(all_feed_dict_times))
    print('feed_dict median', np.median(all_feed_dict_times))
    print('feed_dict min', np.min(all_feed_dict_times))
    print('feed_dict max', np.max(all_feed_dict_times))

    print('inference mean', np.mean(all_inference_times))
    print('inference median', np.median(all_inference_times))
    print('inference min', np.min(all_inference_times))
    print('inference max', np.max(all_inference_times))

    # Run once with full timing
    sess.run(prediction_dict,
             feed_dict,
             options=run_options,
             run_metadata=run_metadata)

    inference_start_time = time.time()
    sess.run(prediction_dict, feed_dict)
    print('Time:', time.time() - inference_start_time)

    tf_timeline = timeline.Timeline(run_metadata.step_stats)
    chrome_trace_fmt = tf_timeline.generate_chrome_trace_format()

    outputfile = args.output
    with open(outputfile, 'w') as f:
        f.write(chrome_trace_fmt)

    print('Done')
Ejemplo n.º 22
0
def main():
    """This demo shows RPN proposals and AVOD predictions in the
    3D point cloud.

    Keys:
        F1: Toggle proposals
        F2: Toggle predictions
        F3: Toggle 3D voxel grid
        F4: Toggle point cloud

        F5: Toggle easy ground truth objects (Green)
        F6: Toggle medium ground truth objects (Orange)
        F7: Toggle hard ground truth objects (Red)
        F8: Toggle all ground truth objects (default off)

        F9: Toggle ground slice filter (default off)
        F10: Toggle offset slice filter (default off)
    """

    ##############################
    # Options
    ##############################
    rpn_score_threshold = 0.1
    avod_score_threshold = 0.1

    proposals_line_width = 1.0
    predictions_line_width = 3.0
    show_orientations = True

    point_cloud_source = 'depth'

    # Config file folder, default (<avod_root>/data/outputs/<checkpoint_name>)
    config_dir = None

    checkpoint_name = 'pyramid_cars_with_aug_example'
    global_step = None  # Latest checkpoint
    global_step = 83000

    #data_split = 'val_half'
    data_split = 'val'
    # data_split = 'test'

    # Show 3D iou text
    draw_ious_3d = True

    name_list =[]


    #name_file = '/media/wavelab/d3cd89ab-7705-4996-94f3-01da25ba8f50/moosey/val.txt'

    #with open(name_file) as f:
        #for line in f:
            #newline = line.replace("\n","")
            #name_list.append(newline)


    #name_list =['0000000003','0000000009','0000000016','0000000233','0000000234','0000000236','0000000422','0000000473','0000000490','0000000494','0000000547','0000000655',\
                #'0000000679','0000000690','0000000692','0000000781']
    name_list =['0000000004']

    for names in name_list:

        sample_name = names
        #sample_name = None

        # # # Cars # # #
        # sample_name = '000050'
        # sample_name = '000104'
        # sample_name = '000169'
        # sample_name = '000191'
        # sample_name = '000360'
        # sample_name = '001783'
        # sample_name = '001820'

        # val split
        # sample_name = '000181'
        # sample_name = '000751'
        # sample_name = '000843'
        # sample_name = '000944'
        # sample_name = '006338'

        # # # People # # #
        # val_half split
        # sample_name = '000001'  # Hard, 1 far cyc
        # sample_name = '000005'  # Easy, 1 ped
        # sample_name = '000122'  # Easy, 1 cyc
        # sample_name = '000134'  # Hard, lots of people
        # sample_name = '000167'  # Medium, 1 ped, 2 cycs
        # sample_name = '000187'  # Medium, 1 ped on left
        # sample_name = '000381'  # Easy, 1 ped
        # sample_name = '000398'  # Easy, 1 ped
        # sample_name = '000401'  # Hard, obscured peds
        # sample_name = '000407'  # Easy, 1 ped
        # sample_name = '000448'  # Hard, several far people
        # sample_name = '000486'  # Hard 2 obscured peds
        # sample_name = '000509'  # Easy, 1 ped
        # sample_name = '000718'  # Hard, lots of people
        # sample_name = '002216'  # Easy, 1 cyc

        # val split
        # sample_name = '000015'
        # sample_name = '000048'
        # sample_name = '000058'
        # sample_name = '000076'    # Medium, few ped, 1 cyc
        # sample_name = '000108'
        # sample_name = '000118'
        # sample_name = '000145'
        # sample_name = '000153'
        # sample_name = '000186'
        # sample_name = '000195'
        # sample_name = '000199'
        # sample_name = '000397'
        # sample_name = '004425'
        # sample_name = '004474'    # Hard, many ped, 1 cyc
        # sample_name = '004657'    # Hard, Few cycl, few ped
        # sample_name = '006071'
        # sample_name = '006828'    # Hard, Few cycl, few ped
        # sample_name = '006908'    # Hard, Few cycl, few ped
        # sample_name = '007412'
        # sample_name = '007318'    # Hard, Few cycl, few ped

        ##############################
        # End of Options
        ##############################

        if data_split == 'test':
            draw_ious_3d = False

        if config_dir is None:
            config_dir = avod.root_dir() + '/data/outputs/' + checkpoint_name

        # Parse experiment config
        pipeline_config_file = \
            config_dir + '/' + checkpoint_name + '.config'
        _, _, _, dataset_config = \
            config_builder_util.get_configs_from_pipeline_file(
                pipeline_config_file, is_training=False)

        dataset_config.data_split = data_split

        if data_split == 'test':
            dataset_config.data_split_dir = 'testing'
            dataset_config.has_labels = False

        dataset = DatasetBuilder.build_kitti_dataset(dataset_config,
                                                     use_defaults=False)

        # Random sample
        if sample_name is None:
            sample_idx = np.random.randint(0, dataset.num_samples)
            sample_name = dataset.sample_names[sample_idx]

        ##############################
        # Setup Paths
        ##############################
        img_idx = int(sample_name)

        # Text files directory
        proposals_and_scores_dir = avod.root_dir() + \
            '/data/outputs/' + checkpoint_name + '/predictions' +  \
            '/proposals_and_scores/' + dataset.data_split

        predictions_and_scores_dir = avod.root_dir() + \
            '/data/outputs/' + checkpoint_name + '/predictions' +  \
            '/final_predictions_and_scores/' + dataset.data_split

        # Get checkpoint step
        steps = os.listdir(proposals_and_scores_dir)
        steps.sort(key=int)
        print('Available steps: {}'.format(steps))

        # Use latest checkpoint if no index provided
        if global_step is None:
            global_step = steps[-1]

        # Output images directory
        img_out_dir = avod.root_dir() + '/data/outputs/' + checkpoint_name + \
            '/predictions/images_3d/{}/{}/{}'.format(dataset.data_split,
                                                     global_step,
                                                     rpn_score_threshold)

        if not os.path.exists(img_out_dir):
            os.makedirs(img_out_dir)

        ##############################
        # Proposals
        ##############################
        # Load proposals from files
        proposals_and_scores = np.loadtxt(proposals_and_scores_dir +
                                          "/{}/{}.txt".format(global_step,
                                                              sample_name))

        proposals = proposals_and_scores[:, 0:7]
        proposal_scores = proposals_and_scores[:, 7]

        rpn_score_mask = proposal_scores > rpn_score_threshold

        proposals = proposals[rpn_score_mask]
        proposal_scores = proposal_scores[rpn_score_mask]
        print('Proposals:', len(proposal_scores), proposal_scores)

        proposal_objs = \
            [box_3d_encoder.box_3d_to_object_label(proposal,
                                                   obj_type='Proposal')
             for proposal in proposals]

        ##############################
        # Predictions
        ##############################
        # Load proposals from files
        predictions_and_scores = np.loadtxt(predictions_and_scores_dir +
                                            "/{}/{}.txt".format(
                                                global_step,
                                                sample_name)).reshape(-1, 9)

        prediction_boxes_3d = predictions_and_scores[:, 0:7]
        prediction_scores = predictions_and_scores[:, 7]
        prediction_types = np.asarray(predictions_and_scores[:, 8], dtype=np.int32)

        avod_score_mask = prediction_scores >= avod_score_threshold
        prediction_boxes_3d = prediction_boxes_3d[avod_score_mask]
        prediction_scores = prediction_scores[avod_score_mask]
        print('Predictions: ', len(prediction_scores), prediction_scores)

        final_predictions = np.copy(prediction_boxes_3d)

        # # Swap l, w for predictions where w > l
        # swapped_indices = predictions[:, 4] > predictions[:, 3]
        # final_predictions[swapped_indices, 3] = predictions[swapped_indices, 4]
        # final_predictions[swapped_indices, 4] = predictions[swapped_indices, 3]

        prediction_objs = []
        for pred_idx in range(len(final_predictions)):
            prediction_box_3d = final_predictions[pred_idx]
            prediction_type = dataset.classes[prediction_types[pred_idx]]
            prediction_obj = box_3d_encoder.box_3d_to_object_label(
                prediction_box_3d, obj_type=prediction_type)
            prediction_objs.append(prediction_obj)

        ##############################
        # Ground Truth
        ##############################
        if dataset.has_labels:
            # Get ground truth labels
            easy_gt_objs, medium_gt_objs, \
                hard_gt_objs, all_gt_objs = \
                demo_utils.get_gts_based_on_difficulty(dataset, img_idx)
        else:
            easy_gt_objs = medium_gt_objs = hard_gt_objs = all_gt_objs = []

        ##############################
        # 3D IoU
        ##############################
        if draw_ious_3d:
            # Convert to box_3d
            all_gt_boxes_3d = [box_3d_encoder.object_label_to_box_3d(gt_obj)
                               for gt_obj in all_gt_objs]
            pred_boxes_3d = [box_3d_encoder.object_label_to_box_3d(pred_obj)
                             for pred_obj in prediction_objs]
            max_ious_3d = demo_utils.get_max_ious_3d(all_gt_boxes_3d,
                                                     pred_boxes_3d)

        ##############################
        # Point Cloud
        ##############################
        image_path = dataset.get_rgb_image_path(sample_name)
        image = cv2.imread(image_path)

        print("***************")
        print(point_cloud_source)
        print(img_idx)
        print(image.shape)

        point_cloud = dataset.kitti_utils.get_point_cloud(point_cloud_source,
                                                          img_idx,
                                                          image_shape=image.shape)


        print("This is the shape of the point_cloud")
        print(point_cloud.shape)
        point_cloud = np.asarray(point_cloud)

        # Filter point cloud to extents
        area_extents = np.asarray([[-40, 40], [-5, 3], [0, 70]])
        bev_extents = area_extents[[0, 2]]

        points = point_cloud.T
        point_filter = obj_utils.get_point_filter(point_cloud, area_extents)
        points = points[point_filter]

        point_colours = vis_utils.project_img_to_point_cloud(points,
                                                             image,
                                                             dataset.calib_dir,
                                                             img_idx)

        # Voxelize the point cloud for visualization
        voxel_grid = VoxelGrid()
        voxel_grid.voxelize(points, voxel_size=0.1,
                            create_leaf_layout=False)

        # Ground plane
        ground_plane = obj_utils.get_road_plane(img_idx, dataset.planes_dir)

        ##############################
        # Visualization
        ##############################
        # Create VtkVoxelGrid
        vtk_voxel_grid = VtkVoxelGrid()
        vtk_voxel_grid.set_voxels(voxel_grid)

        vtk_point_cloud = VtkPointCloud()
        vtk_point_cloud.set_points(points, point_colours)

        # Create VtkAxes
        vtk_axes = vtk.vtkAxesActor()
        vtk_axes.SetTotalLength(5, 5, 5)

        # Create VtkBoxes for proposal boxes
        vtk_proposal_boxes = VtkBoxes()
        vtk_proposal_boxes.set_line_width(proposals_line_width)
        vtk_proposal_boxes.set_objects(proposal_objs,
                                       COLOUR_SCHEME_PREDICTIONS)

        # Create VtkBoxes for prediction boxes
        vtk_prediction_boxes = VtkPyramidBoxes()
        vtk_prediction_boxes.set_line_width(predictions_line_width)
        vtk_prediction_boxes.set_objects(prediction_objs,
                                         COLOUR_SCHEME_PREDICTIONS,
                                         show_orientations)

        # Create VtkBoxes for ground truth
        vtk_hard_gt_boxes = VtkBoxes()
        vtk_medium_gt_boxes = VtkBoxes()
        vtk_easy_gt_boxes = VtkBoxes()
        vtk_all_gt_boxes = VtkBoxes()

        vtk_hard_gt_boxes.set_objects(hard_gt_objs, COLOUR_SCHEME_PREDICTIONS,
                                      show_orientations)
        vtk_medium_gt_boxes.set_objects(medium_gt_objs, COLOUR_SCHEME_PREDICTIONS,
                                        show_orientations)
        vtk_easy_gt_boxes.set_objects(easy_gt_objs, COLOUR_SCHEME_PREDICTIONS,
                                      show_orientations)
        vtk_all_gt_boxes.set_objects(all_gt_objs, VtkBoxes.COLOUR_SCHEME_KITTI,
                                     show_orientations)

        # Create VtkTextLabels for 3D ious
        vtk_text_labels = VtkTextLabels()

        if draw_ious_3d and len(all_gt_boxes_3d) > 0:
            gt_positions_3d = np.asarray(all_gt_boxes_3d)[:, 0:3]
            vtk_text_labels.set_text_labels(
                gt_positions_3d,
                ['{:0.3f}'.format(iou_3d) for iou_3d in max_ious_3d])

        # Create VtkGroundPlane
        vtk_ground_plane = VtkGroundPlane()
        vtk_slice_bot_plane = VtkGroundPlane()
        vtk_slice_top_plane = VtkGroundPlane()

        vtk_ground_plane.set_plane(ground_plane, bev_extents)
        vtk_slice_bot_plane.set_plane(ground_plane + [0, 0, 0, -0.2], bev_extents)
        vtk_slice_top_plane.set_plane(ground_plane + [0, 0, 0, -2.0], bev_extents)

        # Create Voxel Grid Renderer in bottom half
        vtk_renderer = vtk.vtkRenderer()
        vtk_renderer.AddActor(vtk_voxel_grid.vtk_actor)
        vtk_renderer.AddActor(vtk_point_cloud.vtk_actor)

        vtk_renderer.AddActor(vtk_proposal_boxes.vtk_actor)
        vtk_renderer.AddActor(vtk_prediction_boxes.vtk_actor)

        vtk_renderer.AddActor(vtk_hard_gt_boxes.vtk_actor)
        vtk_renderer.AddActor(vtk_medium_gt_boxes.vtk_actor)
        vtk_renderer.AddActor(vtk_easy_gt_boxes.vtk_actor)
        vtk_renderer.AddActor(vtk_all_gt_boxes.vtk_actor)

        vtk_renderer.AddActor(vtk_text_labels.vtk_actor)

        # Add ground plane and slice planes
        vtk_renderer.AddActor(vtk_ground_plane.vtk_actor)
        vtk_renderer.AddActor(vtk_slice_bot_plane.vtk_actor)
        vtk_renderer.AddActor(vtk_slice_top_plane.vtk_actor)

        vtk_renderer.AddActor(vtk_axes)
        vtk_renderer.SetBackground(0.2, 0.3, 0.4)

        # Set initial properties for some actors
        vtk_point_cloud.vtk_actor.GetProperty().SetPointSize(3)
        vtk_proposal_boxes.vtk_actor.SetVisibility(0)
        vtk_voxel_grid.vtk_actor.SetVisibility(0)
        vtk_all_gt_boxes.vtk_actor.SetVisibility(0)

        vtk_ground_plane.vtk_actor.SetVisibility(0)
        vtk_slice_bot_plane.vtk_actor.SetVisibility(0)
        vtk_slice_top_plane.vtk_actor.SetVisibility(0)
        vtk_ground_plane.vtk_actor.GetProperty().SetOpacity(0.9)
        vtk_slice_bot_plane.vtk_actor.GetProperty().SetOpacity(0.9)
        vtk_slice_top_plane.vtk_actor.GetProperty().SetOpacity(0.9)

        # Setup Camera
        current_cam = vtk_renderer.GetActiveCamera()
        current_cam.Pitch(140.0)
        current_cam.Roll(180.0)

        # Zooms out to fit all points on screen
        vtk_renderer.ResetCamera()
        # Zoom in slightly
        current_cam.Zoom(2)

        # Reset the clipping range to show all points
        vtk_renderer.ResetCameraClippingRange()

        # Setup Render Window
        vtk_render_window = vtk.vtkRenderWindow()
        vtk_render_window.SetWindowName(
            "Predictions: Step {}, Sample {}, Min Score {}".format(
                global_step,
                sample_name,
                avod_score_threshold,
            ))
        vtk_render_window.SetSize(900, 600)
        vtk_render_window.AddRenderer(vtk_renderer)

        # Setup custom interactor style, which handles mouse and key events
        vtk_render_window_interactor = vtk.vtkRenderWindowInteractor()
        vtk_render_window_interactor.SetRenderWindow(vtk_render_window)

        # Add custom interactor to toggle actor visibilities
        custom_interactor = vis_utils.CameraInfoInteractorStyle([
            vtk_proposal_boxes.vtk_actor,
            vtk_prediction_boxes.vtk_actor,
            vtk_voxel_grid.vtk_actor,
            vtk_point_cloud.vtk_actor,

            vtk_easy_gt_boxes.vtk_actor,
            vtk_medium_gt_boxes.vtk_actor,
            vtk_hard_gt_boxes.vtk_actor,
            vtk_all_gt_boxes.vtk_actor,

            vtk_ground_plane.vtk_actor,
            vtk_slice_bot_plane.vtk_actor,
            vtk_slice_top_plane.vtk_actor,
            vtk_text_labels.vtk_actor,
        ])

        vtk_render_window_interactor.SetInteractorStyle(custom_interactor)
        # Render in VTK
        vtk_render_window.Render()

        # Take a screenshot
        window_to_image_filter = vtk.vtkWindowToImageFilter()
        window_to_image_filter.SetInput(vtk_render_window)
        window_to_image_filter.Update()

        png_writer = vtk.vtkPNGWriter()
        file_name = img_out_dir + "/{}.png".format(sample_name)
        png_writer.SetFileName(file_name)
        png_writer.SetInputData(window_to_image_filter.GetOutput())
        png_writer.Write()

        print('Screenshot saved to ', file_name)

        #vtk_render_window_interactor.Start()  # Blocking


        vtk_render_window_interactor.Initialize()   # Non-Blocking
Ejemplo n.º 23
0
class DatasetBuilder(object):
    """
    Static class to return preconfigured dataset objects
    """

    KITTI_UNITTEST = KittiDatasetConfig(
        name="unittest-kitti",
        dataset_dir=avod.root_dir() + "/tests/datasets/Kitti/object",
        data_split="train",
        data_split_dir="training",
        has_labels=True,
        cluster_split="train",
        classes=["Car", "Pedestrian", "Cyclist"],
        num_clusters=[2, 1, 1],
    )

    KITTI_TRAIN = KittiDatasetConfig(name="kitti",
                                     data_split="train",
                                     data_split_dir="training",
                                     has_labels=True,
                                     cluster_split="train",
                                     classes=["Car"],
                                     num_clusters=[2])

    KITTI_VAL = KittiDatasetConfig(
        name="kitti",
        data_split="val",
        data_split_dir="training",
        has_labels=True,
        cluster_split="train",
        classes=["Car"],
        num_clusters=[2],
    )

    KITTI_TEST = KittiDatasetConfig(
        name="kitti",
        data_split="test",
        data_split_dir="testing",
        has_labels=False,
        cluster_split="train",
        classes=["Car"],
        num_clusters=[2],
    )

    KITTI_TRAINVAL = KittiDatasetConfig(
        name="kitti",
        data_split="trainval",
        data_split_dir="training",
        has_labels=True,
        cluster_split="trainval",
        classes=["Car"],
        num_clusters=[2],
    )

    KITTI_TRAIN_MINI = KittiDatasetConfig(
        name="kitti",
        data_split="train_mini",
        data_split_dir="training",
        has_labels=True,
        cluster_split="train",
        classes=["Car"],
        num_clusters=[2],
    )
    KITTI_VAL_MINI = KittiDatasetConfig(
        name="kitti",
        data_split="val_mini",
        data_split_dir="training",
        has_labels=True,
        cluster_split="train",
        classes=["Car"],
        num_clusters=[2],
    )
    KITTI_TEST_MINI = KittiDatasetConfig(
        name="kitti",
        data_split="test_mini",
        data_split_dir="testing",
        has_labels=False,
        cluster_split="train",
        classes=["Car"],
        num_clusters=[2],
    )

    CONFIG_DEFAULTS_PROTO = \
        """
        bev_source: 'lidar'

        kitti_utils_config {
            area_extents: [-40, 40, -5, 3, 0, 70]
            voxel_size: 0.1
            anchor_strides: [0.5, 0.5, 0.5, 0.5, 0.5, 0.5]

            bev_generator {
                slices {
                    height_lo: -0.2
                    height_hi: 2.3
                    num_slices: 5
                }
            }

            mini_batch_config {
                density_threshold: 1

                rpn_config {
                    iou_2d_thresholds {
                        neg_iou_lo: 0.0
                        neg_iou_hi: 0.3
                        pos_iou_lo: 0.5
                        pos_iou_hi: 1.0
                    }
                    # iou_3d_thresholds {
                    #     neg_iou_lo: 0.0
                    #     neg_iou_hi: 0.005
                    #     pos_iou_lo: 0.1
                    #     pos_iou_hi: 1.0
                    # }

                    mini_batch_size: 512
                }

                avod_config {
                    iou_2d_thresholds {
                        neg_iou_lo: 0.0
                        neg_iou_hi: 0.55
                        pos_iou_lo: 0.65
                        pos_iou_hi: 1.0
                    }

                    mini_batch_size: 1024
                }
            }
        }
        """

    @staticmethod
    def load_dataset_from_config(dataset_config_path):

        dataset_config = kitti_dataset_pb2.KittiDatasetConfig()
        with open(dataset_config_path, 'r') as f:
            text_format.Merge(f.read(), dataset_config)

        return DatasetBuilder.build_kitti_dataset(dataset_config,
                                                  use_defaults=False)

    @staticmethod
    def copy_config(cfg):
        return deepcopy(cfg)

    @staticmethod
    def merge_defaults(cfg):
        cfg_copy = DatasetBuilder.copy_config(cfg)
        text_format.Merge(DatasetBuilder.CONFIG_DEFAULTS_PROTO, cfg_copy)
        return cfg_copy

    @staticmethod
    def build_kitti_dataset(base_cfg,
                            use_defaults=True,
                            new_cfg=None,
                            use_custom_input=False) -> KittiDataset:
        """Builds a KittiDataset object using the provided configurations

        Args:
            base_cfg: a base dataset configuration
            use_defaults: whether to use the default config values
            new_cfg: (optional) a custom dataset configuration, no default
                values will be used, all config values must be provided

        Returns:
            KittiDataset object
        """
        cfg_copy = DatasetBuilder.copy_config(base_cfg)

        if use_defaults:
            # Use default values
            text_format.Merge(DatasetBuilder.CONFIG_DEFAULTS_PROTO, cfg_copy)

        if new_cfg:
            # Use new config values if provided
            cfg_copy.MergeFrom(new_cfg)

        return KittiDataset(cfg_copy, use_custom_input)
def main():
    """This demo shows RPN proposals and AVOD predictions in 3D
    and 2D in image space. Given certain thresholds for proposals
    and predictions, it selects and draws the bounding boxes on
    the image sample. It goes through the entire proposal and
    prediction samples for the given dataset split.

    The proposals, overlaid, and prediction images can be toggled on or off
    separately in the options section.
    The prediction score and IoU with ground truth can be toggled on or off
    as well, shown as (score, IoU) above the detection.
    """
    dataset_config = DatasetBuilder.copy_config(DatasetBuilder.KITTI_VAL)

    ##############################
    # Options
    ##############################
    dataset_config.data_split = 'val'

    fig_size = (10, 6.1)

    rpn_score_threshold = 0.1
    avod_score_threshold = 0.1

    # gt_classes = ['Car']
    gt_classes = ['Pedestrian', 'Cyclist']
    # gt_classes = ['Car', 'Pedestrian', 'Cyclist']

    # Overwrite this to select a specific checkpoint
    global_step = None
    checkpoint_name = sys.argv[1]  #'pyramid_cars_with_aug_example'

    # Drawing Toggles
    draw_proposals_separate = False
    draw_overlaid = False
    draw_predictions_separate = True

    # Show orientation for both GT and proposals/predictions
    draw_orientations_on_prop = False
    draw_orientations_on_pred = False

    # Draw 2D bounding boxes
    draw_projected_2d_boxes = True

    # Save images for samples with no detections
    save_empty_images = True

    draw_score = True
    draw_iou = True
    ##############################
    # End of Options
    ##############################

    # Get the dataset
    dataset = DatasetBuilder.build_kitti_dataset(dataset_config)

    # Setup Paths
    predictions_dir = avod.root_dir() + \
        '/data/outputs/' + checkpoint_name + '/predictions'

    proposals_and_scores_dir = predictions_dir + \
        '/proposals_and_scores/' + dataset.data_split

    predictions_and_scores_dir = predictions_dir + \
        '/final_predictions_and_scores/' + dataset.data_split

    # Output images directories
    output_dir_base = predictions_dir + '/images_2d'

    # Get checkpoint step
    steps = os.listdir(proposals_and_scores_dir)
    steps.sort(key=int)
    print('Available steps: {}'.format(steps))

    # Use latest checkpoint if no index provided
    if global_step is None:
        global_step = steps[-1]

    if draw_proposals_separate:
        prop_out_dir = output_dir_base + '/proposals/{}/{}/{}'.format(
            dataset.data_split, global_step, rpn_score_threshold)

        if not os.path.exists(prop_out_dir):
            os.makedirs(prop_out_dir)

        print('Proposal images saved to:', prop_out_dir)

    if draw_overlaid:
        overlaid_out_dir = output_dir_base + '/overlaid/{}/{}/{}'.format(
            dataset.data_split, global_step, avod_score_threshold)

        if not os.path.exists(overlaid_out_dir):
            os.makedirs(overlaid_out_dir)

        print('Overlaid images saved to:', overlaid_out_dir)

    if draw_predictions_separate:
        pred_out_dir = output_dir_base + '/predictions/{}/{}/{}'.format(
            dataset.data_split, global_step, avod_score_threshold)

        if not os.path.exists(pred_out_dir):
            os.makedirs(pred_out_dir)

        print('Prediction images saved to:', pred_out_dir)

    # Rolling average array of times for time estimation
    avg_time_arr_length = 10
    last_times = np.repeat(time.time(), avg_time_arr_length) + \
        np.arange(avg_time_arr_length)

    for sample_idx in range(dataset.num_samples):
        # Estimate time remaining with 5 slowest times
        start_time = time.time()
        last_times = np.roll(last_times, -1)
        last_times[-1] = start_time
        avg_time = np.mean(np.sort(np.diff(last_times))[-5:])
        samples_remaining = dataset.num_samples - sample_idx
        est_time_left = avg_time * samples_remaining

        # Print progress and time remaining estimate
        sys.stdout.write('\rSaving {} / {}, Avg Time: {:.3f}s, '
                         'Time Remaining: {:.2f}s'.format(
                             sample_idx + 1, dataset.num_samples, avg_time,
                             est_time_left))
        sys.stdout.flush()

        sample_name = dataset.sample_names[sample_idx]
        img_idx = int(sample_name)

        ##############################
        # Proposals
        ##############################
        if draw_proposals_separate or draw_overlaid:
            # Load proposals from files
            proposals_file_path = proposals_and_scores_dir + \
                "/{}/{}.txt".format(global_step, sample_name)
            if not os.path.exists(proposals_file_path):
                print('Sample {}: No proposals, skipping'.format(sample_name))
                continue
            print('Sample {}: Drawing proposals'.format(sample_name))

            proposals_and_scores = np.loadtxt(proposals_file_path)

            proposal_boxes_3d = proposals_and_scores[:, 0:7]
            proposal_scores = proposals_and_scores[:, 7]

            # Apply score mask to proposals
            score_mask = proposal_scores > rpn_score_threshold
            proposal_boxes_3d = proposal_boxes_3d[score_mask]
            proposal_scores = proposal_scores[score_mask]

            proposal_objs = \
                [box_3d_encoder.box_3d_to_object_label(proposal,
                                                       obj_type='Proposal')
                 for proposal in proposal_boxes_3d]

        ##############################
        # Predictions
        ##############################
        if draw_predictions_separate or draw_overlaid:
            predictions_file_path = predictions_and_scores_dir + \
                "/{}/{}.txt".format(global_step,
                                    sample_name)
            if not os.path.exists(predictions_file_path):
                continue

            # Load predictions from files
            predictions_and_scores = np.loadtxt(
                predictions_and_scores_dir +
                "/{}/{}.txt".format(global_step, sample_name))

            prediction_boxes_3d = predictions_and_scores[:, 0:7]
            prediction_scores = predictions_and_scores[:, 7]
            prediction_class_indices = predictions_and_scores[:, 8]

            # process predictions only if we have any predictions left after
            # masking
            if len(prediction_boxes_3d) > 0:

                # Apply score mask
                avod_score_mask = prediction_scores >= avod_score_threshold
                prediction_boxes_3d = prediction_boxes_3d[avod_score_mask]
                prediction_scores = prediction_scores[avod_score_mask]
                prediction_class_indices = \
                    prediction_class_indices[avod_score_mask]

                # # Swap l, w for predictions where w > l
                # swapped_indices = \
                #     prediction_boxes_3d[:, 4] > prediction_boxes_3d[:, 3]
                # prediction_boxes_3d = np.copy(prediction_boxes_3d)
                # prediction_boxes_3d[swapped_indices, 3] = \
                #     prediction_boxes_3d[swapped_indices, 4]
                # prediction_boxes_3d[swapped_indices, 4] = \
                #     prediction_boxes_3d[swapped_indices, 3]

        ##############################
        # Ground Truth
        ##############################

        # Get ground truth labels
        if dataset.has_labels:
            gt_objects = obj_utils.read_labels(dataset.label_dir, img_idx)
        else:
            gt_objects = []

        # Filter objects to desired difficulty
        filtered_gt_objs = dataset.kitti_utils.filter_labels(
            gt_objects, classes=gt_classes)

        boxes2d, _, _ = obj_utils.build_bbs_from_objects(
            filtered_gt_objs, class_needed=gt_classes)

        image_path = dataset.get_rgb_image_path(sample_name)
        image = Image.open(image_path)
        image_size = image.size

        # Read the stereo calibration matrix for visualization
        stereo_calib = calib_utils.read_calibration(dataset.calib_dir, img_idx)
        calib_p2 = stereo_calib.p2

        ##############################
        # Reformat and prepare to draw
        ##############################
        if draw_proposals_separate or draw_overlaid:
            proposals_as_anchors = box_3d_encoder.box_3d_to_anchor(
                proposal_boxes_3d)

            proposal_boxes, _ = anchor_projector.project_to_image_space(
                proposals_as_anchors, calib_p2, image_size)

            num_of_proposals = proposal_boxes_3d.shape[0]

            prop_fig, prop_2d_axes, prop_3d_axes = \
                vis_utils.visualization(dataset.rgb_image_dir,
                                        img_idx,
                                        display=False)

            draw_proposals(filtered_gt_objs, calib_p2, num_of_proposals,
                           proposal_objs, proposal_boxes, prop_2d_axes,
                           prop_3d_axes, draw_orientations_on_prop)

            if draw_proposals_separate:
                # Save just the proposals
                filename = prop_out_dir + '/' + sample_name + '.png'
                plt.savefig(filename)

                if not draw_overlaid:
                    plt.close(prop_fig)

        if draw_overlaid or draw_predictions_separate:
            if len(prediction_boxes_3d) > 0:
                # Project the 3D box predictions to image space
                image_filter = []
                final_boxes_2d = []
                for i in range(len(prediction_boxes_3d)):
                    box_3d = prediction_boxes_3d[i, 0:7]
                    img_box = box_3d_projector.project_to_image_space(
                        box_3d,
                        calib_p2,
                        truncate=True,
                        image_size=image_size,
                        discard_before_truncation=False)
                    if img_box is not None:
                        image_filter.append(True)
                        final_boxes_2d.append(img_box)
                    else:
                        image_filter.append(False)
                final_boxes_2d = np.asarray(final_boxes_2d)
                final_prediction_boxes_3d = prediction_boxes_3d[image_filter]
                final_scores = prediction_scores[image_filter]
                final_class_indices = prediction_class_indices[image_filter]

                num_of_predictions = final_boxes_2d.shape[0]

                # Convert to objs
                final_prediction_objs = \
                    [box_3d_encoder.box_3d_to_object_label(
                        prediction, obj_type='Prediction')
                        for prediction in final_prediction_boxes_3d]
                for (obj, score) in zip(final_prediction_objs, final_scores):
                    obj.score = score
            else:
                if save_empty_images:
                    pred_fig, pred_2d_axes, pred_3d_axes = \
                        vis_utils.visualization(dataset.rgb_image_dir,
                                                img_idx,
                                                display=False,
                                                fig_size=fig_size)
                    filename = pred_out_dir + '/' + sample_name + '.png'
                    plt.savefig(filename)
                    plt.close(pred_fig)
                continue

            if draw_overlaid:
                # Overlay prediction boxes on image
                draw_predictions(filtered_gt_objs, calib_p2,
                                 num_of_predictions, final_prediction_objs,
                                 final_class_indices, final_boxes_2d,
                                 prop_2d_axes, prop_3d_axes, draw_score,
                                 draw_iou, gt_classes,
                                 draw_orientations_on_pred)
                filename = overlaid_out_dir + '/' + sample_name + '.png'
                plt.savefig(filename)

                plt.close(prop_fig)

            if draw_predictions_separate:
                # Now only draw prediction boxes on images
                # on a new figure handler
                if draw_projected_2d_boxes:
                    pred_fig, pred_2d_axes, pred_3d_axes = \
                        vis_utils.visualization(dataset.rgb_image_dir,
                                                img_idx,
                                                display=False,
                                                fig_size=fig_size)

                    draw_predictions(filtered_gt_objs, calib_p2,
                                     num_of_predictions, final_prediction_objs,
                                     final_class_indices, final_boxes_2d,
                                     pred_2d_axes, pred_3d_axes, draw_score,
                                     draw_iou, gt_classes,
                                     draw_orientations_on_pred)
                else:
                    pred_fig, pred_3d_axes = \
                        vis_utils.visualize_single_plot(
                            dataset.rgb_image_dir, img_idx, display=False)

                    draw_3d_predictions(filtered_gt_objs, calib_p2,
                                        num_of_predictions,
                                        final_prediction_objs,
                                        final_class_indices, final_boxes_2d,
                                        pred_3d_axes, draw_score, draw_iou,
                                        gt_classes, draw_orientations_on_pred)
                filename = pred_out_dir + '/' + sample_name + '.png'
                plt.savefig(filename)
                plt.close(pred_fig)

    print('\nDone')
Ejemplo n.º 25
0
def main(_):
    parser = argparse.ArgumentParser()

    # Example usage
    # --checkpoint_name='avod_exp_example'
    # --data_split='test'
    # --ckpt_indices=50 100 112
    # Optional arg:
    # --device=0
    # --additional_cls=False

    parser.add_argument('--checkpoint_name',
                        type=str,
                        dest='checkpoint_name',
                        required=True,
                        help='Checkpoint name must be specified as a str\
                        and must match the experiment config file name.')

    parser.add_argument('--base_dir',
                        type=str,
                        dest='base_dir',
                        required=True,
                        help='Base data directory must be specified')

    parser.add_argument('--ckpt_indices',
                        type=int,
                        nargs='+',
                        dest='ckpt_indices',
                        required=True,
                        help='Checkpoint indices must be a set of \
        integers with space in between -> 0 10 20 etc')

    parser.add_argument('--device',
                        type=str,
                        dest='device',
                        default='0',
                        help='CUDA device id')

    parser.add_argument('--additional_cls',
                        dest='additional_cls',
                        action='store_true',
                        default=False,
                        help='If detections are from an additional class\
                        i.e. another class has already been pre-processed.')

    args = parser.parse_args()
    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(1)

    experiment_config = args.checkpoint_name + '.config'

    # Read the config from the experiment folder
    experiment_config_path = avod.root_dir() + '/data/outputs/' +\
        args.checkpoint_name + '/' + experiment_config

    model_config, _, eval_config, dataset_config = \
        config_builder.get_configs_from_pipeline_file(
            experiment_config_path, is_training=False)

    os.environ['CUDA_VISIBLE_DEVICES'] = args.device
    inference(model_config, eval_config, dataset_config, args.base_dir,
              args.ckpt_indices, args.additional_cls)
Ejemplo n.º 26
0
    def __init__(self, dataset):

        self._dataset = dataset

        self._mini_batch_sampler = \
            balanced_positive_negative_sampler.BalancedPositiveNegativeSampler()

        ##############################
        # Parse KittiUtils config
        ##############################
        self.kitti_utils_config = dataset.config.kitti_utils_config
        self._area_extents = self.kitti_utils_config.area_extents
        self._anchor_strides = np.reshape(
            self.kitti_utils_config.anchor_strides, (-1, 2))

        ##############################
        # Parse MiniBatchUtils config
        ##############################
        self.config = self.kitti_utils_config.mini_batch_config
        self._density_threshold = self.config.density_threshold

        # RPN mini batches
        rpn_config = self.config.rpn_config
        if (rpn_config.ByteSize() != 0):
            rpn_iou_type = rpn_config.WhichOneof('iou_type')
            if rpn_iou_type == 'iou_2d_thresholds':
                self.rpn_iou_type = '2d'
                self.rpn_iou_thresholds = rpn_config.iou_2d_thresholds

            elif rpn_iou_type == 'iou_3d_thresholds':
                self.rpn_iou_type = '3d'
                self.rpn_iou_thresholds = rpn_config.iou_3d_thresholds

            self.rpn_neg_iou_range = [self.rpn_iou_thresholds.neg_iou_lo,
                                      self.rpn_iou_thresholds.neg_iou_hi]
            self.rpn_pos_iou_range = [self.rpn_iou_thresholds.pos_iou_lo,
                                      self.rpn_iou_thresholds.pos_iou_hi]

            self.rpn_mini_batch_size = rpn_config.mini_batch_size

        # AVOD mini batches
        avod_config = self.config.avod_config
        self.avod_iou_type = '2d'
        self.avod_iou_thresholds = avod_config.iou_2d_thresholds

        self.avod_neg_iou_range = [self.avod_iou_thresholds.neg_iou_lo,
                                   self.avod_iou_thresholds.neg_iou_hi]
        self.avod_pos_iou_range = [self.avod_iou_thresholds.pos_iou_lo,
                                   self.avod_iou_thresholds.pos_iou_hi]

        self.avod_mini_batch_size = avod_config.mini_batch_size

        # Setup paths
        if (rpn_config.ByteSize() != 0):
            self.mini_batch_dir = avod.root_dir() + '/data/mini_batches/' + \
                'iou_{}/'.format(self.rpn_iou_type) + \
                dataset.name + '/' + dataset.cluster_split + '/' + \
                dataset.bev_source
        else:
            self.mini_batch_dir = avod.root_dir() + '/data/mini_batches/' + \
                'iou_{}/'.format(self.avod_iou_type) + \
                dataset.name + '/' + dataset.cluster_split + '/' + \
                dataset.bev_source

        # Array column indices for saving to files
        self.col_length = 9
        self.col_anchor_indices = 0
        self.col_ious = 1
        self.col_offsets_lo = 2
        self.col_offsets_hi = 8
        self.col_class_idx = 8
def main(checkpoint_name):
    """This demo shows RPN proposals and AVOD predictions in 3D
    and 2D in image space. Given certain thresholds for proposals
    and predictions, it selects and draws the bounding boxes on
    the image sample. It goes through the entire proposal and
    prediction samples for the given dataset split.

    The proposals, overlaid, and prediction images can be toggled on or off
    separately in the options section.
    The prediction score and IoU with ground truth can be toggled on or off
    as well, shown as (score, IoU) above the detection.
    """

    # checkpoint_name =='pyramid_cars_with_aug_example'
    dataset_config = DatasetBuilder.copy_config(DatasetBuilder.KITTI_VAL)

    ##############################
    # Options
    ##############################
    dataset_config.data_split = 'val'

    fig_size = (10, 6.1)

    rpn_score_threshold = 0.1
    avod_score_threshold = 0.002  #0.1 #0.009 # <== final threshold
    sample_names = [90] + list(range(
        98, 104)) + [138, 224, 270, 290, 310, 330, 520]

    # Convert to string with correct format (don't change)
    sample_names = ['{:06d}'.format(x) for x in sample_names]

    # gt_classes = ['Car']
    gt_classes = ['Pedestrian', 'Cyclist']
    # gt_classes = ['Car', 'Pedestrian', 'Cyclist']

    img_dir = '/home/jhuang/repo/avod/input'

    # Overwrite this to select a specific checkpoint
    global_step = None

    # Drawing Toggles
    draw_proposals_separate = False
    draw_overlaid = False
    draw_predictions_separate = True

    # Show orientation for both GT and proposals/predictions
    draw_orientations_on_prop = False
    draw_orientations_on_pred = False

    # Draw 2D bounding boxes
    draw_projected_2d_boxes = True

    # Save images for samples with no detections
    save_empty_images = True

    draw_score = True
    draw_iou = True
    ##############################
    # End of Options
    ##############################

    # Get the dataset
    dataset = None
    data_split = 'val'

    # Setup Paths
    predictions_dir = avod.root_dir() + \
        '/data/outputs/' + checkpoint_name + '/predictions'

    proposals_and_scores_dir = predictions_dir + \
        '/proposals_and_scores/' + data_split

    predictions_and_scores_dir = predictions_dir + \
        '/final_predictions_and_scores/' + data_split

    # Output images directories
    output_dir_base = predictions_dir + '/images_2d'

    # Get checkpoint step
    steps = os.listdir(proposals_and_scores_dir)
    steps.sort(key=int)
    print('Available steps: {}'.format(steps))

    # Use latest checkpoint if no index provided
    if global_step is None:
        global_step = steps[-1]

    if draw_proposals_separate:
        prop_out_dir = output_dir_base + '/proposals/{}/{}/{}'.format(
            data_split, global_step, rpn_score_threshold)

        if not os.path.exists(prop_out_dir):
            os.makedirs(prop_out_dir)

        print('Proposal images saved to:', prop_out_dir)

    if draw_overlaid:
        overlaid_out_dir = output_dir_base + '/overlaid/{}/{}/{}'.format(
            data_split, global_step, avod_score_threshold)

        if not os.path.exists(overlaid_out_dir):
            os.makedirs(overlaid_out_dir)

        print('Overlaid images saved to:', overlaid_out_dir)

    if draw_predictions_separate:
        pred_out_dir = output_dir_base + '/predictions/{}/{}/{}'.format(
            data_split, global_step, avod_score_threshold)

        if not os.path.exists(pred_out_dir):
            os.makedirs(pred_out_dir)

        print('Prediction images saved to:', pred_out_dir)

    # Rolling average array of times for time estimation
    avg_time_arr_length = 10
    last_times = np.repeat(time.time(), avg_time_arr_length) + \
        np.arange(avg_time_arr_length)

    num_samples = len(sample_names)
    for sample_idx in range(num_samples):
        # Estimate time remaining with 5 slowest times
        start_time = time.time()
        last_times = np.roll(last_times, -1)
        last_times[-1] = start_time
        avg_time = np.mean(np.sort(np.diff(last_times))[-5:])
        samples_remaining = num_samples - sample_idx
        est_time_left = avg_time * samples_remaining

        # Print progress and time remaining estimate
        sys.stdout.write('\rSaving {} / {}, Avg Time: {:.3f}s, '
                         'Time Remaining: {:.2f}s\n'.format(
                             sample_idx + 1, num_samples, avg_time,
                             est_time_left))
        sys.stdout.flush()

        sample_name = sample_names[sample_idx]
        img_idx = int(sample_name)

        ##############################
        # Predictions
        ##############################
        if draw_predictions_separate or draw_overlaid:
            predictions_file_path = predictions_and_scores_dir + \
                "/{}/{}.txt".format(global_step,
                                    sample_name)
            if not os.path.exists(predictions_file_path):
                continue

            # Load predictions from files
            predictions_and_scores = np.loadtxt(
                predictions_and_scores_dir +
                "/{}/{}.txt".format(global_step, sample_name))

            prediction_boxes_3d = predictions_and_scores[:, 0:7]
            prediction_scores = predictions_and_scores[:, 7]
            print("scores=", prediction_scores)
            prediction_class_indices = predictions_and_scores[:, 8]

            # process predictions only if we have any predictions left after
            # masking
            if len(prediction_boxes_3d) > 0:

                # Apply score mask
                avod_score_mask = prediction_scores >= avod_score_threshold
                prediction_boxes_3d = prediction_boxes_3d[avod_score_mask]
                print("len(prediction_boxes_3d)=", len(prediction_boxes_3d))
                prediction_scores = prediction_scores[avod_score_mask]
                prediction_class_indices = \
                    prediction_class_indices[avod_score_mask]

                # # Swap l, w for predictions where w > l
                # swapped_indices = \
                #     prediction_boxes_3d[:, 4] > prediction_boxes_3d[:, 3]
                # prediction_boxes_3d = np.copy(prediction_boxes_3d)
                # prediction_boxes_3d[swapped_indices, 3] = \
                #     prediction_boxes_3d[swapped_indices, 4]
                # prediction_boxes_3d[swapped_indices, 4] = \
                #     prediction_boxes_3d[swapped_indices, 3]

        ##############################
        # Ground Truth
        ##############################

        # Get ground truth labels
        gt_objects = []
        image_path = get_rgb_image_path(img_dir, img_idx, 'img_')
        image = Image.open(image_path)
        image_size = image.size

        # Read the stereo calibration matrix for visualization
        calib_dir = img_dir
        stereo_calib = load_calib(calib_dir, img_idx, 'calib.txt')
        calib_p2 = stereo_calib.p2

        if draw_overlaid or draw_predictions_separate:
            num_of_predictions = 0
            if len(prediction_boxes_3d) > 0:
                # Project the 3D box predictions to image space
                image_filter = []
                final_boxes_2d = []
                for i in range(len(prediction_boxes_3d)):
                    box_3d = prediction_boxes_3d[i, 0:7]
                    img_box = box_3d_projector.project_to_image_space(
                        box_3d,
                        calib_p2,
                        truncate=True,
                        image_size=image_size,
                        discard_before_truncation=False)
                    if img_box is not None:
                        image_filter.append(True)
                        final_boxes_2d.append(img_box)
                    else:
                        image_filter.append(False)
                final_boxes_2d = np.asarray(final_boxes_2d)
                final_prediction_boxes_3d = prediction_boxes_3d[image_filter]
                final_scores = prediction_scores[image_filter]
                final_class_indices = prediction_class_indices[image_filter]

                num_of_predictions = final_boxes_2d.shape[0]

                # Convert to objs
                final_prediction_objs = \
                    [box_3d_encoder.box_3d_to_object_label(
                        prediction, obj_type='Prediction')
                        for prediction in final_prediction_boxes_3d]
                for (obj, score) in zip(final_prediction_objs, final_scores):
                    obj.score = score
            # else:
            #     if save_empty_images:
            #         pred_fig, pred_2d_axes, pred_3d_axes = \
            #             vis_utils.visualization(dataset.rgb_image_dir,
            #                                     img_idx,
            #                                     display=False,
            #                                     fig_size=fig_size)
            #         filename = pred_out_dir + '/' + sample_name + '.png'
            #         plt.savefig(filename)
            #         plt.close(pred_fig)
            #     continue

            if draw_predictions_separate and num_of_predictions > 0:
                # Now only draw prediction boxes on images
                # on a new figure handler
                if draw_projected_2d_boxes:
                    pred_fig, pred_2d_axes, pred_3d_axes = \
                        vis_utils.visualization_jhuang(img_dir,
                                                img_idx, 'img_',
                                                display=False,
                                                fig_size=fig_size)

                    draw_predictions([], calib_p2, num_of_predictions,
                                     final_prediction_objs,
                                     final_class_indices, final_boxes_2d,
                                     pred_2d_axes, pred_3d_axes, draw_score,
                                     draw_iou, gt_classes,
                                     draw_orientations_on_pred)
                else:
                    pred_fig, pred_3d_axes = \
                        vis_utils.visualize_single_plot(
                            dataset.rgb_image_dir, img_idx, display=False)

                    draw_3d_predictions([], calib_p2, num_of_predictions,
                                        final_prediction_objs,
                                        final_class_indices, final_boxes_2d,
                                        pred_3d_axes, draw_score, draw_iou,
                                        gt_classes, draw_orientations_on_pred)
                filename = pred_out_dir + '/' + sample_name + '.png'
                plt.savefig(filename)
                plt.close(pred_fig)

    print('\nDone')
Ejemplo n.º 28
0
    def __init__(self, dataset):

        self._dataset = dataset

        self._mini_batch_sampler = \
            balanced_positive_negative_sampler.BalancedPositiveNegativeSampler()

        ##############################
        # Parse KittiUtils config
        ##############################
        self.kitti_utils_config = dataset.config.kitti_utils_config
        self._area_extents = self.kitti_utils_config.area_extents
        self._anchor_strides = np.reshape(
            self.kitti_utils_config.anchor_strides, (-1, 2))

        ##############################
        # Parse MiniBatchUtils config
        ##############################
        self.config = self.kitti_utils_config.mini_batch_config
        self._density_threshold = self.config.density_threshold

        self.use_retinanet = self.config.use_retinanet
        if not self.use_retinanet:
            # RPN mini batches
            rpn_config = self.config.rpn_config

            rpn_iou_type = rpn_config.WhichOneof('iou_type')
            if rpn_iou_type == 'iou_2d_thresholds':
                self.rpn_iou_type = '2d'
                self.rpn_iou_thresholds = rpn_config.iou_2d_thresholds

            elif rpn_iou_type == 'iou_3d_thresholds':
                self.rpn_iou_type = '3d'
                self.rpn_iou_thresholds = rpn_config.iou_3d_thresholds

            self.rpn_neg_iou_range = [
                self.rpn_iou_thresholds.neg_iou_lo,
                self.rpn_iou_thresholds.neg_iou_hi
            ]
            self.rpn_pos_iou_range = [
                self.rpn_iou_thresholds.pos_iou_lo,
                self.rpn_iou_thresholds.pos_iou_hi
            ]

            self.rpn_mini_batch_size = rpn_config.mini_batch_size

            # AVOD mini batches
            avod_config = self.config.avod_config
            self.avod_iou_type = '2d'
            self.avod_iou_thresholds = avod_config.iou_2d_thresholds

            self.avod_neg_iou_range = [
                self.avod_iou_thresholds.neg_iou_lo,
                self.avod_iou_thresholds.neg_iou_hi
            ]
            self.avod_pos_iou_range = [
                self.avod_iou_thresholds.pos_iou_lo,
                self.avod_iou_thresholds.pos_iou_hi
            ]

            self.avod_mini_batch_size = avod_config.mini_batch_size

            # Setup paths
            self.mini_batch_dir = avod.root_dir() + '/data/mini_batches/' + \
                'iou_{}/'.format(self.rpn_iou_type) + \
                dataset.name + '/' + dataset.cluster_split + '/' + \
                dataset.bev_source

            # Array column indices for saving to files
            self.col_length = 9
            self.col_anchor_indices = 0
            self.col_ious = 1
            self.col_offsets_lo = 2
            self.col_offsets_hi = 8
            self.col_class_idx = 8

        else:
            #use retinanet
            retinanet_config = self.config.retinanet_config
            self.retinanet_pyramid_levels = retinanet_config.pyramid_levels
            self.retinanet_iou_type = retinanet_config.iou_type
            self.retinanet_iou_thresholds = retinanet_config.iou_2d_thresholds
            self.retinanet_neg_iou_range = [
                self.retinanet_iou_thresholds.neg_iou_lo,
                self.retinanet_iou_thresholds.neg_iou_hi
            ]
            self.retinanet_pos_iou_range = [
                self.retinanet_iou_thresholds.pos_iou_lo,
                self.retinanet_iou_thresholds.pos_iou_hi
            ]

            self.mini_batch_dir = avod.root_dir() + '/data/mini_batches/' + \
                    'retinanet/' + 'iou_{}/'.format(self.retinanet_iou_type) + \
                    dataset.name + '/' + dataset.cluster_split
            #[x_bev, y_bev, w_bev, h_bev, angle_bev, h_img, angle_cls]
            #[2:9] is all offset cols.
            self.col_length = 12  #11
            self.col_anchor_indices = 0
            self.col_ious = 1
            self.col_offsets_lo = 2
            self.col_offsets_hi = 10  #9
            self.col_class_idx = 10  #9
            anchor_strides = [2**(int(l[-1])) for l in \
                    self.retinanet_pyramid_levels]
            input_bev_dims_h = retinanet_config.input_bev_dims_h
            input_bev_dims_w = retinanet_config.input_bev_dims_w
            self.retinanet_bev_shape = (input_bev_dims_h, input_bev_dims_w)
            image_shapes = [(int(np.ceil(input_bev_dims_h/s)), int(np.ceil(input_bev_dims_w/s)))\
                    for s in anchor_strides]
            anchor_base_sizes =  [2**(int(l[-1])+2) for l in \
                    self.retinanet_pyramid_levels]
            self.retinanet_anchor_params = {\
                'anchor_strides': np.reshape(anchor_strides, (-1, 1)), \
                  'anchor_base_sizes': anchor_base_sizes, \
                  'anchor_scales': retinanet_config.anchor_scales,\
                  'anchor_ratios': retinanet_config.anchor_ratios,\
                  'anchor_init_ry_type': retinanet_config.anchor_init_ry_type,\
                  'image_shapes': image_shapes, }
Ejemplo n.º 29
0
def main(dataset=None):
    """Generates anchors info which is used for mini batch sampling.

    Processing on 'Cars' can be split into multiple processes, see the Options
    section for configuration.

    Args:
        dataset: KittiDataset (optional)
            If dataset is provided, only generate info for that dataset.
            If no dataset provided, generates info for all 3 classes.
    """

    if dataset is not None:
        do_preprocessing(dataset, None)
        return

    car_dataset_config_path = avod.root_dir() + \
        '/configs/mb_preprocessing/rpn_cars.config'
    ped_dataset_config_path = avod.root_dir() + \
        '/configs/mb_preprocessing/rpn_pedestrians.config'
    cyc_dataset_config_path = avod.root_dir() + \
        '/configs/mb_preprocessing/rpn_cyclists.config'
    ppl_dataset_config_path = avod.root_dir() + \
        '/configs/mb_preprocessing/rpn_people.config'

    ##############################
    # Options
    ##############################
    # Serial vs parallel processing
    in_parallel = True

    process_car = True   # Cars
    process_ped = False  # Pedestrians
    process_cyc = False  # Cyclists
    process_ppl = True   # People (Pedestrians + Cyclists)

    # Number of child processes to fork, samples will
    #  be divided evenly amongst the processes (in_parallel must be True)
    num_car_children = 8
    num_ped_children = 8
    num_cyc_children = 8
    num_ppl_children = 8

    ##############################
    # Dataset setup
    ##############################
    if process_car:
        car_dataset = DatasetBuilder.load_dataset_from_config(
            car_dataset_config_path)
    if process_ped:
        ped_dataset = DatasetBuilder.load_dataset_from_config(
            ped_dataset_config_path)
    if process_cyc:
        cyc_dataset = DatasetBuilder.load_dataset_from_config(
            cyc_dataset_config_path)
    if process_ppl:
        ppl_dataset = DatasetBuilder.load_dataset_from_config(
            ppl_dataset_config_path)

    ##############################
    # Serial Processing
    ##############################
    if not in_parallel:
        if process_car:
            do_preprocessing(car_dataset, None)
        if process_ped:
            do_preprocessing(ped_dataset, None)
        if process_cyc:
            do_preprocessing(cyc_dataset, None)
        if process_ppl:
            do_preprocessing(ppl_dataset, None)

        print('All Done (Serial)')

    ##############################
    # Parallel Processing
    ##############################
    else:

        # List of all child pids to wait on
        all_child_pids = []

        # Cars
        if process_car:
            car_indices_split = split_indices(car_dataset, num_car_children)
            split_work(
                all_child_pids,
                car_dataset,
                car_indices_split,
                num_car_children)

        # Pedestrians
        if process_ped:
            ped_indices_split = split_indices(ped_dataset, num_ped_children)
            split_work(
                all_child_pids,
                ped_dataset,
                ped_indices_split,
                num_ped_children)

        # Cyclists
        if process_cyc:
            cyc_indices_split = split_indices(cyc_dataset, num_cyc_children)
            split_work(
                all_child_pids,
                cyc_dataset,
                cyc_indices_split,
                num_cyc_children)

        # People (Pedestrians + Cyclists)
        if process_ppl:
            ppl_indices_split = split_indices(ppl_dataset, num_ppl_children)
            split_work(
                all_child_pids,
                ppl_dataset,
                ppl_indices_split,
                num_ppl_children)

        # Wait to child processes to finish
        print('num children:', len(all_child_pids))
        for i, child_pid in enumerate(all_child_pids):
            os.waitpid(child_pid, 0)

        print('All Done (Parallel)')
Ejemplo n.º 30
0
            split_work(all_child_pids, ped_dataset, ped_indices_split,
                       num_ped_children)

        # Cyclists
        if process_cyc:
            cyc_indices_split = split_indices(cyc_dataset, num_cyc_children)
            split_work(all_child_pids, cyc_dataset, cyc_indices_split,
                       num_cyc_children)

        # People (Pedestrians + Cyclists)
        if process_ppl:
            ppl_indices_split = split_indices(ppl_dataset, num_ppl_children)
            split_work(all_child_pids, ppl_dataset, ppl_indices_split,
                       num_ppl_children)

        # Wait to child processes to finish
        print('num children:', len(all_child_pids))
        for i, child_pid in enumerate(all_child_pids):
            os.waitpid(child_pid, 0)

        print('All Done (Parallel)')


if __name__ == '__main__':
    # main()
    cars_people_dataset_config_path = avod.root_dir() + \
        '/configs/mb_preprocessing/rpn_cars_people.config'
    cars_people_dataset = DatasetBuilder.load_dataset_from_config(
        cars_people_dataset_config_path)
    do_preprocessing(cars_people_dataset, None)