Exemplo n.º 1
0
def run_panoptic_orient_script_with_05_iou(checkpoint_name, score_threshold,
                                           global_step):
    """Runs the panoptic native code script."""

    eval_script_dir = pplp.root_dir() + '/data/outputs/' + \
        checkpoint_name + '/predictions'
    make_script = eval_script_dir + \
        '/panoptic_pplp_eval/run_eval_orient_05_iou.sh'
    script_folder = eval_script_dir + \
        '/panoptic_pplp_eval/'

    results_dir = pplp.top_dir() + '/scripts/offline_eval/results_orient_05_iou/'

    print('--------------- run_panoptic_orient_script_with_05_iou(checkpoint_name, score_threshold, global_step) -----------')
    print('make_script = ', make_script)
    print('script_folder = ', script_folder)
    print('score_threshold = ', score_threshold)
    print('global_step = ', global_step)
    print('checkpoint_name = ', checkpoint_name)
    print('results_dir = ', results_dir)

    # 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)])
Exemplo 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.
    """

    pplp_root_dir = pplp.root_dir()
    kitti_native_code_copy = pplp_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 = pplp.top_dir() + \
            '/scripts/offline_eval/kitti_native_eval/'

        predictions_dir = pplp_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 = pplp.top_dir() + '/scripts/offline_eval/results'
    results_05_dir = pplp.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)
Exemplo n.º 3
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(
            pplp.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))
Exemplo n.º 4
0
def main():
    """Generates anchors info which is used for mini batch sampling.
        This code only generate mini batches for the CMU Panoptic dataset.

    """

    panoptic_dataset_config_path = pplp.root_dir() + \
        '/configs/mb_preprocessing/rpn_panoptic_3d.config'

    ##############################
    # Options
    ##############################
    # Serial vs parallel processing
    in_parallel = False  # Change it back to True  after debugging

    process_ped = True  # Pedestrians , default: False

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

    ##############################
    # Dataset setup
    ##############################

    if process_ped:
        ped_dataset = DatasetBuilder.load_dataset_from_config(
            panoptic_dataset_config_path)

    ##############################
    # Serial Processing
    ##############################
    if not in_parallel:
        if process_ped:
            do_preprocessing(ped_dataset, None)

        print('All Done (Serial)')

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

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

        # 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)

        # 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)')
Exemplo n.º 5
0
    def setUpClass(cls):
        pipeline_config = pipeline_pb2.NetworkPipelineConfig()
        dataset_config = pipeline_config.dataset_config
        config_path = pplp.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)
Exemplo n.º 6
0
    def __init__(self, dataset):

        self._dataset = dataset

        self.cluster_split = dataset.cluster_split

        self.data_dir = pplp.root_dir() + "/data/label_clusters"
        self.clusters = []
        self.std_devs = []
Exemplo n.º 7
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 = pplp.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)
Exemplo n.º 8
0
    def setUp(self):
        tf.test.TestCase.setUp(self)

        test_pipeline_config_path = pplp.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)
Exemplo n.º 9
0
def main(_):
    parser = argparse.ArgumentParser()

    default_pipeline_config_path = pplp.root_dir() + \
        '/configs/orientation_pedestrian_panoptic.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

    # Overwrite eval_config if data_split is 'test'
    if args.data_split.startswith('test'):
        eval_config.eval_mode = 'test'

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

    print('model_config = ', model_config)
    print('eval_config = ', eval_config)
    print('dataset_config = ', dataset_config)
    evaluate(model_config, eval_config, dataset_config)
Exemplo n.º 10
0
def main(_):
    parser = argparse.ArgumentParser()

    # Defaults
    default_pipeline_config_path = pplp.root_dir() + \
        '/configs/avod_pedestrian_panoptic.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')

    args = parser.parse_args()

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

    # 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)
Exemplo n.º 11
0
def run_kitti_native_script(checkpoint_name, score_threshold, global_step):
    """Runs the kitti native code script."""

    eval_script_dir = pplp.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 = pplp.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)
    ])
def main():
    """This demo shows OrientNet predictions on 2D image space.
    Given certain thresholds for predictions, it selects and draws the
    groundtruth bounding boxes on the image sample. It goes through the entire
    prediction samples for the given dataset split.

    """
    dataset_config = DatasetBuilder.copy_config(DatasetBuilder.PANOPTIC_VAL)

    ##############################
    # Options
    ##############################
    dataset_config = DatasetBuilder.merge_defaults(dataset_config)
    dataset_config.data_split = 'val'

    # fig_size = (10, 6.1)
    fig_size = (12, 23)  # The size of final picture as a whole.

    rpn_score_threshold = 0.00
    orientnet_score_threshold = 0.30

    gt_classes = ['Pedestrian']

    # Overwrite this to select a specific checkpoint
    print('!!!Please make sure your settings are all correct!!!!!')
    global_step = 298261  # None
    checkpoint_name = 'orientation_pedestrian_panoptic'

    # Drawing Toggles
    draw_proposals_separate = False
    draw_overlaid = False  # To draw both proposal and predcition bounding boxes
    draw_predictions_separate = True

    # Show orientation for both GT and proposals/predictions
    draw_orientations_on_prop = False  # Set it to false would be OK, since all the orietations of proposals are poiting to the 0 angle.
    draw_orientations_on_pred = True

    # Draw 2D bounding boxes
    draw_projected_2d_boxes = True

    # Draw BEV bounding boxes
    draw_bev_map = False

    # Draw pointclouds
    draw_point_cloud = True
    point_cloud_source = 'lidar'
    slices_config = \
        """
        slices {
            height_lo: -5 # -0.2
            height_hi: 2 # 2.3
            num_slices: 1 # 5
        }
        """

    print('slices_config = ', slices_config)

    text_format.Merge(slices_config,
                      dataset_config.panoptic_utils_config.bev_generator)

    # Save images for samples with no detections
    save_empty_images = False

    draw_proposals_bev = True
    draw_proposals_2d_box = False
    draw_proposals_3d_box = True
    draw_proposals_score = True
    draw_proposals_iou = True

    draw_prediction_score = True
    draw_prediction_iou = True
    ##############################
    # End of Options
    ##############################

    # Get the dataset
    dataset = DatasetBuilder.build_panoptic_dataset(dataset_config,
                                                    use_defaults=False)

    # Setup Paths
    predictions_dir = pplp.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, orientnet_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, orientnet_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 [100]:
    #     print('Hack the number!!!!!')
    for sample_idx in range(dataset.num_samples):
        print('\nStart sample #', sample_idx + 1)
        # 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 \n'.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)
            print('proposals_file_path = ', proposals_file_path)
            if not os.path.exists(proposals_file_path):
                print(proposals_file_path, 'does not exist!')
                print('Sample {}: No proposals, skipping'.format(sample_name))
                continue
            print('Sample {}: Drawing proposals'.format(sample_name))

            proposals_and_scores = np.loadtxt(proposals_file_path)

            # change 1D array in to 2D array even if it has only one row.
            if len(proposals_and_scores.shape) == 1:
                proposals_and_scores.shape = (1, -1)

            # proposals_and_scores, 1~7th colunms are the boxes_3d,
            # the 8th colunm is the score.
            proposal_boxes_3d = proposals_and_scores[:, 0:7]
            proposal_scores = proposals_and_scores[:, 7]

            # Apply score mask to proposals
            print('rpn_score_threshold = ', rpn_score_threshold)
            score_mask = proposal_scores >= rpn_score_threshold
            proposal_boxes_3d = proposal_boxes_3d[score_mask]
            proposal_scores = proposal_scores[score_mask]
            print('There are ', len(proposal_scores), 'proposals left. ')

            proposal_objs = \
                [box_3d_panoptic_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):
                print('predictions_file_path NOT EXIST: ',
                      predictions_file_path)
                continue

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

            # change 1D array in to 2D array even if it has only one row.
            if len(predictions_and_scores.shape) == 1:
                predictions_and_scores.shape = (1, -1)

            # print('predictions_and_scores = ', predictions_and_scores)
            prediction_boxes_3d = predictions_and_scores[:, 0:7]
            prediction_scores = predictions_and_scores[:, 7]
            # print('prediction_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 >= orientnet_score_threshold
                prediction_boxes_3d = prediction_boxes_3d[avod_score_mask]
                print('orientnet_score_threshold = ',
                      orientnet_score_threshold)
                print('There are ', len(prediction_boxes_3d),
                      ' predictions left.')
                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:
            print('dataset.label_dir = ', dataset.label_dir)
            print('img_idx = ', img_idx)
            gt_objects = obj_panoptic_utils.read_labels(
                dataset.label_dir, img_idx)
            # for obj in gt_objects:
            #     print('obj.x1 = ', obj.x1)
        else:
            gt_objects = []

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

        # if sample_idx == 100:
        #     for obj in filtered_gt_objs:
        #         if obj.t[0]>1:
        #             # print('obj.x1 = ', obj.x1)
        #             # print('obj.y1 = ', obj.y1)
        #             # print('obj.x2 = ', obj.x2)
        #             # print('obj.y2 = ', obj.y2)
        #             print('obj.t = ', obj.t)
        #             print('obj.w = ', obj.w)
        #             print('obj.h = ', obj.h)
        #             print('obj.l = ', obj.l)
        #     # print('filtered_gt_objs.x1 = ', filtered_gt_objs.x1)
        #     # print('filtered_gt_objs.x2 = ', filtered_gt_objs.x2)
        #     # print('filtered_gt_objs.y1 = ', filtered_gt_objs.y1)
        #     # print('filtered_gt_objs.y2 = ', filtered_gt_objs.y2)
        boxes2d, _, _ = obj_panoptic_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_panoptic_utils.read_calibration(
            dataset.calib_dir, img_idx)
        calib_p2 = stereo_calib.HD_11
        distortion = stereo_calib.Kd_11
        ##############################
        # Reformat and prepare to draw
        ##############################
        # To get the BEV occupancy map, we need to find the ground plane first.
        panoptic_utils = dataset.panoptic_utils
        ground_plane = panoptic_utils.get_ground_plane(sample_name)
        image_shape = [image.size[1], image.size[0]]
        point_cloud = panoptic_utils.get_point_cloud('lidar', img_idx,
                                                     image_shape)
        bev_maps = panoptic_utils.create_bev_maps(point_cloud, ground_plane)
        bev_img = np.array(
            bev_maps['occupancy_maps'], dtype=np.int
        )  # Remember, the original occupancy grid format is int.
        bev_img = np.resize(
            bev_img, (bev_img.shape[1], bev_img.shape[2]))  # [height, width]
        if not draw_bev_map:
            bev_img = np.zeros((bev_img.shape[1], bev_img.shape[2]),
                               dtype=np.float)
        if draw_proposals_separate or draw_overlaid:
            proposals_as_anchors = box_3d_panoptic_encoder.box_3d_to_anchor(
                proposal_boxes_3d)

            proposal_boxes, _ = anchor_panoptic_projector.project_to_image_space(
                proposals_as_anchors,
                calib_p2,
                image_size,
                distortion=distortion)

            num_of_proposals = proposal_boxes_3d.shape[0]

            prop_fig, prop_bev_axes, prop_2d_axes, prop_3d_axes = \
                vis_panoptic_utils.visualization(dataset.rgb_image_dir,
                                        img_idx,
                                        bev_img,
                                        display=False,
                                        fig_size=fig_size)

            draw_proposals(filtered_gt_objs,
                           calib_p2,
                           num_of_proposals,
                           proposal_objs,
                           proposal_scores,
                           proposal_boxes,
                           prop_2d_axes,
                           prop_3d_axes,
                           prop_bev_axes,
                           panoptic_utils.area_extents,
                           bev_img.shape,
                           draw_proposals_bev,
                           draw_proposals_2d_box,
                           draw_proposals_3d_box,
                           draw_proposals_score,
                           draw_proposals_iou,
                           draw_orientations_on_prop,
                           distortion=distortion)
            if draw_point_cloud:
                # First,get pointclouds. Now pointclouds are in camera coordinates.
                panoptic_utils = dataset.panoptic_utils
                image_shape = [image_size[1], image_size[0]]
                point_cloud = panoptic_utils.get_point_cloud(
                    point_cloud_source, img_idx, image_shape)
                # print('point_cloud =', point_cloud)
                # Now point_cloud is a 4XN array, in Lidar frame, but only
                # includes those points that can be seen on the image

                # Filter the useful pointclouds from all points
                # In order to do that, we need to find the ground plane first.
                ground_plane = panoptic_utils.get_ground_plane(sample_name)
                filtered_points = panoptic_utils.filter_bev_points(
                    point_cloud, ground_plane)
                # if len(filtered_points) > 0:
                #     print('point_cloud =', point_cloud)
                #     print('filtered_points =', filtered_points)

                # Now, filtered_points is transposed, so filtered_points should
                # be Nx4

                # Project the filtered pointclouds on 2D image. Now filtered
                # pointclouds are already in camera coordinates.
                point_2d = obj_panoptic_utils.project_points_on_2D_image(
                    img_idx, dataset.calib_dir, image_size, filtered_points)
                draw_points(prop_2d_axes, point_2d, 'red', pt_size=4)

                # TODO: Project the filtered pointclouds on BEV image. Now filtered
                # pointclouds are already in camera coordinates.
                # point_bev = obj_panoptic_utils.project_points_on_BEV_image(img_idx,
                #                                                 dataset.calib_dir,
                #                                                 image_size,
                #                                                 filtered_points)
                # draw_points(prop_bev_axes, point_bev, 'red', pt_size=4)

            if draw_proposals_separate:
                # Save just the proposals
                filename = prop_out_dir + '/' + sample_name + '.jpg'
                print('Draw proposals_separate: ', filename)
                # Now add the legends
                # prop_bev_axes.legend(loc='best', shadow=True, fontsize=20)
                # prop_2d_axes.legend(loc='best', shadow=True, fontsize=20)
                # prop_3d_axes.legend(loc='upper right', shadow=True, fontsize=20)
                plt.savefig(filename)

                if not draw_overlaid:
                    plt.close(prop_fig)

        if draw_overlaid or draw_predictions_separate:
            # print('prediction_boxes_3d = ', prediction_boxes_3d)
            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_panoptic_projector.project_to_image_space(
                        box_3d,
                        calib_p2,
                        truncate=True,
                        image_size=image_size,
                        discard_before_truncation=False,
                        distortion=distortion)
                    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_panoptic_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_bev_axes, pred_2d_axes, pred_3d_axes = \
                        vis_panoptic_utils.visualization(dataset.rgb_image_dir,
                                                         img_idx,
                                                         display=False,
                                                         fig_size=fig_size)
                    filename = pred_out_dir + '/' + sample_name + '.jpg'
                    plt.savefig(filename)
                    print('Draw empty_images: ', 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,
                                 prop_bev_axes,
                                 panoptic_utils.area_extents,
                                 bev_img.shape,
                                 draw_prediction_score,
                                 draw_prediction_iou,
                                 gt_classes,
                                 draw_orientations_on_pred,
                                 distortion=distortion)
                filename = overlaid_out_dir + '/' + sample_name + '.jpg'
                # Now add the legends
                # prop_bev_axes.legend(loc='best', shadow=True, fontsize=20)
                # prop_2d_axes.legend(loc='best', shadow=True, fontsize=20)
                # prop_3d_axes.legend(loc='upper right', shadow=True, fontsize=20)
                plt.savefig(filename)
                print('Draw overlaid: ', 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_bev_axes, pred_2d_axes, pred_3d_axes = \
                        vis_panoptic_utils.visualization(dataset.rgb_image_dir,
                                                         img_idx,
                                                         bev_img,
                                                         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,
                                     pred_bev_axes,
                                     panoptic_utils.area_extents,
                                     bev_img.shape,
                                     draw_prediction_score,
                                     draw_prediction_iou,
                                     gt_classes,
                                     draw_orientations_on_pred,
                                     distortion=distortion)
                    # Now add the legends
                    # pred_bev_axes.legend(loc='best', shadow=True, fontsize=20)
                    # pred_2d_axes.legend(loc='best', shadow=True, fontsize=20)
                    # pred_3d_axes.legend(loc='best', shadow=True, fontsize=20)
                else:
                    pred_fig, pred_3d_axes = \
                        vis_panoptic_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_prediction_score,
                                        draw_prediction_iou,
                                        gt_classes,
                                        draw_orientations_on_pred,
                                        distortion=distortion)
                    # Now add the legends
                    # pred_3d_axes.legend(loc='upper right', shadow=True, fontsize=20)
                filename = pred_out_dir + '/' + sample_name + '.jpg'
                plt.savefig(filename)
                print('Draw predictions_separate: ', filename)
                plt.close(pred_fig)

    print('\nDone')
Exemplo n.º 13
0
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 = DatasetBuilder.merge_defaults(dataset_config)
    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']
    # gt_classes = ['Pedestrian', 'Cyclist']

    # Overwrite this to select a specific checkpoint
    global_step = 115000  # None
    checkpoint_name = 'pplp_pedestrian_kitti'

    # Drawing Toggles
    draw_proposals_separate = False
    draw_overlaid = True  # To draw both proposal and predcition bounding boxes
    draw_predictions_separate = False

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

    # Draw 2D bounding boxes
    draw_projected_2d_boxes = True

    # Draw pointclouds
    draw_point_cloud = True
    point_cloud_source = 'lidar'
    slices_config = \
        """
        slices {
            height_lo: -1.0 # -0.2
            height_hi: 2 # 2.3
            num_slices: 1 # 5
        }
        """

    print('slices_config = ', slices_config)

    text_format.Merge(slices_config,
                      dataset_config.kitti_utils_config.bev_generator)

    # Save images for samples with no detections
    save_empty_images = False

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

    # Get the dataset
    dataset = DatasetBuilder.build_kitti_dataset(dataset_config,
                                                 use_defaults=False)

    # Setup Paths
    predictions_dir = pplp.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):
    for sample_idx in [6]:
        # 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_point_cloud:
                # Filter the useful pointclouds from all points
                kitti_utils = dataset.kitti_utils
                x, y, z, i = calib_utils.read_lidar(dataset.velo_dir, img_idx)
                point_cloud = np.vstack((x, y, z))
                # pts = calib_utils.lidar_to_cam_frame(pts, frame_calib)
                # point_cloud = kitti_utils.get_point_cloud(
                #     point_cloud_source, img_idx, image_size)
                point_cloud = kitti_utils.get_point_cloud(
                    point_cloud_source, img_idx, image_size)
                print('point_cloud = ', point_cloud)
                ground_plane = kitti_utils.get_ground_plane(sample_name)
                all_points = np.transpose(point_cloud)
                # print('dataset_config.kitti_utils_config.bev_generator.\
                # slices.height_lo = ', dataset_config.kitti_utils_config.bev_generator.slices.height_lo)
                height_lo = dataset_config.kitti_utils_config.bev_generator.slices.height_lo
                height_hi = dataset_config.kitti_utils_config.bev_generator.slices.height_hi

                # config = dataset.config.kitti_utils_config
                # print('config = ', config)
                area_extents = [[0., 70.], [-40, 40], [-1.1, -1]]
                # ?,x,?
                area_extents = np.reshape(area_extents, (3, 2))
                print('area_extents = ', area_extents)
                print('ground_plane = ', ground_plane)
                slice_filter = get_point_filter(point_cloud,
                                                area_extents,
                                                ground_plane=None,
                                                offset_dist=2.0)

                # slice_filter = kitti_utils.create_slice_filter(
                #     point_cloud,
                #     area_extents,
                #     ground_plane,
                #     height_lo,
                #     height_hi)
                # Apply slice filter
                slice_points = all_points[slice_filter]
                print('slice_points = ', slice_points)
                # print('slice_points =', slice_points)
                # Project the useful pointclouds on 2D image
                point_2d = obj_utils.get_lidar_points_on_2D_image(
                    img_idx, dataset.calib_dir, dataset.velo_dir, image_size,
                    True, slice_points)
                draw_points(prop_2d_axes, point_2d, 'red')

            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')
Exemplo n.º 14
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()
    print('pipeline_config = ', pipeline_config)
    with open(pipeline_config_path, 'r') as f:
        text_format.Merge(f.read(), pipeline_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:
        print('checkpoint_name =', checkpoint_name)
        print('config_file_name =', config_file_name)
        raise ValueError('Config and checkpoint names must match.')

    output_root_dir = pplp.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
Exemplo n.º 15
0
def save_predictions_in_panoptic_format(model,
                                     checkpoint_name,
                                     data_split,
                                     score_threshold,
                                     global_step):
    """ Converts a set of network predictions into text files required for
    PANOPTIC 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 = pplp.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
    panoptic_predictions_3d_dir = predictions_root_dir + \
        '/panoptic_pplp_eval/' + \
        str(score_threshold) + '/' + \
        str(global_step) + '/data'

    if not os.path.exists(panoptic_predictions_3d_dir):
        os.makedirs(panoptic_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:', panoptic_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'

        panoptic_predictions_3d_file_path = panoptic_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(panoptic_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]

        all_predictions = np.array(all_predictions)

        # change 1D array in to 2D array even if it has only one row.
        if len(all_predictions.shape) == 1:
            all_predictions.shape = (1, -1)

        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(panoptic_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_panoptic_utils.read_calibration(dataset.calib_dir,
                                                       img_idx).HD_11

        boxes = []
        image_filter = []
        for i in range(len(all_predictions)):
            box_3d = all_predictions[i, 0:7]
            img_box = box_3d_panoptic_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)
                print('**ERROR img_box = ', img_box)
                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(panoptic_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
        panoptic_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)
        panoptic_predictions[:, 3] = -10 * np.ones((len(panoptic_predictions)),
                                                dtype=np.int32)

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

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

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

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

        # Stack 3D predictions text
        panoptic_text_3d = np.column_stack([obj_types,
                                         panoptic_empty_1,
                                         panoptic_predictions[:, 3:16]])

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

    print('\nNum valid:', num_valid_samples)
    print('Num samples:', num_samples)
Exemplo n.º 16
0
def main():
    """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.
    """

    kitti_dataset_config_path = pplp.root_dir() + \
        '/configs/mb_preprocessing/rpn_pedestrians.config'

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

    process_ped = True

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

    ##############################
    # Dataset setup
    ##############################

    if process_ped:
        ped_dataset = DatasetBuilder.load_dataset_from_config(
            kitti_dataset_config_path)

    ##############################
    # Serial Processing
    ##############################
    if not in_parallel:
        if process_ped:
            do_preprocessing(ped_dataset, None)

        print('All Done (Serial)')

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

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

        # 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)

        # 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)')
Exemplo n.º 17
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

        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 = pplp.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
Exemplo n.º 18
0
class DatasetBuilder(object):
    """
    Static class to return preconfigured dataset objects
    """

    PANOPTIC_UNITTEST = PanopticDatasetConfig(
        name="unittest-panoptic",
        dataset_dir=pplp.root_dir() + "/tests/datasets/Panoptic/object",
        data_split="train",
        data_split_dir="training",
        has_labels=True,
        cluster_split="train",
        classes=["Pedestrian"],
        num_clusters=[1],
    )

    PANOPTIC_TRAIN = PanopticDatasetConfig(name="panoptic",
                                           data_split="train",
                                           data_split_dir="training",
                                           has_labels=True,
                                           cluster_split="train",
                                           classes=["Pedestrian"],
                                           num_clusters=[1])

    PANOPTIC_VAL = PanopticDatasetConfig(
        name="panoptic",
        data_split="val",
        data_split_dir="training",
        has_labels=True,
        cluster_split="train",
        classes=["Pedestrian"],
        num_clusters=[1],
    )

    PANOPTIC_TEST = PanopticDatasetConfig(
        name="panoptic",
        data_split="test",
        data_split_dir="testing",
        has_labels=False,
        cluster_split="train",
        classes=["Pedestrian"],
        num_clusters=[1],
    )

    PANOPTIC_TRAINVAL = PanopticDatasetConfig(
        name="panoptic",
        data_split="trainval",
        data_split_dir="training",
        has_labels=True,
        cluster_split="trainval",
        classes=["Pedestrian"],
        num_clusters=[1],
    )

    PANOPTIC_TRAIN_MINI = PanopticDatasetConfig(
        name="panoptic",
        data_split="train_mini",
        data_split_dir="training",
        has_labels=True,
        cluster_split="train",
        classes=["Pedestrian"],
        num_clusters=[1],
    )
    PANOPTIC_VAL_MINI = PanopticDatasetConfig(
        name="panoptic",
        data_split="val_mini",
        data_split_dir="training",
        has_labels=True,
        cluster_split="train",
        classes=["Pedestrian"],
        num_clusters=[1],
    )
    PANOPTIC_TEST_MINI = PanopticDatasetConfig(
        name="panoptic",
        data_split="test_mini",
        data_split_dir="testing",
        has_labels=False,
        cluster_split="train",
        classes=["Pedestrian"],
        num_clusters=[1],
    )

    CONFIG_DEFAULTS_PROTO = \
        """
        bev_source: 'lidar'

        panoptic_utils_config {
            area_extents: [-4, 4, -5, 3, 0, 7]
            voxel_size: 0.01
            anchor_strides: [0.5, 0.5]

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

            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 = panoptic_dataset_pb2.PanopticDatasetConfig()
        with open(dataset_config_path, 'r') as f:
            text_format.Merge(f.read(), dataset_config)

        return DatasetBuilder.build_panoptic_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_panoptic_dataset(base_cfg,
                               use_defaults=True,
                               new_cfg=None) -> PanopticDataset:
        """Builds a PanopticDataset 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:
            PanopticDataset 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 PanopticDataset(cfg_copy)