Apply transforms to box, segmentation and keypoints annotations of a single instance. It will use `transforms.apply_box` for the box, and `transforms.apply_coords` for segmentation polygons & keypoints. If you need anything more specially designed for each data structure, you'l
(
annotation, transforms, image_size, *, keypoint_hflip_indices=None
)
| 253 | |
| 254 | |
| 255 | def transform_instance_annotations( |
| 256 | annotation, transforms, image_size, *, keypoint_hflip_indices=None |
| 257 | ): |
| 258 | """ |
| 259 | Apply transforms to box, segmentation and keypoints annotations of a single instance. |
| 260 | |
| 261 | It will use `transforms.apply_box` for the box, and |
| 262 | `transforms.apply_coords` for segmentation polygons & keypoints. |
| 263 | If you need anything more specially designed for each data structure, |
| 264 | you'll need to implement your own version of this function or the transforms. |
| 265 | |
| 266 | Args: |
| 267 | annotation (dict): dict of instance annotations for a single instance. |
| 268 | It will be modified in-place. |
| 269 | transforms (TransformList or list[Transform]): |
| 270 | image_size (tuple): the height, width of the transformed image |
| 271 | keypoint_hflip_indices (ndarray[int]): see `create_keypoint_hflip_indices`. |
| 272 | |
| 273 | Returns: |
| 274 | dict: |
| 275 | the same input dict with fields "bbox", "segmentation", "keypoints" |
| 276 | transformed according to `transforms`. |
| 277 | The "bbox_mode" field will be set to XYXY_ABS. |
| 278 | """ |
| 279 | if isinstance(transforms, (tuple, list)): |
| 280 | transforms = T.TransformList(transforms) |
| 281 | # bbox is 1d (per-instance bounding box) |
| 282 | bbox = BoxMode.convert(annotation["bbox"], annotation["bbox_mode"], BoxMode.XYXY_ABS) |
| 283 | # clip transformed bbox to image size |
| 284 | bbox = transforms.apply_box(np.array([bbox]))[0].clip(min=0) |
| 285 | annotation["bbox"] = np.minimum(bbox, list(image_size + image_size)[::-1]) |
| 286 | annotation["bbox_mode"] = BoxMode.XYXY_ABS |
| 287 | |
| 288 | if "segmentation" in annotation: |
| 289 | # each instance contains 1 or more polygons |
| 290 | segm = annotation["segmentation"] |
| 291 | if isinstance(segm, list): |
| 292 | # polygons |
| 293 | polygons = [np.asarray(p).reshape(-1, 2) for p in segm] |
| 294 | annotation["segmentation"] = [ |
| 295 | p.reshape(-1) for p in transforms.apply_polygons(polygons) |
| 296 | ] |
| 297 | elif isinstance(segm, dict): |
| 298 | # RLE |
| 299 | mask = mask_util.decode(segm) |
| 300 | mask = transforms.apply_segmentation(mask) |
| 301 | assert tuple(mask.shape[:2]) == image_size |
| 302 | annotation["segmentation"] = mask |
| 303 | else: |
| 304 | raise ValueError( |
| 305 | "Cannot transform segmentation of type '{}'!" |
| 306 | "Supported types are: polygons as list[list[float] or ndarray]," |
| 307 | " COCO-style RLE as a dict.".format(type(segm)) |
| 308 | ) |
| 309 | |
| 310 | if "keypoints" in annotation: |
| 311 | keypoints = transform_keypoint_annotations( |
| 312 | annotation["keypoints"], transforms, image_size, keypoint_hflip_indices |
nothing calls this directly
no test coverage detected