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 + ' <---')
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 + ' <---')
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 + ' <---')
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)
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.")