def evaluate_det( ann_file: Union[str, List[Frame]], pred_file: Union[str, List[Frame]], cfg_path: str, out_dir: str = "none", nproc: int = 4, ) -> Dict[str, float]: """Load the ground truth and prediction results. Args: ann_file: path to the ground truth annotations. "*.json" pred_file: path to the prediciton results in BDD format. "*.json" cfg_path: path to the config file out_dir: output_directory nproc: processes number for loading jsons Returns: dict: detection metric scores """ # Convert the annotation file to COCO format if isinstance(ann_file, str): ann_frames = load(ann_file, nproc) else: ann_frames = ann_file ann_frames = sorted(ann_frames, key=lambda frame: frame.name) categories, name_mapping, ignore_mapping = load_coco_config( mode="det", filepath=cfg_path, ) ann_coco = scalabel2coco_detection(SHAPE, ann_frames, categories, name_mapping, ignore_mapping) coco_gt = COCOV2(None, ann_coco) # Load results and convert the predictions if isinstance(pred_file, str): pred_frames = load(pred_file, nproc) else: pred_frames = pred_file pred_frames = sorted(pred_frames, key=lambda frame: frame.name) pred_res = scalabel2coco_detection(SHAPE, pred_frames, categories, name_mapping, ignore_mapping)["annotations"] coco_dt = coco_gt.loadRes(pred_res) cat_ids = coco_dt.getCatIds() cat_names = [cat["name"] for cat in coco_dt.loadCats(cat_ids)] img_ids = sorted(coco_gt.getImgIds()) ann_type = "bbox" coco_eval = COCOeval(coco_gt, coco_dt, ann_type) coco_eval.params.imgIds = img_ids return evaluate_workflow(coco_eval, cat_ids, cat_names, out_dir)
def main() -> None: """Main function.""" args = parse_args() assert args.mode in ["det", "box_track", "ins_seg", "seg_track"] categories, name_mapping, ignore_mapping = load_coco_config( mode=args.mode, filepath=args.config, ignore_as_class=args.ignore_as_class, ) shape = (args.height, args.width) if args.only_mask: assert args.mode in ["ins_seg", "seg_track"] convert_function = dict( ins_seg=bitmask2coco_ins_seg, seg_track=bitmask2coco_seg_track, )[args.mode] coco = convert_function( args.label, shape, list_files(args.label, suffix=".png"), categories, args.mask_mode, args.nproc, ) else: if args.mode in ["det", "box_track"]: convert_func = dict( det=scalabel2coco_detection, box_track=scalabel2coco_box_track, )[args.mode] else: convert_func = partial( dict( ins_seg=bdd100k2coco_ins_seg, seg_track=bdd100k2coco_seg_track, )[args.mode], mask_base=args.mask_base, mask_mode=args.mask_mode, nproc=args.nproc, ) frames = start_converting(args) coco = convert_func( shape=shape, frames=frames, categories=categories, name_mapping=name_mapping, ignore_mapping=ignore_mapping, ignore_as_class=args.ignore_as_class, remove_ignore=args.remove_ignore, ) logger.info("Saving converted annotations to disk...") with open(args.output, "w") as f: json.dump(coco, f) logger.info("Finished!")
def evaluate_ins_seg( ann_base: str, pred_base: str, pred_score_file: str, cfg_path: str, out_dir: str = "none", ) -> Dict[str, float]: """Load the ground truth and prediction results. Args: ann_base: path to the ground truth bitmasks folder. pred_base: path to the prediciton bitmasks folder. pred_score_file: path tothe prediction scores. cfg_path: path to the config file. out_dir: output_directory. Returns: dict: detection metric scores """ categories, _, _ = load_coco_config("ins_seg", cfg_path) bdd_eval = BDDInsSegEval(ann_base, pred_base, pred_score_file) cat_ids = [int(category["id"]) for category in categories] cat_names = [str(category["name"]) for category in categories] return evaluate_workflow(bdd_eval, cat_ids, cat_names, out_dir)
def segtrack_to_bitmasks( frames: List[Frame], out_base: str, ignore_as_class: bool = False, remove_ignore: bool = False, nproc: int = 4, ) -> None: """Converting segmentation tracking poly2d to bitmasks.""" frames_list = group_and_sort(frames) categories, name_mapping, ignore_mapping = load_coco_config( mode="track", filepath=DEFAULT_COCO_CONFIG, ignore_as_class=ignore_as_class, ) out_paths: List[str] = [] colors_list: List[List[np.ndarray]] = [] poly2ds_list: List[List[List[Poly2D]]] = [] logger.info("Preparing annotations for SegTrack to Bitmasks") for video_anns in tqdm(frames_list): global_instance_id: int = 1 instance_id_maps: Dict[str, int] = dict() video_name = video_anns[0].video_name out_dir = os.path.join(out_base, video_name) if not os.path.isdir(out_dir): os.makedirs(out_dir) for image_anns in video_anns: # Bitmask in .png format image_name = image_anns.name.replace(".jpg", ".png") image_name = os.path.split(image_name)[-1] out_path = os.path.join(out_dir, image_name) out_paths.append(out_path) colors: List[np.ndarray] = [] poly2ds: List[List[Poly2D]] = [] colors_list.append(colors) poly2ds_list.append(poly2ds) labels_ = image_anns.labels if labels_ is None or len(labels_) == 0: continue # Scores higher, rendering later if labels_[0].score is not None: labels_ = sorted(labels_, key=lambda label: float(label.score)) for label in labels_: if label.poly2d is None: continue category_ignored, category_id = process_category( label.category, categories, name_mapping, ignore_mapping, ignore_as_class=ignore_as_class, ) if category_ignored and remove_ignore: continue instance_id, global_instance_id = get_bdd100k_instance_id( instance_id_maps, global_instance_id, str(label.id)) color = set_instance_color(label, category_id, instance_id, category_ignored) colors.append(color) poly2ds.append(label.poly2d) logger.info("Start Conversion for SegTrack to Bitmasks") frames_to_masks(nproc, out_paths, colors_list, poly2ds_list)
def insseg_to_bitmasks( frames: List[Frame], out_base: str, ignore_as_class: bool = False, remove_ignore: bool = False, nproc: int = 4, ) -> None: """Converting instance segmentation poly2d to bitmasks.""" os.makedirs(out_base, exist_ok=True) categories, name_mapping, ignore_mapping = load_coco_config( mode="track", filepath=DEFAULT_COCO_CONFIG, ignore_as_class=ignore_as_class, ) out_paths: List[str] = [] colors_list: List[List[np.ndarray]] = [] poly2ds_list: List[List[List[Poly2D]]] = [] logger.info("Preparing annotations for InsSeg to Bitmasks") for image_anns in tqdm(frames): ann_id = 0 # Bitmask in .png format image_name = image_anns.name.replace(".jpg", ".png") image_name = os.path.split(image_name)[-1] out_path = os.path.join(out_base, image_name) out_paths.append(out_path) colors: List[np.ndarray] = [] poly2ds: List[List[Poly2D]] = [] colors_list.append(colors) poly2ds_list.append(poly2ds) labels_ = image_anns.labels if labels_ is None or len(labels_) == 0: continue # Scores higher, rendering later if labels_[0].score is not None: labels_ = sorted(labels_, key=lambda label: float(label.score)) for label in labels_: if label.poly2d is None: continue category_ignored, category_id = process_category( label.category, categories, name_mapping, ignore_mapping, ignore_as_class=ignore_as_class, ) if remove_ignore and category_ignored: continue ann_id += 1 color = set_instance_color(label, category_id, ann_id, category_ignored) colors.append(color) poly2ds.append(label.poly2d) logger.info("Start conversion for InsSeg to Bitmasks") frames_to_masks(nproc, out_paths, colors_list, poly2ds_list)