Adapted from: https://github.com/facebookresearch/detectron2/blob/master/detectron2/data/detection_utils.py#L254 The changes from original: - The presence of 2D bounding box (i.e. "bbox" field) is assumed by default in d2; here it's optional. - Add optional 3D bounding b
(
annotation,
transforms,
image_size,
)
| 14 | |
| 15 | |
| 16 | def transform_instance_annotations( |
| 17 | annotation, |
| 18 | transforms, |
| 19 | image_size, |
| 20 | ): |
| 21 | """Adapted from: |
| 22 | https://github.com/facebookresearch/detectron2/blob/master/detectron2/data/detection_utils.py#L254 |
| 23 | |
| 24 | The changes from original: |
| 25 | - The presence of 2D bounding box (i.e. "bbox" field) is assumed by default in d2; here it's optional. |
| 26 | - Add optional 3D bounding box support. |
| 27 | - If the instance mask annotation is in RLE, then it's decoded into polygons, not bitmask, to save memory. |
| 28 | |
| 29 | =============================================================================================================== |
| 30 | |
| 31 | Apply transforms to box, segmentation and keypoints annotations of a single instance. |
| 32 | |
| 33 | It will use `transforms.apply_box` for the box, and |
| 34 | `transforms.apply_coords` for segmentation polygons & keypoints. |
| 35 | If you need anything more specially designed for each data structure, |
| 36 | you'll need to implement your own version of this function or the transforms. |
| 37 | |
| 38 | Args: |
| 39 | annotation (dict): dict of instance annotations for a single instance. |
| 40 | It will be modified in-place. |
| 41 | transforms (TransformList or list[Transform]): |
| 42 | image_size (tuple): the height, width of the transformed image |
| 43 | keypoint_hflip_indices (ndarray[int]): see `create_keypoint_hflip_indices`. |
| 44 | |
| 45 | Returns: |
| 46 | dict: |
| 47 | the same input dict with fields "bbox", "segmentation", "keypoints" |
| 48 | transformed according to `transforms`. |
| 49 | The "bbox_mode" field will be set to XYXY_ABS. |
| 50 | """ |
| 51 | if isinstance(transforms, (tuple, list)): |
| 52 | transforms = T.TransformList(transforms) |
| 53 | # (dennis.park) Here 2D bounding box is optional. |
| 54 | if "bbox" in annotation: |
| 55 | assert "bbox_mode" in annotation, "'bbox' is present, but 'bbox_mode' is not." |
| 56 | # bbox is 1d (per-instance bounding box) |
| 57 | bbox = BoxMode.convert(annotation["bbox"], annotation["bbox_mode"], BoxMode.XYXY_ABS) |
| 58 | bbox = transforms.apply_box(np.array([bbox]))[0] |
| 59 | # clip transformed bbox to image size |
| 60 | bbox = bbox.clip(min=0) |
| 61 | bbox = np.minimum(bbox, list(image_size + image_size)[::-1]) |
| 62 | annotation["bbox"] = bbox |
| 63 | annotation["bbox_mode"] = BoxMode.XYXY_ABS |
| 64 | |
| 65 | # Vertical flipping is not implemented (`flip_transform.py`). TODO: implement if needed. |
| 66 | if "bbox3d" in annotation: |
| 67 | bbox3d = np.array(annotation["bbox3d"]) |
| 68 | annotation['bbox3d'] = transforms.apply_box3d(bbox3d) |
| 69 | |
| 70 | return annotation |
| 71 | |
| 72 | |
| 73 | def _create_empty_instances(image_size): |