From 576c7904dcd9d3d8b37bca24be8f4f8697f0c38f Mon Sep 17 00:00:00 2001 From: Dmitrii Lavrukhin Date: Tue, 30 Jul 2024 21:04:08 +0400 Subject: [PATCH] more yolo v8 tests --- datumaro/plugins/yolo_format/extractor.py | 4 ++ tests/cli/test_yolo_format.py | 58 ++++++++++++++++----- tests/unit/data_formats/test_yolo_format.py | 11 ++++ 3 files changed, 61 insertions(+), 12 deletions(-) diff --git a/datumaro/plugins/yolo_format/extractor.py b/datumaro/plugins/yolo_format/extractor.py index 817260c842..57cbd2be64 100644 --- a/datumaro/plugins/yolo_format/extractor.py +++ b/datumaro/plugins/yolo_format/extractor.py @@ -438,6 +438,10 @@ def _check_is_rectangle(p1, p2, p3, p4): raise InvalidAnnotationError( "Given points do not form a rectangle: opposite sides have different slope angles." ) + if abs((p12_angle - p23_angle) % math.pi - math.pi / 2) > 0.001: + raise InvalidAnnotationError( + "Given points do not form a rectangle: adjacent sides are not orthogonal." + ) def _load_one_annotation( self, parts: List[str], image_height: int, image_width: int diff --git a/tests/cli/test_yolo_format.py b/tests/cli/test_yolo_format.py index b49a9441c8..9d839bc21b 100644 --- a/tests/cli/test_yolo_format.py +++ b/tests/cli/test_yolo_format.py @@ -16,6 +16,9 @@ class YoloIntegrationScenarios(TestCase): + ASSET_PATH = ["yolo_dataset", "yolo"] + FORMAT_NAME = "yolo" + @mark_requirement(Requirements.DATUM_GENERAL_REQ) def test_can_save_and_load_yolo_dataset(self): target_dataset = Dataset.from_iterable( @@ -35,11 +38,14 @@ def test_can_save_and_load_yolo_dataset(self): with TestDir() as test_dir: yolo_dir = osp.join( - __file__[: __file__.rfind(osp.join("tests", ""))], "tests", "assets", "yolo_dataset" + __file__[: __file__.rfind(osp.join("tests", ""))], + "tests", + "assets", + *self.ASSET_PATH, ) run(self, "create", "-o", test_dir) - run(self, "import", "-p", test_dir, "-f", "yolo", yolo_dir) + run(self, "import", "-p", test_dir, "-f", self.FORMAT_NAME, yolo_dir) export_dir = osp.join(test_dir, "export_dir") run( @@ -50,12 +56,12 @@ def test_can_save_and_load_yolo_dataset(self): "-o", export_dir, "-f", - "yolo", + self.FORMAT_NAME, "--", "--save-media", ) - parsed_dataset = Dataset.import_from(export_dir, format="yolo") + parsed_dataset = Dataset.import_from(export_dir, format=self.FORMAT_NAME) compare_datasets(self, target_dataset, parsed_dataset) @mark_requirement(Requirements.DATUM_GENERAL_REQ) @@ -82,9 +88,20 @@ def test_can_export_mot_as_yolo(self): run(self, "import", "-p", test_dir, "-f", "mot_seq", mot_dir) yolo_dir = osp.join(test_dir, "yolo_dir") - run(self, "export", "-p", test_dir, "-o", yolo_dir, "-f", "yolo", "--", "--save-media") + run( + self, + "export", + "-p", + test_dir, + "-o", + yolo_dir, + "-f", + self.FORMAT_NAME, + "--", + "--save-media", + ) - parsed_dataset = Dataset.import_from(yolo_dir, format="yolo") + parsed_dataset = Dataset.import_from(yolo_dir, format=self.FORMAT_NAME) compare_datasets(self, target_dataset, parsed_dataset) @mark_requirement(Requirements.DATUM_GENERAL_REQ) @@ -126,14 +143,14 @@ def test_can_convert_voc_to_yolo(self): "-i", voc_dir, "-f", - "yolo", + self.FORMAT_NAME, "-o", yolo_dir, "--", "--save-media", ) - parsed_dataset = Dataset.import_from(yolo_dir, format="yolo") + parsed_dataset = Dataset.import_from(yolo_dir, format=self.FORMAT_NAME) compare_datasets(self, target_dataset, parsed_dataset, require_media=True) @mark_requirement(Requirements.DATUM_GENERAL_REQ) @@ -152,11 +169,14 @@ def test_can_delete_labels_from_yolo_dataset(self): with TestDir() as test_dir: yolo_dir = osp.join( - __file__[: __file__.rfind(osp.join("tests", ""))], "tests", "assets", "yolo_dataset" + __file__[: __file__.rfind(osp.join("tests", ""))], + "tests", + "assets", + *self.ASSET_PATH, ) run(self, "create", "-o", test_dir) - run(self, "import", "-p", test_dir, "-f", "yolo", yolo_dir) + run(self, "import", "-p", test_dir, "-f", self.FORMAT_NAME, yolo_dir) run( self, @@ -185,8 +205,22 @@ def test_can_delete_labels_from_yolo_dataset(self): export_dir = osp.join(test_dir, "export") run( - self, "export", "-p", test_dir, "-o", export_dir, "-f", "yolo", "--", "--save-image" + self, + "export", + "-p", + test_dir, + "-o", + export_dir, + "-f", + self.FORMAT_NAME, + "--", + "--save-image", ) - parsed_dataset = Dataset.import_from(export_dir, format="yolo") + parsed_dataset = Dataset.import_from(export_dir, format=self.FORMAT_NAME) compare_datasets(self, target_dataset, parsed_dataset) + + +class YOLOv8IntegrationScenarios(YoloIntegrationScenarios): + ASSET_PATH = ["yolo_dataset", "yolov8"] + FORMAT_NAME = "yolov8" diff --git a/tests/unit/data_formats/test_yolo_format.py b/tests/unit/data_formats/test_yolo_format.py index eb12ce19a4..4f458962c3 100644 --- a/tests/unit/data_formats/test_yolo_format.py +++ b/tests/unit/data_formats/test_yolo_format.py @@ -1161,6 +1161,17 @@ def test_can_report_invalid_shape(self, test_dir): assert isinstance(capture.value.__cause__, InvalidAnnotationError) assert "Given points do not form a rectangle" in str(capture.value.__cause__) + @mark_requirement(Requirements.DATUM_ERROR_REPORTING) + def test_can_report_invalid_shape_parallelogram(self, test_dir): + self._prepare_dataset(test_dir) + with open(osp.join(test_dir, self._get_annotation_dir(), "a.txt"), "w") as f: + f.write("0 0.1 0.1 0.5 0.1 0.6 0.5 0.2 0.5") + + with pytest.raises(AnnotationImportError) as capture: + Dataset.import_from(test_dir, self.IMPORTER.NAME).init_cache() + assert isinstance(capture.value.__cause__, InvalidAnnotationError) + assert "adjacent sides are not orthogonal" in str(capture.value.__cause__) + class YOLOv8PoseExtractorTest(YOLOv8ExtractorTest): IMPORTER = YOLOv8PoseImporter