Create an :class:`Instances` object used by the models, from instance annotations in the dataset dict. Args: annos (list[dict]): a list of instance annotations in one image, each element for one instance. image_size (tuple): height, width Returns:
(annos, image_size, mask_format="polygon")
| 359 | |
| 360 | |
| 361 | def annotations_to_instances(annos, image_size, mask_format="polygon"): |
| 362 | """ |
| 363 | Create an :class:`Instances` object used by the models, |
| 364 | from instance annotations in the dataset dict. |
| 365 | |
| 366 | Args: |
| 367 | annos (list[dict]): a list of instance annotations in one image, each |
| 368 | element for one instance. |
| 369 | image_size (tuple): height, width |
| 370 | |
| 371 | Returns: |
| 372 | Instances: |
| 373 | It will contain fields "gt_boxes", "gt_classes", |
| 374 | "gt_masks", "gt_keypoints", if they can be obtained from `annos`. |
| 375 | This is the format that builtin models expect. |
| 376 | """ |
| 377 | boxes = [BoxMode.convert(obj["bbox"], obj["bbox_mode"], BoxMode.XYXY_ABS) for obj in annos] |
| 378 | target = Instances(image_size) |
| 379 | target.gt_boxes = Boxes(boxes) |
| 380 | |
| 381 | classes = [int(obj["category_id"]) for obj in annos] |
| 382 | classes = torch.tensor(classes, dtype=torch.int64) |
| 383 | target.gt_classes = classes |
| 384 | |
| 385 | if len(annos) and "segmentation" in annos[0]: |
| 386 | segms = [obj["segmentation"] for obj in annos] |
| 387 | if mask_format == "polygon": |
| 388 | # TODO check type and provide better error |
| 389 | masks = PolygonMasks(segms) |
| 390 | else: |
| 391 | assert mask_format == "bitmask", mask_format |
| 392 | masks = [] |
| 393 | for segm in segms: |
| 394 | if isinstance(segm, list): |
| 395 | # polygon |
| 396 | masks.append(polygons_to_bitmask(segm, *image_size)) |
| 397 | elif isinstance(segm, dict): |
| 398 | # COCO RLE |
| 399 | masks.append(mask_util.decode(segm)) |
| 400 | elif isinstance(segm, np.ndarray): |
| 401 | assert segm.ndim == 2, "Expect segmentation of 2 dimensions, got {}.".format( |
| 402 | segm.ndim |
| 403 | ) |
| 404 | # mask array |
| 405 | masks.append(segm) |
| 406 | else: |
| 407 | raise ValueError( |
| 408 | "Cannot convert segmentation of type '{}' to BitMasks!" |
| 409 | "Supported types are: polygons as list[list[float] or ndarray]," |
| 410 | " COCO-style RLE as a dict, or a full-image segmentation mask " |
| 411 | "as a 2D ndarray.".format(type(segm)) |
| 412 | ) |
| 413 | # torch.from_numpy does not support array with negative stride. |
| 414 | masks = BitMasks( |
| 415 | torch.stack([torch.from_numpy(np.ascontiguousarray(x)) for x in masks]) |
| 416 | ) |
| 417 | target.gt_masks = masks |
| 418 |
nothing calls this directly
no test coverage detected