From be35a52ecbadc3b68c3b2f1b459aac343bbaeeca Mon Sep 17 00:00:00 2001 From: "kirill.sizov" Date: Mon, 19 Apr 2021 12:54:40 +0300 Subject: [PATCH] add test --- .../dataset_manager/tests/test_formats.py | 329 +++++++++++++++++- 1 file changed, 327 insertions(+), 2 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_formats.py b/cvat/apps/dataset_manager/tests/test_formats.py index 44c0cda7..2a7c40cd 100644 --- a/cvat/apps/dataset_manager/tests/test_formats.py +++ b/cvat/apps/dataset_manager/tests/test_formats.py @@ -217,9 +217,9 @@ class TaskExportTest(_DbTestBase): } return self._generate_custom_annotations(annotations, task) - def _generate_task_images(self, count, name="image"): # pylint: disable=no-self-use + def _generate_task_images(self, count): # pylint: disable=no-self-use images = { - "client_files[%d]" % i: generate_image_file(name + "_%d.jpg" % i) + "client_files[%d]" % i: generate_image_file("image_%d.jpg" % i) for i in range(count) } images["image_quality"] = 75 @@ -496,6 +496,7 @@ class TaskExportTest(_DbTestBase): self.assertTrue(frame.frame in range(6, 10)) self.assertEqual(i + 1, 4) + class FrameMatchingTest(_DbTestBase): def _generate_task_images(self, paths): # pylint: disable=no-self-use f = BytesIO() @@ -586,3 +587,327 @@ class FrameMatchingTest(_DbTestBase): root = find_dataset_root(dataset, task_data) self.assertEqual(expected, root) + +class TaskAnnotationsImportTest(_DbTestBase): + def _generate_custom_annotations(self, annotations, task): + self._put_api_v1_task_id_annotations(task["id"], annotations) + return annotations + + def _generate_task_images(self, count, name="image"): + images = { + "client_files[%d]" % i: generate_image_file("image_%d.jpg" % i) + for i in range(count) + } + images["image_quality"] = 75 + return images + + def _generate_task(self, images, annotation_format, **overrides): + labels = [] + if annotation_format in ["ICDAR Recognition 1.0", + "ICDAR Localization 1.0"]: + labels = [{ + "name": "icdar", + "attributes": [{ + "name": "text", + "mutable": False, + "input_type": "text", + "values": ["word1", "word2"] + }] + }] + elif annotation_format == "ICDAR Segmentation 1.0": + labels = [{ + "name": "icdar", + "attributes": [ + { + "name": "text", + "mutable": False, + "input_type": "text", + "values": ["word_1", "word_2", "word_3"] + }, + { + "name": "index", + "mutable": False, + "input_type": "number", + "values": ["0", "1", "2"] + }, + { + "name": "color", + "mutable": False, + "input_type": "text", + "values": ["100 110 240", "10 15 20", "120 128 64"] + }, + { + "name": "center", + "mutable": False, + "input_type": "text", + "values": ["1 2", "2 4", "10 45"] + }, + ] + }] + elif annotation_format == "Market-1501 1.0": + labels = [{ + "name": "market-1501", + "attributes": [ + { + "name": "query", + "mutable": False, + "input_type": "select", + "values": ["True", "False"] + }, + { + "name": "camera_id", + "mutable": False, + "input_type": "number", + "values": ["0", "1", "2", "3"] + }, + { + "name": "person_id", + "mutable": False, + "input_type": "number", + "values": ["1", "2", "3"] + }, + ] + }] + else: + labels = [ + { + "name": "car", + "attributes": [ + { + "name": "model", + "mutable": False, + "input_type": "select", + "default_value": "mazda", + "values": ["bmw", "mazda", "renault"] + }, + { + "name": "parked", + "mutable": True, + "input_type": "checkbox", + "default_value": False + } + ] + }, + {"name": "person"} + ] + + task = { + "name": "my task #1", + "overlap": 0, + "segment_size": 100, + "labels": labels + } + task.update(overrides) + return self._create_task(task, images) + + def _generate_annotations(self, task, annotation_format): + shapes = [] + tracks = [] + tags = [] + + if annotation_format in ["ICDAR Recognition 1.0", + "ICDAR Localization 1.0"]: + shapes = [{ + "frame": 0, + "label_id": task["labels"][0]["id"], + "group": 0, + "source": "manual", + "attributes": [ + { + "spec_id": task["labels"][0]["attributes"][0]["id"], + "value": task["labels"][0]["attributes"][0]["values"][0] + }, + ], + "points": [1.0, 2.1, 10.6, 53.22], + "type": "rectangle", + "occluded": False, + }] + elif annotation_format == "Market-1501 1.0": + tags = [{ + "frame": 1, + "label_id": task["labels"][0]["id"], + "group": 0, + "source": "manual", + "attributes": [ + { + "spec_id": task["labels"][0]["attributes"][0]["id"], + "value": task["labels"][0]["attributes"][0]["values"][1] + }, + { + "spec_id": task["labels"][0]["attributes"][1]["id"], + "value": task["labels"][0]["attributes"][1]["values"][2] + }, + { + "spec_id": task["labels"][0]["attributes"][2]["id"], + "value": task["labels"][0]["attributes"][2]["values"][0] + } + ], + }] + elif annotation_format == "ICDAR Segmentation 1.0": + shapes = [{ + "frame": 0, + "label_id": task["labels"][0]["id"], + "group": 0, + "source": "manual", + "attributes": [ + { + "spec_id": task["labels"][0]["attributes"][0]["id"], + "value": task["labels"][0]["attributes"][0]["values"][0] + }, + { + "spec_id": task["labels"][0]["attributes"][1]["id"], + "value": task["labels"][0]["attributes"][1]["values"][0] + }, + { + "spec_id": task["labels"][0]["attributes"][2]["id"], + "value": task["labels"][0]["attributes"][2]["values"][1] + }, + { + "spec_id": task["labels"][0]["attributes"][3]["id"], + "value": task["labels"][0]["attributes"][3]["values"][2] + } + ], + "points": [1.0, 2.1, 10.6, 53.22], + "type": "rectangle", + "occluded": False, + }] + elif annotation_format == "VGGFace2 1.0": + shapes = [{ + "frame": 1, + "label_id": task["labels"][1]["id"], + "group": None, + "source": "manual", + "attributes": [], + "points": [2.0, 2.1, 40, 50.7], + "type": "rectangle", + "occluded": False + }] + else: + rectangle_shape_wo_attrs = { + "frame": 1, + "label_id": task["labels"][1]["id"], + "group": 0, + "source": "manual", + "attributes": [], + "points": [2.0, 2.1, 40, 50.7], + "type": "rectangle", + "occluded": False, + } + + rectangle_shape_with_attrs = { + "frame": 0, + "label_id": task["labels"][0]["id"], + "group": 0, + "source": "manual", + "attributes": [ + { + "spec_id": task["labels"][0]["attributes"][0]["id"], + "value": task["labels"][0]["attributes"][0]["values"][0] + }, + { + "spec_id": task["labels"][0]["attributes"][1]["id"], + "value": task["labels"][0]["attributes"][1]["default_value"] + } + ], + "points": [1.0, 2.1, 10.6, 53.22], + "type": "rectangle", + "occluded": False, + } + + track_wo_attrs = { + "frame": 0, + "label_id": task["labels"][1]["id"], + "group": 0, + "source": "manual", + "attributes": [], + "shapes": [ + { + "frame": 0, + "attributes": [], + "points": [1.0, 2.1, 100, 300.222], + "type": "polygon", + "occluded": False, + "outside": False + } + ] + } + + tag_wo_attrs = { + "frame": 0, + "label_id": task["labels"][0]["id"], + "group": None, + "attributes": [] + } + + tag_with_attrs = { + "frame": 1, + "label_id": task["labels"][0]["id"], + "group": 3, + "source": "manual", + "attributes": [ + { + "spec_id": task["labels"][0]["attributes"][0]["id"], + "value": task["labels"][0]["attributes"][0]["values"][1] + }, + { + "spec_id": task["labels"][0]["attributes"][1]["id"], + "value": task["labels"][0]["attributes"][1]["default_value"] + } + ], + } + + if annotation_format == "VGGFace2 1.0": + shapes = rectangle_shape_wo_attrs + elif annotation_format == "CVAT 1.1": + shapes = [rectangle_shape_wo_attrs, + rectangle_shape_with_attrs] + tags = [tag_with_attrs, tag_wo_attrs] + elif annotation_format == "MOTS PNG 1.0": + tracks = [track_wo_attrs] + else: + shapes = [rectangle_shape_wo_attrs, + rectangle_shape_with_attrs] + tags = tag_wo_attrs + tracks = track_wo_attrs + + annotations = { + "version": 0, + "tags": tags, + "shapes": shapes, + "tracks": tracks + } + + return self._generate_custom_annotations(annotations, task) + + def _test_can_import_annotations(self, task, import_format): + with tempfile.TemporaryDirectory() as temp_dir: + file_path = osp.join(temp_dir, import_format) + + export_format = import_format + if import_format == "CVAT 1.1": + export_format = "CVAT for images 1.1" + + dm.task.export_task(task["id"], file_path, export_format) + expected_ann = TaskAnnotation(task["id"]) + expected_ann.init_from_db() + + dm.task.import_task_annotations(task["id"], + file_path, import_format) + actual_ann = TaskAnnotation(task["id"]) + actual_ann.init_from_db() + + self.assertEqual(len(expected_ann.data), len(actual_ann.data)) + + def test_can_import_annotations_for_image_with_dots_in_filename(self): + for f in dm.views.get_import_formats(): + format_name = f.DISPLAY_NAME + + images = self._generate_task_images(3, "img0.0.0") + task = self._generate_task(images, format_name) + self._generate_annotations(task, format_name) + + with self.subTest(format=format_name): + if not f.ENABLED: + self.skipTest("Format is disabled") + + self._test_can_import_annotations(task, format_name) \ No newline at end of file