Example #1
0
def vehicle_tracker(cf):
    with log_context(cf.log_file):
        logger = logging.getLogger(__name__)
        logger.info(' ---> Init test: ' + cf.test_name + ' <---')

        if cf.save_results:
            logger.info('Saving results in {}'.format(cf.results_path))
            mkdirs(cf.results_path)

        image_list = get_image_list_changedetection_dataset(
            cf.dataset_path, 'in', cf.first_image, cf.image_type, cf.nr_images)

        background_img_list = image_list[:len(image_list) // 2]
        foreground_img_list = image_list[(len(image_list) // 2):]
        mean, variance = background_modeling.multivariative_gaussian_modelling(
            background_img_list, cf.color_space)

        # Instantiate tracker for multi-object tracking
        kalman_init_params = {
            'init_estimate_error': cf.init_estimate_error,
            'motion_model_noise': cf.motion_model_noise,
            'measurement_noise': cf.measurement_noise
        }
        multi_tracker = MultiTracker(cf.cost_of_non_assignment,
                                     cf.invisible_too_long,
                                     cf.min_age_threshold, kalman_init_params)

        for image_path in tqdm(foreground_img_list):

            foreground, mean, variance = background_modeling.adaptive_foreground_estimation_color(
                image_path, mean, variance, cf.alpha, cf.rho, cf.color_space)

            foreground = foreground_improving.hole_filling(
                foreground, cf.four_connectivity)
            foreground = foreground_improving.remove_small_regions(
                foreground, cf.area_filtering_P)
            foreground = foreground_improving.image_opening(
                foreground, cf.opening_strel, cf.opening_strel_size)
            foreground = foreground_improving.image_closing(
                foreground, cf.closing_strel, cf.closing_strel_size)

            image_gray = skio.imread(image_path, as_grey=True)
            bboxes, centroids = detection.detectObjects(image_gray, foreground)

            # Tracking
            multi_tracker.predict_new_locations_of_tracks()
            multi_tracker.detection_to_track_assignment(centroids)
            multi_tracker.update_assigned_tracks(bboxes, centroids)
            multi_tracker.update_unassigned_tracks()
            multi_tracker.delete_lost_tracks()
            multi_tracker.create_new_tracks(bboxes, centroids)

            if cf.save_results:
                image_name = os.path.basename(image_path)
                image_name = os.path.splitext(image_name)[0]
                save_path = os.path.join(
                    cf.results_path, image_name + '.' + cf.result_image_type)
                image = cv.imread(image_path)
                visualization.display_tracking_results(image,
                                                       multi_tracker.tracks,
                                                       foreground, save_path)

        logger.info(' ---> Finish test: ' + cf.test_name + ' <---')
Example #2
0
def visualize_all_tracks(cf):
    with log_context(cf.log_file):
        logger = logging.getLogger(__name__)
        logger.info(' ---> Init test: ' + cf.test_name + ' <---')

        if cf.save_results:
            logger.info('Saving results in {}'.format(cf.results_path))
            mkdirs(cf.results_path)

        image_list = get_image_list_changedetection_dataset(
            cf.dataset_path, 'in', cf.first_image, cf.image_type, cf.nr_images)

        background_img_list = image_list[:len(image_list) // 2]
        foreground_img_list = image_list[(len(image_list) // 2):]
        mean, variance = background_modeling.multivariative_gaussian_modelling(
            background_img_list, cf.color_space)

        # Instantiate tracker for multi-object tracking
        #tracker = Tracker(cf.distance_threshold, cf.max_frames_to_skip, cf.max_trace_length, 0, cf)

        tracks = []  # Create an empty array of tracks.

        nextId = 1  # ID of the next track

        for image_path in foreground_img_list:

            foreground, mean, variance = background_modeling.adaptive_foreground_estimation_color(
                image_path, mean, variance, cf.alpha, cf.rho, cf.color_space)

            foreground = foreground_improving.hole_filling(
                foreground, cf.four_connectivity)
            foreground = foreground_improving.remove_small_regions(
                foreground, cf.area_filtering_P)
            foreground = foreground_improving.image_opening(
                foreground, cf.opening_strel, cf.opening_strel_size)
            foreground = foreground_improving.image_closing(
                foreground, cf.closing_strel, cf.closing_strel_size)

            bboxes, centroids = detection.detectObjects(image_path, foreground)
            multi_tracking.predictNewLocationsOfTracks(tracks)
            assignments, unassignedTracks, unassignedDetections = multi_tracking.detectionToTrackAssignment(
                tracks, centroids, cf.costOfNonAssignment)
            multi_tracking.updateAssignedTracks(tracks, bboxes, centroids,
                                                assignments)
            multi_tracking.updateUnassignedTracks(tracks, unassignedTracks)
            multi_tracking.createNewTracks(tracks, bboxes, centroids,
                                           unassignedDetections)

        img = cv.imread(
            cf.dataset_path +
            '/in000023.jpg')  # in000023 for traffic and in000471 for highway
        if tracks != list():

            # Display the objects. If an object has not been detected
            # in this frame, display its predicted bounding box.
            if tracks != list():
                for track in tracks:
                    car_colour = CAR_COLOURS[track.id % len(CAR_COLOURS)]
                    # for point in track.positions:
                    #    cv.circle(img, (int(point[0]), int(point[1])), 5, car_colour, 1)
                    cv.polylines(img, [np.int32(track.positions)], False,
                                 (0, 0, 0), 1)
                    '''for point in track.predictions:
                        vrtx = np.array([[point[0]-5, point[1]-5], [point[0], point[1]+5], [point[0]+5, point[1]-5]],
                                        np.int32)
                        cv.polylines(img, [vrtx], True, car_colour, 1)
                        # cv.rectangle(img, (int(point[0]) - 2, int(point[1]) - 2),
                        #            (int(point[0]) + 2, int(point[1]) + 2), car_colour, 1)'''
                    cv.polylines(img, [np.int32(track.predictions)], False,
                                 car_colour, 1)

        cv.imwrite(cf.results_path + '/all_tracks.jpg', img)
        logger.info(' ---> Finish test: ' + cf.test_name + ' <---')
Example #3
0
def road_statistics(cf):
    with log_context(cf.log_file):
        logger = logging.getLogger(__name__)
        logger.info(' ---> Init test: ' + cf.test_name + ' <---')

        if cf.save_results:
            logger.info('Saving results in {}'.format(cf.results_path))
            mkdirs(cf.results_path)

        image_list = get_image_list_changedetection_dataset(
            cf.dataset_path, cf.input_prefix, cf.first_image, cf.image_type,
            cf.nr_images)

        background_img_list = get_image_list_changedetection_dataset(
            cf.dataset_path, cf.input_prefix, cf.first_back, cf.image_type,
            cf.nr_back)

        visualization.visualize_lanes(cv.imread(
            background_img_list[0]), cf.lanes, (background_img_list[0].replace(
                'input', 'results').replace(cf.input_prefix, 'lane')))

        visualization.visualize_roi(
            cv.imread(background_img_list[0]), cf.roi_speed,
            (background_img_list[0].replace('input', 'results').replace(
                cf.input_prefix, 'roi')))

        mean, variance = background_modeling.multivariative_gaussian_modelling(
            background_img_list, cf.color_space)

        # Instantiate tracker for multi-object tracking
        kalman_init_params = {
            'init_estimate_error': cf.init_estimate_error,
            'motion_model_noise': cf.motion_model_noise,
            'measurement_noise': cf.measurement_noise
        }
        multi_tracker = MultiTracker(cf.cost_of_non_assignment,
                                     cf.invisible_too_long,
                                     cf.min_age_threshold, kalman_init_params)
        lanes = [Lane() for _ in range(len(cf.lanes))]

        # Tracking folder to save results
        tracking_folder = os.path.join(cf.results_path, 'tracking')
        mkdirs(tracking_folder)

        for n, image_path in tqdm(enumerate(image_list)):
            image = cv.imread(image_path)
            foreground, mean, variance = background_modeling.adaptive_foreground_estimation_color(
                image, mean, variance, cf.alpha, cf.rho, cf.color_space)

            foreground = foreground_improving.hole_filling(
                foreground, cf.four_connectivity)
            foreground = foreground_improving.remove_small_regions(
                foreground, cf.area_filtering_P)
            foreground = foreground_improving.image_opening(
                foreground, cf.opening_strel, cf.opening_strel_size)
            foreground = foreground_improving.image_closing(
                foreground, cf.closing_strel, cf.closing_strel_size)

            image_gray = skio.imread(image_path, as_grey=True)

            bboxes, centroids = detection.detectObjects(image_gray, foreground)

            # Tracking
            multi_tracker.detection_to_track_assignment(centroids)
            multi_tracker.update_assigned_tracks(bboxes, centroids)
            multi_tracker.update_unassigned_tracks()
            multi_tracker.delete_lost_tracks()
            multi_tracker.create_new_tracks(bboxes, centroids)
            multi_tracker.predict_new_locations_of_tracks()

            tracks = multi_tracker.tracks

            if n % cf.update_speed == 0:
                for lane in lanes:
                    lane.current_vehicles = 0

                for track in tracks:
                    if isinstance(cf.pixels_meter, list):
                        if track.lane != -1:
                            pix_meter = cf.pixels_meter[track.lane]
                        else:
                            pix_meter = sum(cf.pixels_meter) / len(
                                cf.pixels_meter)
                    else:
                        pix_meter = cf.pixels_meter
                    if traffic_parameters.is_inside_speed_roi(
                            track.positions[-1], cf.roi_speed):
                        # Compute speed using running average
                        try:
                            run_avg_alpha = cf.speed_estimate_running_avg
                        except AttributeError:
                            run_avg_alpha = 0.2  # Default value
                        traffic_parameters.speed(track,
                                                 pix_meter,
                                                 cf.frames_second,
                                                 dt=cf.update_speed,
                                                 alpha=run_avg_alpha)
                        track.speeds.append(track.current_speed)

                        # Detect and assign lane
                        vehicle_lane = traffic_parameters.lane_detection(
                            track.positions[-1], cf.lanes)
                        if vehicle_lane != -1 and track.lane == -1:
                            track.lane = vehicle_lane
                            lanes[vehicle_lane].total_vehicles += 1

                        # Update speeds of the lane assigned to this track
                        if track.lane != -1 and track.current_speed != 0:
                            # noinspection PyTypeChecker
                            lanes[track.lane].sum_vehicles += 1
                            # noinspection PyTypeChecker
                            lanes[track.
                                  lane].sum_velocities += track.current_speed

                for lane in lanes:
                    if lane.current_vehicles > cf.high_density:
                        lane.density = 'high'
                    else:
                        lane.density = 'low'

            if cf.save_results:
                image_name = os.path.basename(image_path)
                image_name = os.path.splitext(image_name)[0]
                save_path = os.path.join(
                    cf.results_path, image_name + '.' + cf.result_image_type)
                image = image.astype('uint8')
                image_copy = image.copy()
                visualization.display_speed_results(image, tracks,
                                                    cf.max_speed, lanes,
                                                    save_path, cf.roi_speed,
                                                    cf.margin)
                save_path = os.path.join(
                    tracking_folder,
                    image_name + '_tracking.' + cf.result_image_type)
                visualization.display_tracking_results(image_copy, tracks,
                                                       foreground, save_path)
        for n, lane in enumerate(lanes):
            average_velocity = lane.sum_velocities / lane.sum_vehicles

            if n + 1 == 1:
                logger.info(
                    '{}st lane: a total of {} vehicles have passed with an average velocity of {} km/h'
                    .format(n + 1, lane.total_vehicles, average_velocity))
            elif n + 1 == 2:
                logger.info(
                    '{}nd lane: a total of {} vehicles have passed with an average velocity of {} km/h'
                    .format(n + 1, lane.total_vehicles, average_velocity))
            elif n + 1 == 3:
                logger.info(
                    '{}rd lane: a total of {} vehicles have passed with an average velocity of {} km/h'
                    .format(n + 1, lane.total_vehicles, average_velocity))
            else:
                logger.info(
                    '{}th lane: a total of {} vehicles have passed with an average velocity of {} km/h'
                    .format(n + 1, lane.total_vehicles, average_velocity))

        logger.info(' ---> Finish test: ' + cf.test_name + ' <---')
Example #4
0
def foreground_estimation(cf):

    if cf.AUC_area_filtering:
        """ TASK 2 """

        with log_context(cf.log_file):

            # Get a list with input images filenames
            image_list = get_image_list_changedetection_dataset(
                cf.dataset_path, 'in', cf.first_image, cf.image_type, cf.nr_images
            )

            # Get a list with groung truth images filenames
            gt_list = get_image_list_changedetection_dataset(
                cf.gt_path, 'gt', cf.first_image, cf.gt_image_type, cf.nr_images
            )
            background_img_list = image_list[:len(image_list) // 2]
            foreground_img_list = image_list[(len(image_list) // 2):]
            foreground_gt_list = gt_list[(len(image_list) // 2):]

            auc_pr, pixels_range, best_pixels, best_alpha = foreground_improving.area_filtering_auc_vs_pixels(
                cf, background_img_list, foreground_img_list, foreground_gt_list
            )

            visualization.aux_plot_auc_vs_pixels(auc_pr, pixels_range, cf.output_folder)

            # Save auc_pr as a pickle
            auc_pr_path = os.path.join(cf.output_folder, '{}_AUC_vs_pixels.pkl'.format(cf.dataset_name))
            with open(auc_pr_path, 'w') as fd:
                pickle.dump(auc_pr, fd)

            if cf.save_results:
                mkdirs(cf.results_path)
                mean, variance = background_modeling.multivariative_gaussian_modelling(background_img_list,
                                                                                       cf.color_space)
                for (image, gt) in zip(foreground_img_list, foreground_gt_list):
                    foreground, mean, variance = background_modeling.adaptive_foreground_estimation_color(
                        image, mean, variance, best_alpha, cf.rho, cf.color_space
                    )
                    foreground = foreground_improving.hole_filling(foreground, cf.four_connectivity)
                    foreground = foreground_improving.remove_small_regions(foreground, best_pixels)
                    fore = np.array(foreground, dtype='uint8') * 255
                    image_name = os.path.basename(image)
                    image_name = os.path.splitext(image_name)[0]
                    cv.imwrite(
                        os.path.join(cf.results_path, 'task2_' + image_name + '.' + cf.result_image_type),
                        fore)

    else:
        with log_context(cf.log_file):
            logger = logging.getLogger(__name__)

            # Get a list with input images filenames
            image_list = get_image_list_changedetection_dataset(
                cf.dataset_path, 'in', cf.first_image, cf.image_type, cf.nr_images
            )

            # Get a list with groung truth images filenames
            gt_list = get_image_list_changedetection_dataset(
                cf.gt_path, 'gt', cf.first_image, cf.gt_image_type, cf.nr_images
            )
            background_img_list = image_list[:len(image_list) // 2]
            foreground_img_list = image_list[(len(image_list) // 2):]
            foreground_gt_list = gt_list[(len(image_list) // 2):]

            # Task 1
            mean_back, variance_back = background_modeling.multivariative_gaussian_modelling(background_img_list,
                                                                                   cf.color_space)

            alpha_range = np.linspace(cf.evaluate_alpha_range[0], cf.evaluate_alpha_range[1], num=cf.evaluate_alpha_values)

            precision = []
            recall = []
            F1_score = []
            i = 1
            for alpha in alpha_range:

                tp = 0
                fp = 0
                tn = 0
                fn = 0
                mean = np.copy(mean_back)
                variance = np.copy(variance_back)

                for (image, gt) in zip(foreground_img_list, foreground_gt_list):
                    gt_img = cv.imread(gt, cv.IMREAD_GRAYSCALE)
                    foreground, mean, variance = background_modeling.adaptive_foreground_estimation_color(
                        image, mean, variance, alpha, cf.rho, cf.color_space
                    )

                    foreground = foreground_improving.hole_filling(foreground, cf.four_connectivity)

                    if cf.area_filtering:
                        # Area Filtering
                        foreground = foreground_improving.remove_small_regions(foreground, cf.area_filtering_P)

                    if cf.task_name == 'task3':
                        foreground = foreground_improving.image_opening(foreground, cf.opening_strel,
                                                                        cf.opening_strel_size)
                        foreground = foreground_improving.image_closing(foreground, cf.closing_strel,
                                                                        cf.closing_strel_size)

                    if cf.shadow_remove:
                        shadow, highlight = foreground_improving.shadow_detection(cf, mean, image, foreground)
                        foreground = foreground - shadow - highlight

                    foreground = np.array(foreground, dtype='uint8')
                    tp_temp, fp_temp, tn_temp, fn_temp = seg_metrics.evaluate_single_image(foreground,
                                                                                           gt_img)

                    tp += tp_temp
                    fp += fp_temp
                    tn += tn_temp
                    fn += fn_temp

                pre = tp / (tp + fp) if (tp + fp) > 0 else 0.0
                rec = tp / (tp + fn) if (tp + fn) > 0 else 0.0
                f1 = 2 * pre * rec / (pre + rec + EPSILON)

                precision.append(tp / (tp + fp) if (tp + fp) > 0 else 0.0)
                recall.append(tp / (tp + fn) if (tp + fn) > 0 else 0.0)
                F1_score.append(f1)
                logger.info('[{} of {}]\talpha: {}. F1-score {} '.format(i, len(alpha_range), alpha, f1))
                i += 1

            best_f1_score = max(F1_score)
            index_alpha = F1_score.index(best_f1_score)
            best_alpha = alpha_range[index_alpha]
            logger.info('Best alpha: {:.3f}'.format(best_alpha))
            logger.info('Best F1-score: {:.3f}'.format(best_f1_score))
            visualization.plot_metrics_vs_threshold(precision, recall, F1_score, alpha_range,
                                                    cf.output_folder)

            colors = {
                'highway': 'blue',
                'fall': 'green',
                'traffic': 'orange',
            }
            color = colors.get(cf.dataset_name, 'blue')
            auc_pr = visualization.plot_precision_recall_curve(precision, recall, cf.output_folder, color=color)

            logger.info('Best alpha: {:.3f}'.format(best_alpha))
            logger.info('Best F1-score: {:.3f}'.format(best_f1_score))
            logger.info('AUC: {:.3f}'.format(auc_pr))
            if cf.save_results:
                mean = np.copy(mean_back)
                variance = np.copy(variance_back)
                logger.info('Saving results in {}'.format(cf.results_path))
                mkdirs(cf.results_path)
                for image in foreground_img_list:
                    foreground, mean, variance = background_modeling.adaptive_foreground_estimation_color(
                        image, mean, variance, best_alpha, cf.rho, cf.color_space
                    )
                    foreground = foreground_improving.hole_filling(foreground, cf.four_connectivity)

                    if cf.area_filtering:
                        # Area Filtering
                        foreground = foreground_improving.remove_small_regions(foreground, cf.area_filtering_P)

                    if cf.task_name == 'task3':
                        foreground = foreground_improving.image_opening(foreground, cf.opening_strel, cf.opening_strel_size)
                        foreground = foreground_improving.image_closing(foreground, cf.closing_strel, cf.closing_strel_size)


                    image_name = os.path.basename(image)
                    image_name = os.path.splitext(image_name)[0]
                    if cf.shadow_remove:
                        shadow, highlight = foreground_improving.shadow_detection(cf, mean, image, foreground)
                        foreground = foreground - shadow - highlight
                        shadow_comp = np.stack([foreground, shadow, highlight], axis=2)
                        cv.imwrite(os.path.join(cf.results_path, 'rgb_' + image_name + '.' + cf.result_image_type),
                                   shadow_comp * 255)
                        cv.imwrite(os.path.join(cf.results_path, 'shadow_' + image_name + '.' + cf.result_image_type),
                               foreground*255)

                    fore = np.array(foreground, dtype='uint8') * 255
                    cv.imwrite(os.path.join(cf.results_path, image_name + '.' + cf.result_image_type), fore)
Example #5
0
def main():
    log = logging.getLogger("main")
    # Get parameters from arguments
    parser = argparse.ArgumentParser(
        description='W5 - Vehicle tracker and speed estimator [Team 5]')
    parser.add_argument('-c',
                        '--config-path',
                        type=str,
                        required=True,
                        help='Configuration file path')
    parser.add_argument('-t',
                        '--test-name',
                        type=str,
                        required=True,
                        help='Name of the test')

    arguments = parser.parse_args()

    assert arguments.config_path is not None, 'Please provide a configuration' \
                                              'path using -c config/path/name' \
                                              ' in the command line'
    assert arguments.test_name is not None, 'Please provide a name for the ' \
                                            'test using -e test_name in the ' \
                                            'command line'

    # Load the configuration file
    configuration = Configuration(arguments.config_path, arguments.test_name)
    cf = configuration.load()

    log.debug("Creating background subtractor...")

    image_list = get_image_list_changedetection_dataset(
        cf.dataset_path, 'in', cf.first_image, cf.image_type, cf.nr_images)
    background_img_list = image_list[:len(image_list) // 2]
    foreground_img_list = image_list[(len(image_list) // 2):]
    log.debug("Pre-training the background subtractor...")
    mean, variance = background_modeling.multivariative_gaussian_modelling(
        background_img_list, cf.color_space)

    car_counter = None  # Will be created after first frame is captured

    frame_width = cv2.imread(background_img_list[0]).shape[1]
    frame_height = cv2.imread(background_img_list[0]).shape[0]
    log.debug("Video capture frame size=(w=%d, h=%d)", frame_width,
              frame_height)

    log.debug("Starting capture loop...")
    frame_number = -1
    for image_path in foreground_img_list:

        frame_number += 1
        log.debug("Capturing frame #%d...", frame_number)
        frame = cv2.imread(image_path)
        log.debug("Got frame #%d: shape=%s", frame_number, frame.shape)
        foreground, mean, variance = background_modeling.adaptive_foreground_estimation_color(
            image_path, mean, variance, cf.alpha, cf.rho, cf.color_space)

        foreground = foreground_improving.hole_filling(foreground,
                                                       cf.four_connectivity)
        foreground = foreground_improving.remove_small_regions(
            foreground, cf.area_filtering_P)
        foreground = foreground_improving.image_opening(
            foreground, cf.opening_strel, cf.opening_strel_size)
        foreground = foreground_improving.image_closing(
            foreground, cf.closing_strel, cf.closing_strel_size)
        foreground = foreground_improving.remove_small_regions(
            foreground, cf.area_filtering_P_post)

        if car_counter is None:
            # We do this here, so that we can initialize with actual frame size
            log.debug("Creating vehicle counter...")
            car_counter = VehicleCounter(frame.shape[:2], frame.shape[0] / 2)

        # Archive raw frames from video to disk for later inspection/testing
        if CAPTURE_FROM_VIDEO:
            save_frame(IMAGE_FILENAME_FORMAT, frame_number, frame,
                       "source frame #%d")

        log.debug("Processing frame #%d...", frame_number)
        foreground_ = np.array(foreground, dtype=np.uint8)
        processed = process_frame(frame_number, frame, foreground_,
                                  car_counter, cf)

        save_frame(cf.output_folder + "/processed_%04d.png", frame_number,
                   processed, "processed frame #%d")

        cv2.imshow('Source Image', foreground.astype('uint8') * 255)
        cv2.imshow('Processed Image', processed)

        log.debug("Frame #%d processed.", frame_number)

        c = cv2.waitKey(WAIT_TIME)
        if c == 27:
            log.debug("ESC detected, stopping...")
            break

    log.debug("Closing video capture device...")
    cv2.destroyAllWindows()
    log.debug("Done.")