def test_get_pc_inside_box(): """ test get_pc_inside_box(pc_raw,bbox) *bbox format is [p0,p1,p2,h] - -------- - /| /| - -------- - . h | | | | . p2 -------- |/ |/ p0 -------- p1 :test lidar data: x y z intensity laser_number 0 0.0 0.0 5.0 4.0 31.0 1 1.0 0.0 5.0 1.0 14.0 2 2.0 0.0 5.0 0.0 16.0 3 3.0 0.0 5.0 20.0 30.0 4 4.0 0.0 5.0 3.0 29.0 5 5.0 0.0 5.0 1.0 11.0 6 6.0 0.0 5.0 31.0 13.0 7 7.0 0.0 5.0 2.0 28.0 8 8.0 0.0 5.0 5.0 27.0 9 9.0 0.0 5.0 6.0 10.0 """ bbox = np.array([np.array([[0], [0], [0]]), np.array([[2], [0], [0]]), np.array([[0], [5], [0]]), np.array(10)]) pc = ply_loader.load_ply(TEST_DATA_LOC / "1/lidar/PC_0.ply") pc_inside = eval_utils.get_pc_inside_bbox(pc, bbox) assert len(pc_inside) == 3
def eval_tracks( path_tracker_output: str, path_dataset: _PathLike, d_min: float, d_max: float, out_file: TextIO, centroid_method: str, ) -> None: """Evaluate tracking output. Args: path_tracker_output: path to tracker output path_dataset: path to dataset d_min: minimum distance range d_max: maximum distance range out_file: output file object centroid_method: method for ground truth centroid estimation """ acc = mm.MOTAccumulator(auto_id=True) path_track_data = sorted(glob.glob(os.fspath(path_tracker_output) + "/*")) log_id = pathlib.Path(path_dataset).name logger.info("log_id = %s", log_id) city_info_fpath = f"{path_dataset}/city_info.json" city_info = read_json_file(city_info_fpath) city_name = city_info["city_name"] logger.info("city name = %s", city_name) ID_gt_all: List[str] = [] for ind_frame in range(len(path_track_data)): if ind_frame % 50 == 0: logger.info("%d/%d" % (ind_frame, len(path_track_data))) timestamp_lidar = int(path_track_data[ind_frame].split("/")[-1].split("_")[-1].split(".")[0]) path_gt = os.path.join( path_dataset, "per_sweep_annotations_amodal", f"tracked_object_labels_{timestamp_lidar}.json" ) if not os.path.exists(path_gt): logger.warning("Missing ", path_gt) continue gt_data = read_json_file(path_gt) pose_data = read_json_file(f"{path_dataset}/poses/city_SE3_egovehicle_{timestamp_lidar}.json") rotation = np.array(pose_data["rotation"]) translation = np.array(pose_data["translation"]) ego_R = quat2rotmat(rotation) ego_t = translation egovehicle_to_city_se3 = SE3(rotation=ego_R, translation=ego_t) pc_raw0 = load_ply(os.path.join(path_dataset, f"lidar/PC_{timestamp_lidar}.ply")) pc_raw_roi = leave_only_roi_region( pc_raw0, egovehicle_to_city_se3, ground_removal_method="no", city_name=city_name ) gt: Dict[str, Dict[str, Any]] = {} id_gts = [] for i in range(len(gt_data)): if gt_data[i]["label_class"] != "VEHICLE": continue bbox, orientation = label_to_bbox(gt_data[i]) pc_segment = get_pc_inside_bbox(pc_raw_roi, bbox) center = np.array([gt_data[i]["center"]["x"], gt_data[i]["center"]["y"], gt_data[i]["center"]["z"]]) if ( len(pc_segment) >= min_point_num and bbox[3] > 0 and in_distance_range_pose(np.zeros(3), center, d_min, d_max) ): track_label_uuid = gt_data[i]["track_label_uuid"] gt[track_label_uuid] = {} if centroid_method == "average": gt[track_label_uuid]["centroid"] = pc_segment.sum(axis=0) / len(pc_segment) elif centroid_method == "label_center": gt[track_label_uuid]["centroid"] = center else: logger.warning("Not implemented") gt[track_label_uuid]["bbox"] = bbox gt[track_label_uuid]["orientation"] = orientation if track_label_uuid not in ID_gt_all: ID_gt_all.append(track_label_uuid) id_gts.append(track_label_uuid) tracks: Dict[str, Dict[str, Any]] = {} id_tracks: List[str] = [] track_data = read_json_file(path_track_data[ind_frame]) for track in track_data: key = track["track_label_uuid"] if track["label_class"] != "VEHICLE" or track["height"] == 0: continue center = np.array([track["center"]["x"], track["center"]["y"], track["center"]["z"]]) if in_distance_range_pose(np.zeros(3), center, d_min, d_max): tracks[key] = {} tracks[key]["centroid"] = center id_tracks.append(key) dists: List[List[float]] = [] for gt_key, gt_value in gt.items(): gt_track_data: List[float] = [] dists.append(gt_track_data) for track_key, track_value in tracks.items(): gt_track_data.append(get_distance(gt_value, track_value, "centroid")) acc.update(id_gts, id_tracks, dists) mh = mm.metrics.create() summary = mh.compute( acc, metrics=[ "num_frames", "mota", "motp", "idf1", "mostly_tracked", "mostly_lost", "num_false_positives", "num_misses", "num_switches", "num_fragmentations", ], name="acc", ) logger.info("summary = %s", summary) num_tracks = len(ID_gt_all) fn = os.path.basename(path_tracker_output) num_frames = summary["num_frames"][0] mota = summary["mota"][0] * 100 motp = summary["motp"][0] idf1 = summary["idf1"][0] most_track = summary["mostly_tracked"][0] / num_tracks most_lost = summary["mostly_lost"][0] / num_tracks num_fp = summary["num_false_positives"][0] num_miss = summary["num_misses"][0] num_switch = summary["num_switches"][0] num_flag = summary["num_fragmentations"][0] out_string = ( f"{fn} {num_frames} {mota:.2f} {motp:.2f} {idf1:.2f} {most_track:.2f} " f"{most_lost:.2f} {num_fp} {num_miss} {num_switch} {num_flag} \n" ) out_file.write(out_string)