From 28c7a77ca636a06947c26ca9122937374d8a4424 Mon Sep 17 00:00:00 2001 From: Christoffer Date: Fri, 13 Oct 2023 11:03:59 +0200 Subject: [PATCH 01/10] updated the darwin_1_0 formatter --- darwin/exporter/formats/darwin_1_0.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/darwin/exporter/formats/darwin_1_0.py b/darwin/exporter/formats/darwin_1_0.py index 8cff79fd3..a80fafaf3 100644 --- a/darwin/exporter/formats/darwin_1_0.py +++ b/darwin/exporter/formats/darwin_1_0.py @@ -171,11 +171,15 @@ def _build_image_annotation(annotation: Annotation, skip_slots: bool = False) -> def _build_legacy_annotation_data(annotation_class: AnnotationClass, data: DictFreeForm) -> DictFreeForm: if annotation_class.annotation_type == "complex_polygon": - data["path"] = data["paths"] + path = data["paths"] del data["paths"] - return {"complex_polygon": data} - else: - return {annotation_class.annotation_type: data} + data["complex_polygon"] = {"path": data} + elif annotation_class.annotation_type == "polygon": + path = data["path"] + del data["path"] + data["polygon"] = {"path": path} + + return data def _build_metadata(annotation_file: AnnotationFile) -> DictFreeForm: @@ -183,3 +187,5 @@ def _build_metadata(annotation_file: AnnotationFile) -> DictFreeForm: return {"metadata": annotation_file.slots[0].metadata} else: return {} + + From 96fcb6ef90a5ec06db3f587024f9c4d230a3b375 Mon Sep 17 00:00:00 2001 From: Christoffer Date: Fri, 13 Oct 2023 13:07:32 +0200 Subject: [PATCH 02/10] fix that seems to work --- darwin/exporter/formats/darwin_1_0.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/darwin/exporter/formats/darwin_1_0.py b/darwin/exporter/formats/darwin_1_0.py index a80fafaf3..ce9df3f4f 100644 --- a/darwin/exporter/formats/darwin_1_0.py +++ b/darwin/exporter/formats/darwin_1_0.py @@ -170,16 +170,25 @@ def _build_image_annotation(annotation: Annotation, skip_slots: bool = False) -> def _build_legacy_annotation_data(annotation_class: AnnotationClass, data: DictFreeForm) -> DictFreeForm: + + v1_data = {} + if annotation_class.annotation_type == "complex_polygon": path = data["paths"] del data["paths"] - data["complex_polygon"] = {"path": data} + + v1_data["complex_polygon"] = {"path": data} elif annotation_class.annotation_type == "polygon": path = data["path"] del data["path"] - data["polygon"] = {"path": path} + v1_data["polygon"] = {"path": path} + elif annotation_class.annotation_type == "tag": + v1_data["tag"] = {} + + if "bounding_box" in data: + v1_data["bounding_box"] = data["bounding_box"] - return data + return v1_data def _build_metadata(annotation_file: AnnotationFile) -> DictFreeForm: From fef713927bc51737f5a5d65d23ba647cba3a85e1 Mon Sep 17 00:00:00 2001 From: Christoffer Date: Fri, 13 Oct 2023 14:03:01 +0200 Subject: [PATCH 03/10] works for manual testing on bounding-box and polygons now --- darwin/exporter/formats/darwin_1_0.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/darwin/exporter/formats/darwin_1_0.py b/darwin/exporter/formats/darwin_1_0.py index ce9df3f4f..8e3738892 100644 --- a/darwin/exporter/formats/darwin_1_0.py +++ b/darwin/exporter/formats/darwin_1_0.py @@ -170,22 +170,24 @@ def _build_image_annotation(annotation: Annotation, skip_slots: bool = False) -> def _build_legacy_annotation_data(annotation_class: AnnotationClass, data: DictFreeForm) -> DictFreeForm: - v1_data = {} + polygon_annotation_mappings = { + "complex_polygon": "paths", + "polygon": "path" + } - if annotation_class.annotation_type == "complex_polygon": - path = data["paths"] - del data["paths"] + if annotation_class.annotation_type in polygon_annotation_mappings: + key = polygon_annotation_mappings[annotation_class.annotation_type] + v1_data[annotation_class.annotation_type] = {"path": data.get(key)} - v1_data["complex_polygon"] = {"path": data} - elif annotation_class.annotation_type == "polygon": - path = data["path"] - del data["path"] - v1_data["polygon"] = {"path": path} elif annotation_class.annotation_type == "tag": v1_data["tag"] = {} - if "bounding_box" in data: + elif annotation_class.annotation_type == "bounding_box": + v1_data["bounding_box"] = data + + if "bounding_box" in data and annotation_class.annotation_type != "bounding_box": + # Poygons and complex polygons usually have attached bounding_box annotations v1_data["bounding_box"] = data["bounding_box"] return v1_data From 5ec8a7c8cdbf07dbd62f58a4a1a91e7620f12c65 Mon Sep 17 00:00:00 2001 From: Christoffer Date: Mon, 16 Oct 2023 13:42:43 +0200 Subject: [PATCH 04/10] cleaned up settings.json --- .vscode/settings.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 7343e13d9..bfd0b9283 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -15,9 +15,6 @@ }, "python.formatting.blackPath": "black", "python.formatting.provider": "black", - "python.formatting.blackArgs": [ - "-l 120" - ], "python.linting.mypyEnabled": true, "isort.args": [ "--profile", From 65deec839c463c62527c6f2f2f829f93eaf7cf98 Mon Sep 17 00:00:00 2001 From: Christoffer Date: Mon, 16 Oct 2023 13:43:51 +0200 Subject: [PATCH 05/10] black refactored --- darwin/exporter/formats/darwin_1_0.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/darwin/exporter/formats/darwin_1_0.py b/darwin/exporter/formats/darwin_1_0.py index fb51a938c..538c2a975 100644 --- a/darwin/exporter/formats/darwin_1_0.py +++ b/darwin/exporter/formats/darwin_1_0.py @@ -166,10 +166,7 @@ def _build_image_annotation(annotation: Annotation, skip_slots: bool = False) -> def _build_legacy_annotation_data(annotation_class: AnnotationClass, data: DictFreeForm) -> DictFreeForm: v1_data = {} - polygon_annotation_mappings = { - "complex_polygon": "paths", - "polygon": "path" - } + polygon_annotation_mappings = {"complex_polygon": "paths", "polygon": "path"} if annotation_class.annotation_type in polygon_annotation_mappings: key = polygon_annotation_mappings[annotation_class.annotation_type] @@ -193,5 +190,3 @@ def _build_metadata(annotation_file: AnnotationFile) -> DictFreeForm: return {"metadata": annotation_file.slots[0].metadata} else: return {} - - From 0c4d3e1ea51a114bae255131fa039986425c3630 Mon Sep 17 00:00:00 2001 From: Christoffer Date: Mon, 16 Oct 2023 16:02:04 +0200 Subject: [PATCH 06/10] minor change --- darwin/exporter/formats/darwin_1_0.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/darwin/exporter/formats/darwin_1_0.py b/darwin/exporter/formats/darwin_1_0.py index 538c2a975..28744817d 100644 --- a/darwin/exporter/formats/darwin_1_0.py +++ b/darwin/exporter/formats/darwin_1_0.py @@ -176,7 +176,7 @@ def _build_legacy_annotation_data(annotation_class: AnnotationClass, data: DictF v1_data["tag"] = {} elif annotation_class.annotation_type == "bounding_box": - v1_data["bounding_box"] = data + v1_data[annotation_class.annotation_type] = data if "bounding_box" in data and annotation_class.annotation_type != "bounding_box": # Poygons and complex polygons usually have attached bounding_box annotations From a9018b22038dafa17140e5b41a5f6b5c3fb3ae13 Mon Sep 17 00:00:00 2001 From: Christoffer Date: Mon, 16 Oct 2023 17:31:29 +0200 Subject: [PATCH 07/10] added bouding box to test --- tests/darwin/exporter/formats/export_darwin_1_0_test.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/darwin/exporter/formats/export_darwin_1_0_test.py b/tests/darwin/exporter/formats/export_darwin_1_0_test.py index a997c62b3..92b112a14 100644 --- a/tests/darwin/exporter/formats/export_darwin_1_0_test.py +++ b/tests/darwin/exporter/formats/export_darwin_1_0_test.py @@ -59,8 +59,15 @@ def test_complete_annotation_file(self): {"x": 531.6440000000002, "y": 428.4196}, {"x": 529.8140000000002, "y": 426.5896}, ] + + bounding_box = {"x": 557.66, + "y": 428.98, + "w": 160.76, + "h": 315.3 + } + annotation_class = dt.AnnotationClass(name="test", annotation_type="polygon") - annotation = dt.Annotation(annotation_class=annotation_class, data={"path": polygon_path}, subs=[]) + annotation = dt.Annotation(annotation_class=annotation_class, data={"path": polygon_path, "bounding_box": bounding_box}, subs=[]) annotation_file = dt.AnnotationFile( path=Path("test.json"), From b21b14411f3c2646bb01b431d108fed7ca9a5d47 Mon Sep 17 00:00:00 2001 From: Christoffer Date: Mon, 16 Oct 2023 17:54:42 +0200 Subject: [PATCH 08/10] added polygon and complex polygon tests with bounding boxes --- .../formats/export_darwin_1_0_test.py | 92 ++++++++++++++++++- 1 file changed, 88 insertions(+), 4 deletions(-) diff --git a/tests/darwin/exporter/formats/export_darwin_1_0_test.py b/tests/darwin/exporter/formats/export_darwin_1_0_test.py index 92b112a14..c4b8c7916 100644 --- a/tests/darwin/exporter/formats/export_darwin_1_0_test.py +++ b/tests/darwin/exporter/formats/export_darwin_1_0_test.py @@ -60,6 +60,84 @@ def test_complete_annotation_file(self): {"x": 529.8140000000002, "y": 426.5896}, ] + annotation_class = dt.AnnotationClass(name="test", annotation_type="polygon") + annotation = dt.Annotation(annotation_class=annotation_class, data={"path": polygon_path}, subs=[]) + + annotation_file = dt.AnnotationFile( + path=Path("test.json"), + filename="test.json", + annotation_classes=[annotation_class], + annotations=[annotation], + image_height=1080, + image_width=1920, + image_url="https://darwin.v7labs.com/image.jpg", + ) + + assert _build_json(annotation_file) == { + "image": { + "seq": None, + "width": 1920, + "height": 1080, + "filename": "test.json", + "original_filename": "test.json", + "url": "https://darwin.v7labs.com/image.jpg", + "thumbnail_url": None, + "path": None, + "workview_url": None, + }, + "annotations": [{"polygon": {"path": polygon_path}, "name": "test", "slot_names": []}], + "dataset": "None", + } + + def test_complex_polygon(self): + polygon_path = [ + [{"x": 230.06, "y": 174.04}, {"x": 226.39, "y": 170.36}, {"x": 224.61, "y": 166.81}], + [{"x": 238.98, "y": 171.69}, {"x": 236.97, "y": 174.04}, {"x": 238.67, "y": 174.04}], + [ + {"x": 251.75, "y": 169.77}, + {"x": 251.75, "y": 154.34}, + {"x": 251.08, "y": 151.84}, + {"x": 249.25, "y": 150.01}, + ], + ] + + annotation_class = dt.AnnotationClass(name="test", annotation_type="complex_polygon") + annotation = dt.Annotation(annotation_class=annotation_class, data={"paths": polygon_path}, subs=[]) + + annotation_file = dt.AnnotationFile( + path=Path("test.json"), + filename="test.json", + annotation_classes=[annotation_class], + annotations=[annotation], + image_height=1080, + image_width=1920, + image_url="https://darwin.v7labs.com/image.jpg", + ) + + assert _build_json(annotation_file) == { + "image": { + "seq": None, + "width": 1920, + "height": 1080, + "filename": "test.json", + "original_filename": "test.json", + "url": "https://darwin.v7labs.com/image.jpg", + "thumbnail_url": None, + "path": None, + "workview_url": None, + }, + "annotations": [{"complex_polygon": {"path": polygon_path}, "name": "test", "slot_names": []}], + "dataset": "None", + } + + + def test_polygon_annotation_file_with_bbox(self): + polygon_path = [ + {"x": 534.1440000000002, "y": 429.0896}, + {"x": 531.6440000000002, "y": 428.4196}, + {"x": 529.8140000000002, "y": 426.5896}, + ] + bounding_box = {"x": 557.66, "y": 428.98, "w": 160.76, @@ -91,11 +169,11 @@ def test_complete_annotation_file(self): "path": None, "workview_url": None, }, - "annotations": [{"polygon": {"path": polygon_path}, "name": "test", "slot_names": []}], + "annotations": [{"polygon": {"path": polygon_path}, "name": "test", "slot_names": [], "bounding_box": bounding_box}], "dataset": "None", } - def test_complex_polygon(self): + def test_complex_polygon_with_bbox(self): polygon_path = [ [{"x": 230.06, "y": 174.04}, {"x": 226.39, "y": 170.36}, {"x": 224.61, "y": 166.81}], [{"x": 238.98, "y": 171.69}, {"x": 236.97, "y": 174.04}, {"x": 238.67, "y": 174.04}], @@ -107,8 +185,14 @@ def test_complex_polygon(self): ], ] + bounding_box = {"x": 557.66, + "y": 428.98, + "w": 160.76, + "h": 315.3 + } + annotation_class = dt.AnnotationClass(name="test", annotation_type="complex_polygon") - annotation = dt.Annotation(annotation_class=annotation_class, data={"paths": polygon_path}, subs=[]) + annotation = dt.Annotation(annotation_class=annotation_class, data={"paths": polygon_path, "bounding_box": bounding_box}, subs=[]) annotation_file = dt.AnnotationFile( path=Path("test.json"), @@ -132,6 +216,6 @@ def test_complex_polygon(self): "path": None, "workview_url": None, }, - "annotations": [{"complex_polygon": {"path": polygon_path}, "name": "test", "slot_names": []}], + "annotations": [{"complex_polygon": {"path": polygon_path}, "name": "test", "slot_names": [], "bounding_box": bounding_box}], "dataset": "None", } From bc86dba1159a5614fd59aca82b9b3231632f7366 Mon Sep 17 00:00:00 2001 From: Christoffer Date: Mon, 16 Oct 2023 18:00:48 +0200 Subject: [PATCH 09/10] added further tests --- .../formats/export_darwin_1_0_test.py | 78 +++++++++++++++---- 1 file changed, 64 insertions(+), 14 deletions(-) diff --git a/tests/darwin/exporter/formats/export_darwin_1_0_test.py b/tests/darwin/exporter/formats/export_darwin_1_0_test.py index c4b8c7916..f9ec01711 100644 --- a/tests/darwin/exporter/formats/export_darwin_1_0_test.py +++ b/tests/darwin/exporter/formats/export_darwin_1_0_test.py @@ -8,9 +8,7 @@ class TestBuildJson: def test_empty_annotation_file(self): - annotation_file = dt.AnnotationFile( - path=Path("test.json"), filename="test.json", annotation_classes=[], annotations=[] - ) + annotation_file = dt.AnnotationFile(path=Path("test.json"), filename="test.json", annotation_classes=[], annotations=[]) assert _build_json(annotation_file) == { "image": { @@ -130,7 +128,6 @@ def test_complex_polygon(self): "dataset": "None", } - def test_polygon_annotation_file_with_bbox(self): polygon_path = [ {"x": 534.1440000000002, "y": 429.0896}, @@ -138,11 +135,7 @@ def test_polygon_annotation_file_with_bbox(self): {"x": 529.8140000000002, "y": 426.5896}, ] - bounding_box = {"x": 557.66, - "y": 428.98, - "w": 160.76, - "h": 315.3 - } + bounding_box = {"x": 557.66, "y": 428.98, "w": 160.76, "h": 315.3} annotation_class = dt.AnnotationClass(name="test", annotation_type="polygon") annotation = dt.Annotation(annotation_class=annotation_class, data={"path": polygon_path, "bounding_box": bounding_box}, subs=[]) @@ -185,11 +178,7 @@ def test_complex_polygon_with_bbox(self): ], ] - bounding_box = {"x": 557.66, - "y": 428.98, - "w": 160.76, - "h": 315.3 - } + bounding_box = {"x": 557.66, "y": 428.98, "w": 160.76, "h": 315.3} annotation_class = dt.AnnotationClass(name="test", annotation_type="complex_polygon") annotation = dt.Annotation(annotation_class=annotation_class, data={"paths": polygon_path, "bounding_box": bounding_box}, subs=[]) @@ -219,3 +208,64 @@ def test_complex_polygon_with_bbox(self): "annotations": [{"complex_polygon": {"path": polygon_path}, "name": "test", "slot_names": [], "bounding_box": bounding_box}], "dataset": "None", } + + def test_bounding_box(self): + bounding_box_data = {"x": 100, "y": 150, "w": 50, "h": 30} + annotation_class = dt.AnnotationClass(name="bbox_test", annotation_type="bounding_box") + annotation = dt.Annotation(annotation_class=annotation_class, data=bounding_box_data, subs=[]) + + annotation_file = dt.AnnotationFile( + path=Path("test.json"), + filename="test.json", + annotation_classes=[annotation_class], + annotations=[annotation], + image_height=1080, + image_width=1920, + image_url="https://darwin.v7labs.com/image.jpg", + ) + + assert _build_json(annotation_file) == { + "image": { + "seq": None, + "width": 1920, + "height": 1080, + "filename": "test.json", + "original_filename": "test.json", + "url": "https://darwin.v7labs.com/image.jpg", + "thumbnail_url": None, + "path": None, + "workview_url": None, + }, + "annotations": [{"bounding_box": bounding_box_data, "name": "bbox_test", "slot_names": []}], + "dataset": "None", + } + + def test_tags(self): + tag_data = "sample_tag" + annotation_class = dt.AnnotationClass(name="tag_test", annotation_type="tag") + annotation = dt.Annotation(annotation_class=annotation_class, data=tag_data, subs=[]) + + annotation_file = dt.AnnotationFile( + path=Path("test.json"), + filename="test.json", + annotation_classes=[annotation_class], + annotations=[annotation], + image_height=1080, + image_width=1920, + image_url="https://darwin.v7labs.com/image.jpg", + ) + assert _build_json(annotation_file) == { + "image": { + "seq": None, + "width": 1920, + "height": 1080, + "filename": "test.json", + "original_filename": "test.json", + "url": "https://darwin.v7labs.com/image.jpg", + "thumbnail_url": None, + "path": None, + "workview_url": None, + }, + "annotations": [{"tag": {}, "name": "tag_test", "slot_names": []}], + "dataset": "None", + } From 29ab0e481723357a1a99b18ec976aacb839f384b Mon Sep 17 00:00:00 2001 From: Christoffer Date: Tue, 17 Oct 2023 10:20:28 +0200 Subject: [PATCH 10/10] formatter --- tests/darwin/exporter/formats/export_darwin_1_0_test.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/darwin/exporter/formats/export_darwin_1_0_test.py b/tests/darwin/exporter/formats/export_darwin_1_0_test.py index f9ec01711..4bca09c28 100644 --- a/tests/darwin/exporter/formats/export_darwin_1_0_test.py +++ b/tests/darwin/exporter/formats/export_darwin_1_0_test.py @@ -1,6 +1,5 @@ from pathlib import Path -import pytest import darwin.datatypes as dt from darwin.exporter.formats.darwin_1_0 import _build_json