Skip to content

Commit ec610a9

Browse files
authored
Allow empty tile annotation (#4124)
* Add warnings for empty annotations in OTXTileDetTestDataset and OTXTileInstSegTestDataset * Fix empty annotation handling in tiling
1 parent 5e18121 commit ec610a9

File tree

2 files changed

+16
-7
lines changed

2 files changed

+16
-7
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ All notable changes to this project will be documented in this file.
124124
(<https://github.com/openvinotoolkit/training_extensions/pull/4105>)
125125
- Disable tiling classifier toggle in configurable parameters
126126
(<https://github.com/openvinotoolkit/training_extensions/pull/4107>)
127+
- Fix empty annotation in tiling
128+
(<https://github.com/openvinotoolkit/training_extensions/pull/4124>)
127129

128130
## \[v2.1.0\]
129131

src/otx/core/data/dataset/tile.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import logging as log
99
import operator
10+
import warnings
1011
from copy import deepcopy
1112
from itertools import product
1213
from typing import TYPE_CHECKING, Callable
@@ -372,14 +373,17 @@ def _get_item_impl(self, index: int) -> TileDetDataEntity: # type: ignore[overr
372373
img = item.media_as(Image)
373374
img_data, img_shape, _ = self._get_img_data_and_shape(img)
374375

375-
bbox_anns = [ann for ann in item.annotations if isinstance(ann, Bbox)]
376+
gt_bboxes = [ann for ann in item.annotations if isinstance(ann, Bbox)]
377+
378+
if empty_anno := len(gt_bboxes) == 0:
379+
warnings.warn(f"Empty annotation for image {item.id}!", stacklevel=2)
376380

377381
bboxes = (
378-
np.stack([ann.points for ann in bbox_anns], axis=0).astype(np.float32)
379-
if len(bbox_anns) > 0
380-
else np.zeros((0, 4), dtype=np.float32)
382+
np.empty((0, 4), dtype=np.float32)
383+
if empty_anno
384+
else np.stack([ann.points for ann in gt_bboxes], axis=0).astype(np.float32)
381385
)
382-
labels = torch.as_tensor([ann.label for ann in bbox_anns])
386+
labels = torch.as_tensor([ann.label for ann in gt_bboxes])
383387

384388
tile_entities, tile_attrs = self.get_tiles(img_data, item, index)
385389

@@ -476,11 +480,14 @@ def _get_item_impl(self, index: int) -> TileInstSegDataEntity: # type: ignore[o
476480
else:
477481
gt_masks.append(polygon_to_bitmap([annotation], *img_shape)[0])
478482

483+
if empty_anno := len(gt_bboxes) == 0:
484+
warnings.warn(f"Empty annotation for image {item.id}", stacklevel=2)
485+
479486
# convert xywh to xyxy format
480-
bboxes = np.array(gt_bboxes, dtype=np.float32)
487+
bboxes = np.empty((0, 4), dtype=np.float32) if empty_anno else np.stack(gt_bboxes, dtype=np.float32)
481488
bboxes[:, 2:] += bboxes[:, :2]
482489

483-
masks = np.stack(gt_masks, axis=0) if gt_masks else np.zeros((0, *img_shape), dtype=bool)
490+
masks = np.stack(gt_masks, axis=0) if gt_masks else np.empty((0, *img_shape), dtype=bool)
484491
labels = np.array(gt_labels, dtype=np.int64)
485492

486493
tile_entities, tile_attrs = self.get_tiles(img_data, item, index)

0 commit comments

Comments
 (0)