From dab90d865f44a736d9801201968aeca582d00266 Mon Sep 17 00:00:00 2001 From: Eugene Liu Date: Fri, 13 Dec 2024 09:21:36 +0000 Subject: [PATCH] Allow empty anno --- .../data/dataset/instance_segmentation.py | 7 +++++-- src/otx/core/data/dataset/tile.py | 21 ++++++++----------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/otx/core/data/dataset/instance_segmentation.py b/src/otx/core/data/dataset/instance_segmentation.py index cde68fa59f..8cd8ea6c07 100644 --- a/src/otx/core/data/dataset/instance_segmentation.py +++ b/src/otx/core/data/dataset/instance_segmentation.py @@ -5,6 +5,7 @@ from __future__ import annotations +import warnings from collections import defaultdict from functools import partial from typing import Callable @@ -49,6 +50,9 @@ def _get_item_impl(self, index: int) -> InstanceSegDataEntity | None: gt_bboxes, gt_labels, gt_masks, gt_polygons = [], [], [], [] + # NOTE (Eugene): + # Temporary solution to handle multiple annotation types. + # Ideally, we should pre-filter annotations during initialization of the dataset. if Polygon.__name__ in anno_collection: # Polygon for InstSeg has higher priority for poly in anno_collection[Polygon.__name__]: bbox = Bbox(*poly.get_bbox()).points @@ -80,8 +84,7 @@ def _get_item_impl(self, index: int) -> InstanceSegDataEntity | None: else: gt_masks.append(polygon_to_bitmap([poly], *img_shape)[0]) else: - msg = "No valid annotations found in the dataset." - raise ValueError(msg) + warnings.warn(f"No valid annotations found for image {item.id}!", stacklevel=2) bboxes = np.stack(gt_bboxes, dtype=np.float32, axis=0) if gt_bboxes else np.empty((0, 4)) masks = np.stack(gt_masks, axis=0) if gt_masks else np.zeros((0, *img_shape), dtype=bool) diff --git a/src/otx/core/data/dataset/tile.py b/src/otx/core/data/dataset/tile.py index 611f8062e5..502dd3530a 100644 --- a/src/otx/core/data/dataset/tile.py +++ b/src/otx/core/data/dataset/tile.py @@ -514,6 +514,9 @@ def _get_item_impl(self, index: int) -> TileInstSegDataEntity: # type: ignore[o gt_bboxes, gt_labels, gt_masks, gt_polygons = [], [], [], [] + # NOTE (Eugene): + # Temporary solution to handle multiple annotation types. + # Ideally, we should pre-filter annotations during initialization of the dataset. if Polygon.__name__ in anno_collection: # Polygon for InstSeg has higher priority for poly in anno_collection[Polygon.__name__]: bbox = Bbox(*poly.get_bbox()).points @@ -525,10 +528,10 @@ def _get_item_impl(self, index: int) -> TileInstSegDataEntity: # type: ignore[o else: gt_masks.append(polygon_to_bitmap([poly], *img_shape)[0]) elif Bbox.__name__ in anno_collection: - bboxes = anno_collection[Bbox.__name__] - gt_bboxes = [ann.points for ann in bboxes] - gt_labels = [ann.label for ann in bboxes] - for box in bboxes: + boxes = anno_collection[Bbox.__name__] + gt_bboxes = [ann.points for ann in boxes] + gt_labels = [ann.label for ann in boxes] + for box in boxes: poly = Polygon(box.as_polygon()) if self._dataset.include_polygons: gt_polygons.append(poly) @@ -545,15 +548,9 @@ def _get_item_impl(self, index: int) -> TileInstSegDataEntity: # type: ignore[o else: gt_masks.append(polygon_to_bitmap([poly], *img_shape)[0]) else: - msg = "No valid annotations found in the dataset." - raise ValueError(msg) - - if empty_anno := len(gt_bboxes) == 0: - warnings.warn(f"Empty annotation for image {item.id}", stacklevel=2) - - # convert xywh to xyxy format - bboxes = np.empty((0, 4), dtype=np.float32) if empty_anno else np.stack(gt_bboxes, dtype=np.float32) + warnings.warn(f"No valid annotations found for image {item.id}!", stacklevel=2) + bboxes = np.stack(gt_bboxes, dtype=np.float32) if gt_bboxes else np.empty((0, 4), dtype=np.float32) masks = np.stack(gt_masks, axis=0) if gt_masks else np.empty((0, *img_shape), dtype=bool) labels = np.array(gt_labels, dtype=np.int64)