From d175f67579c7c42f6cb507145565c7e05cef9ee2 Mon Sep 17 00:00:00 2001 From: Eugene Liu Date: Mon, 22 Jan 2024 06:28:04 +0000 Subject: [PATCH] Filter invalid polygon shapes (#2795) * Fix invalid polygon shape filter * style reformat * fix segmentation test * style changes * update for readability * revert some changes --- src/otx/core/data/adapter/base_dataset_adapter.py | 13 +++++++++---- .../core/data/adapter/detection_dataset_adapter.py | 2 +- .../adapter/visual_prompting_dataset_adapter.py | 2 +- .../mmseg/datasets/pipelines/test_transforms.py | 4 ++-- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/otx/core/data/adapter/base_dataset_adapter.py b/src/otx/core/data/adapter/base_dataset_adapter.py index cd92d56c251..4f2feb977f6 100644 --- a/src/otx/core/data/adapter/base_dataset_adapter.py +++ b/src/otx/core/data/adapter/base_dataset_adapter.py @@ -272,11 +272,16 @@ def _prepare_label_information( return {"category_items": category_items, "label_groups": label_groups, "label_entities": label_entities} - def _is_normal_polygon(self, annotation: DatumAnnotationType.polygon) -> bool: + def _is_normal_polygon(self, annotation: DatumAnnotationType.polygon, width: int, height: int) -> bool: """To filter out the abnormal polygon.""" - x_points = [annotation.points[i] for i in range(0, len(annotation.points), 2)] - y_points = [annotation.points[i + 1] for i in range(0, len(annotation.points), 2)] - return min(x_points) < max(x_points) and min(y_points) < max(y_points) + x_points = annotation.points[::2] # Extract x-coordinates + y_points = annotation.points[1::2] # Extract y-coordinates + + return ( + min(x_points) < max(x_points) < width + and min(y_points) < max(y_points) < height + and annotation.get_area() > 0 + ) def _is_normal_bbox(self, x1: float, y1: float, x2: float, y2: float) -> bool: """To filter out the abrnormal bbox.""" diff --git a/src/otx/core/data/adapter/detection_dataset_adapter.py b/src/otx/core/data/adapter/detection_dataset_adapter.py index a6ce1b2bce5..dbcc8ca16ea 100644 --- a/src/otx/core/data/adapter/detection_dataset_adapter.py +++ b/src/otx/core/data/adapter/detection_dataset_adapter.py @@ -41,7 +41,7 @@ def get_otx_dataset(self) -> DatasetEntity: self.task_type in (TaskType.INSTANCE_SEGMENTATION, TaskType.ROTATED_DETECTION) and ann.type == DatumAnnotationType.polygon ): - if self._is_normal_polygon(ann): + if self._is_normal_polygon(ann, image.width, image.height): shapes.append(self._get_polygon_entity(ann, image.width, image.height)) if self.task_type is TaskType.DETECTION and ann.type == DatumAnnotationType.bbox: if self._is_normal_bbox(ann.points[0], ann.points[1], ann.points[2], ann.points[3]): diff --git a/src/otx/core/data/adapter/visual_prompting_dataset_adapter.py b/src/otx/core/data/adapter/visual_prompting_dataset_adapter.py index d428dc6afad..7a5c235f792 100644 --- a/src/otx/core/data/adapter/visual_prompting_dataset_adapter.py +++ b/src/otx/core/data/adapter/visual_prompting_dataset_adapter.py @@ -53,7 +53,7 @@ def get_otx_dataset(self) -> DatasetEntity: for ann in datumaro_item.annotations: if ann.type == DatumAnnotationType.polygon: # save polygons as-is, they will be converted to masks. - if self._is_normal_polygon(ann): + if self._is_normal_polygon(ann, image.width, image.height): shapes.append(self._get_polygon_entity(ann, image.width, image.height)) if ann.type == DatumAnnotationType.mask: diff --git a/tests/unit/algorithms/segmentation/adapters/mmseg/datasets/pipelines/test_transforms.py b/tests/unit/algorithms/segmentation/adapters/mmseg/datasets/pipelines/test_transforms.py index facded59996..dee7c6be234 100644 --- a/tests/unit/algorithms/segmentation/adapters/mmseg/datasets/pipelines/test_transforms.py +++ b/tests/unit/algorithms/segmentation/adapters/mmseg/datasets/pipelines/test_transforms.py @@ -110,8 +110,8 @@ class TestNormalize: @pytest.mark.parametrize( "mean,std,to_rgb,expected", [ - (1.0, 1.0, True, np.array([[[1.0, 0.0, 0.0]]], dtype=np.float32)), - (1.0, 1.0, False, np.array([[[-1.0, 0.0, 0.0]]], dtype=np.float32)), + ([[[1.0, 1.0, 1.0]]], [[[1.0, 1.0, 1.0]]], True, np.array([[[1.0, 0.0, -1.0]]], dtype=np.float32)), + ([[[1.0, 1.0, 1.0]]], [[[1.0, 1.0, 1.0]]], False, np.array([[[-1.0, 0.0, 1.0]]], dtype=np.float32)), ], ) def test_call(self, mean: float, std: float, to_rgb: bool, expected: np.array) -> None: