def load_prediction(result_path: str, max_boxes_per_sample: int, box_cls, verbose: bool = False) \ -> Tuple[EvalBoxes, Dict]: """ Loads object predictions from file. :param result_path: Path to the .json result file provided by the user. :param max_boxes_per_sample: Maximim number of boxes allowed per sample. :param box_cls: Type of box to load, e.g. DetectionBox or TrackingBox. :param verbose: Whether to print messages to stdout. :return: The deserialized results and meta data. """ # Load from file and check that the format is correct. with open(result_path) as f: data = json.load(f) assert 'results' in data, 'Error: No field `results` in result file. Please note that the result format changed.' \ 'See https://www.nuscenes.org/object-detection for more information.' # Deserialize results and get meta data. all_results = EvalBoxes.deserialize(data['results'], box_cls) meta = data['meta'] print('!' * 500) print(all_results.sample_tokens) if verbose: print("Loaded results from {}. Found detections for {} samples.". format(result_path, len(all_results.sample_tokens)) + '%' * 300) # Check that each sample has no more than x predicted boxes. for sample_token in all_results.sample_tokens: assert len(all_results.boxes[sample_token]) <= max_boxes_per_sample, \ "Error: Only <= %d boxes per sample allowed!" % max_boxes_per_sample return all_results, meta
def test_serialization(self): """ Test that instance serialization protocol works with json encoding. """ boxes = EvalBoxes() for i in range(10): boxes.add_boxes(str(i), [DetectionBox(), DetectionBox(), DetectionBox()]) recovered = EvalBoxes.deserialize( json.loads(json.dumps(boxes.serialize())), DetectionBox) self.assertEqual(boxes, recovered)
def load_groundtruth(groundtruth_path: str, box_cls = DetectionBox, verbose: bool = False) \ -> EvalBoxes: """ Loads object GT boxes from file. :param groundtruth_path: Path to the .json GT file provided by the user. :param box_cls: Type of box to load, e.g. DetectionBox or TrackingBox. :param verbose: Whether to print messages to stdout. :return: The deserialized results and meta data. """ # Load from file and check that the format is correct. with open(groundtruth_path) as f: data = json.load(f) assert 'GT_boxes' in data, 'Error: No field `GT_boxes` in ground truth file.' # Deserialize results and get meta data. all_results = EvalBoxes.deserialize(data['GT_boxes'], box_cls) if verbose: print("Loaded GT from {}. Found detections for {} samples.".format( groundtruth_path, len(all_results.sample_tokens))) return all_results
def main(): # test pmbm tracking in val split of NuScenes detection_file = '/home/mqdao/Downloads/nuScene/detection-megvii/megvii_val.json' data_root = '/home/mqdao/Downloads/nuScene/v1.0-trainval' version = 'v1.0-trainval' nusc = NuScenes(version=version, dataroot=data_root, verbose=True) # load detection with open(detection_file) as f: data = json.load(f) all_results = EvalBoxes.deserialize(data['results'], DetectionBox) meta = data['meta'] print('meta: ', meta) print("Loaded results from {}. Found detections for {} samples.".format( detection_file, len(all_results.sample_tokens))) # to filter detection all_score_theshold = [0.35, 0.3, 0.25, 0.2] # init tracking results tracking_results = {} processed_scene_tokens = set() for sample_token_idx in tqdm(range(len(all_results.sample_tokens))): sample_token = all_results.sample_tokens[sample_token_idx] scene_token = nusc.get('sample', sample_token)['scene_token'] if scene_token in processed_scene_tokens: continue # initialize filter config = FilterConfig(state_dim=6, measurement_dim=3) density = get_gaussian_density_NuScenes_CV() pmbm_filter = PoissonMultiBernoulliMixture(config, density) current_sample_token = nusc.get('scene', scene_token)['first_sample_token'] current_time_step = 0 while current_sample_token != '': # filter detections with low detection score sample_record = nusc.get('sample', current_sample_token) gt_num_objects = len(sample_record['anns']) filtered_detections = [] i_threshold = 0 while len(filtered_detections ) < gt_num_objects and i_threshold < len( all_score_theshold): filtered_detections = [ detection for detection in all_results.boxes[current_sample_token] if detection.detection_score >= all_score_theshold[i_threshold] ] i_threshold += 1 # create measurement for pmbm filter measurements = [] for detection in filtered_detections: # get obj_type if detection.detection_name not in NUSCENES_TRACKING_NAMES: continue obj_type = detection.detection_name # get object pose x, y, z = detection.translation quaternion = Quaternion(detection.rotation) yaw = quaternion.angle if quaternion.axis[ 2] > 0 else -quaternion.angle # get object size size = list(detection.size) # get detection score score = detection.detection_score # create object detection obj_det = ObjectDetection(z=np.array([x, y, yaw]).reshape(3, 1), size=size, obj_type=obj_type, height=z, score=score, empty_constructor=False) measurements.append(obj_det) # print('Time {} - Number of measurements: {}'.format(current_time_step, len(measurements))) # initialize tracking results for this sample tracking_results[current_sample_token] = [] # invoke filter and extract estimation if len(measurements) > 0: estimation = pmbm_filter.run(measurements) # log estimation for target_id, target_est in estimation.items(): sample_result = format_result( current_sample_token, target_est['translation'] + [target_est['height']], target_est['size'], target_est['orientation'], target_est['velocity'], target_id, target_est['class'], target_est['score']) tracking_results[current_sample_token].append( sample_result) # move on current_sample_token = sample_record['next'] current_time_step += 1 processed_scene_tokens.add(scene_token) # save tracking result output_data = {'meta': meta, 'results': tracking_results} with open( './estimation-result/all-results-validataion-set-{}.json'.format( datetime.now().strftime("%Y%m%d-%H%M%S")), 'w') as outfile: json.dump(output_data, outfile)
def track_nuscenes(data_root: str, detection_file: str, save_dir: str, eval_set: str = 'val', covariance_id: int = 0, match_distance: str = 'iou', match_threshold: float = 0.1, match_algorithm: str = 'h', use_angular_velocity: bool = False): ''' submission { "meta": { "use_camera": <bool> -- Whether this submission uses camera data as an input. "use_lidar": <bool> -- Whether this submission uses lidar data as an input. "use_radar": <bool> -- Whether this submission uses radar data as an input. "use_map": <bool> -- Whether this submission uses map data as an input. "use_external": <bool> -- Whether this submission uses external data as an input. }, "results": { sample_token <str>: List[sample_result] -- Maps each sample_token to a list of sample_results. } } ''' if 'train' in eval_set: version = 'v1.0-trainval' elif 'val' in eval_set: version = 'v1.0-trainval' elif 'mini' in eval_set: version = 'v1.0-mini' elif 'test' in eval_set: version = 'v1.0-test' else: version = eval_set print("WARNING: Unknown subset version: '{}'".format(version)) nusc = NuScenes(version=version, dataroot=data_root, verbose=True) mkdir_if_missing(save_dir) output_path = os.path.join(save_dir, 'probabilistic_tracking_results.json') results = {} total_time = 0.0 total_frames = 0 with open(detection_file) as f: data = json.load(f) assert 'results' in data, 'Error: No field `results` in result file. Please note that the result format changed.' \ 'See https://www.nuscenes.org/object-detection for more information.' all_results = EvalBoxes.deserialize(data['results'], DetectionBox) meta = data['meta'] print('meta: ', meta) print("Loaded results from {}. Found detections for {} samples.".format( detection_file, len(all_results.sample_tokens))) processed_scene_tokens = set() for sample_token_idx in tqdm(range(len(all_results.sample_tokens))): sample_token = all_results.sample_tokens[sample_token_idx] scene_token = nusc.get('sample', sample_token)['scene_token'] if scene_token in processed_scene_tokens: continue first_sample_token = nusc.get('scene', scene_token)['first_sample_token'] current_sample_token = first_sample_token mot_trackers = { tracking_name: AB3DMOT(covariance_id, tracking_name=tracking_name, use_angular_velocity=use_angular_velocity, tracking_nuscenes=True) for tracking_name in NUSCENES_TRACKING_NAMES } while current_sample_token != '': results[current_sample_token] = [] dets = { tracking_name: [] for tracking_name in NUSCENES_TRACKING_NAMES } info = { tracking_name: [] for tracking_name in NUSCENES_TRACKING_NAMES } for box in all_results.boxes[current_sample_token]: if box.detection_name not in NUSCENES_TRACKING_NAMES: continue q = Quaternion(box.rotation) angle = q.angle if q.axis[2] > 0 else -q.angle #print('box.rotation, angle, axis: ', box.rotation, q.angle, q.axis) #print('box.rotation, angle, axis: ', q.angle, q.axis) #[h, w, l, x, y, z, rot_y] detection = np.array([ box.size[2], box.size[0], box.size[1], box.translation[0], box.translation[1], box.translation[2], angle ]) #print('detection: ', detection) information = np.array([box.detection_score]) dets[box.detection_name].append(detection) info[box.detection_name].append(information) dets_all = { tracking_name: { 'dets': np.array(dets[tracking_name]), 'info': np.array(info[tracking_name]) } for tracking_name in NUSCENES_TRACKING_NAMES } total_frames += 1 start_time = time.time() for tracking_name in NUSCENES_TRACKING_NAMES: if dets_all[tracking_name]['dets'].shape[0] > 0: trackers = mot_trackers[tracking_name].update( dets_all[tracking_name], match_distance, match_threshold, match_algorithm, scene_token) # (N, 9) # (h, w, l, x, y, z, rot_y), tracking_id, tracking_score # print('trackers: ', trackers) for i in range(trackers.shape[0]): sample_result = format_sample_result( current_sample_token, tracking_name, trackers[i]) results[current_sample_token].append(sample_result) cycle_time = time.time() - start_time total_time += cycle_time # get next frame and continue the while loop current_sample_token = nusc.get('sample', current_sample_token)['next'] # left while loop and mark this scene as processed processed_scene_tokens.add(scene_token) # finished tracking all scenes, write output data output_data = {'meta': meta, 'results': results} with open(output_path, 'w') as outfile: json.dump(output_data, outfile) print("Total Tracking took: %.3f for %d frames or %.1f FPS" % (total_time, total_frames, total_frames / total_time))