Spaces:
Runtime error
Runtime error
| # Copyright (c) OpenMMLab. All rights reserved. | |
| import numpy as np | |
| import torch | |
| from mmdet.datasets.transforms.loading import LoadAnnotations | |
| from mmdet.registry import TRANSFORMS | |
| from mmdet.structures.bbox import get_box_type | |
| class LoadMatchAnnotations(LoadAnnotations): | |
| """Load and process the ``instances`` and ``seg_map`` annotation provided | |
| by dataset. It must load ``instances_ids`` which is only used in the | |
| tracking tasks. The annotation format is as the following: | |
| .. code-block:: python | |
| { | |
| 'instances': | |
| [ | |
| { | |
| # List of 4 numbers representing the bounding box of the | |
| # instance, in (x1, y1, x2, y2) order. | |
| 'bbox': [x1, y1, x2, y2], | |
| # Label of image classification. | |
| 'bbox_label': 1, | |
| # Used in tracking. | |
| # Id of instances. | |
| 'instance_id': 100, | |
| # Used in instance/panoptic segmentation. The segmentation mask | |
| # of the instance or the information of segments. | |
| # 1. If list[list[float]], it represents a list of polygons, | |
| # one for each connected component of the object. Each | |
| # list[float] is one simple polygon in the format of | |
| # [x1, y1, ..., xn, yn] (n >= 3). The Xs and Ys are absolute | |
| # coordinates in unit of pixels. | |
| # 2. If dict, it represents the per-pixel segmentation mask in | |
| # COCO's compressed RLE format. The dict should have keys | |
| # “size” and “counts”. Can be loaded by pycocotools | |
| 'mask': list[list[float]] or dict, | |
| } | |
| ] | |
| # Filename of semantic or panoptic segmentation ground truth file. | |
| 'seg_map_path': 'a/b/c' | |
| } | |
| After this module, the annotation has been changed to the format below: | |
| .. code-block:: python | |
| { | |
| # In (x1, y1, x2, y2) order, float type. N is the number of bboxes | |
| # in an image | |
| 'gt_bboxes': np.ndarray(N, 4) | |
| # In int type. | |
| 'gt_bboxes_labels': np.ndarray(N, ) | |
| # In built-in class | |
| 'gt_masks': PolygonMasks (H, W) or BitmapMasks (H, W) | |
| # In uint8 type. | |
| 'gt_seg_map': np.ndarray (H, W) | |
| # in (x, y, v) order, float type. | |
| } | |
| Required Keys: | |
| - height (optional) | |
| - width (optional) | |
| - instances | |
| - bbox (optional) | |
| - bbox_label | |
| - instance_id (optional) | |
| - mask (optional) | |
| - ignore_flag (optional) | |
| - seg_map_path (optional) | |
| Added Keys: | |
| - gt_bboxes (np.float32) | |
| - gt_bboxes_labels (np.int32) | |
| - gt_instances_ids (np.int32) | |
| - gt_masks (BitmapMasks | PolygonMasks) | |
| - gt_seg_map (np.uint8) | |
| - gt_ignore_flags (np.bool) | |
| """ | |
| def __init__(self, **kwargs) -> None: | |
| super().__init__(**kwargs) | |
| def _load_bboxes(self, results: dict) -> None: | |
| """Private function to load bounding box annotations. | |
| Args: | |
| results (dict): Result dict from :obj:``mmcv.BaseDataset``. | |
| Returns: | |
| dict: The dict contains loaded bounding box annotations. | |
| """ | |
| gt_bboxes = [] | |
| gt_ignore_flags = [] | |
| # TODO: use bbox_type | |
| for instance in results["instances"]: | |
| # The datasets which are only format in evaluation don't have | |
| # groundtruth boxes. | |
| if "bbox" in instance: | |
| gt_bboxes.append(instance["bbox"]) | |
| if "ignore_flag" in instance: | |
| gt_ignore_flags.append(instance["ignore_flag"]) | |
| # TODO: check this case | |
| if len(gt_bboxes) != len(gt_ignore_flags): | |
| # There may be no ``gt_ignore_flags`` in some cases, we treat them | |
| # as all False in order to keep the length of ``gt_bboxes`` and | |
| # ``gt_ignore_flags`` the same | |
| gt_ignore_flags = [False] * len(gt_bboxes) | |
| if self.box_type is None: | |
| results["gt_bboxes"] = np.array(gt_bboxes, dtype=np.float32).reshape( | |
| (-1, 4) | |
| ) | |
| else: | |
| _, box_type_cls = get_box_type(self.box_type) | |
| results["gt_bboxes"] = box_type_cls(gt_bboxes, dtype=torch.float32) | |
| results["gt_ignore_flags"] = np.array(gt_ignore_flags, dtype=bool) | |
| def _load_instances_ids(self, results: dict) -> None: | |
| """Private function to load instances id annotations. | |
| Args: | |
| results (dict): Result dict from :obj :obj:``mmcv.BaseDataset``. | |
| Returns: | |
| dict: The dict containing instances id annotations. | |
| """ | |
| gt_instances_ids = [] | |
| for instance in results["instances"]: | |
| gt_instances_ids.append(instance["instance_id"]) | |
| results["gt_instances_ids"] = np.array(gt_instances_ids, dtype=np.int32) | |
| def transform(self, results: dict) -> dict: | |
| """Function to load multiple types annotations. | |
| Args: | |
| results (dict): Result dict from :obj:``mmcv.BaseDataset``. | |
| Returns: | |
| dict: The dict contains loaded bounding box, label, instances id | |
| and semantic segmentation and keypoints annotations. | |
| """ | |
| results = super().transform(results) | |
| self._load_instances_ids(results) | |
| return results | |
| def __repr__(self) -> str: | |
| repr_str = self.__class__.__name__ | |
| repr_str += f"(with_bbox={self.with_bbox}, " | |
| repr_str += f"with_label={self.with_label}, " | |
| repr_str += f"with_mask={self.with_mask}, " | |
| repr_str += f"with_seg={self.with_seg}, " | |
| repr_str += f"poly2mask={self.poly2mask}, " | |
| repr_str += f"imdecode_backend='{self.imdecode_backend}', " | |
| repr_str += f"file_client_args={self.file_client_args})" | |
| return repr_str | |