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", diff --git a/darwin/exporter/formats/darwin_1_0.py b/darwin/exporter/formats/darwin_1_0.py index d42505711..28744817d 100644 --- a/darwin/exporter/formats/darwin_1_0.py +++ b/darwin/exporter/formats/darwin_1_0.py @@ -165,12 +165,24 @@ 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"] - del data["paths"] - return {"complex_polygon": data} - else: - return {annotation_class.annotation_type: data} + v1_data = {} + 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] + v1_data[annotation_class.annotation_type] = {"path": data.get(key)} + + elif annotation_class.annotation_type == "tag": + v1_data["tag"] = {} + + elif annotation_class.annotation_type == "bounding_box": + 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 + v1_data["bounding_box"] = data["bounding_box"] + + return v1_data def _build_metadata(annotation_file: AnnotationFile) -> DictFreeForm: 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..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 @@ -8,9 +7,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": { @@ -59,6 +56,7 @@ def test_complete_annotation_file(self): {"x": 531.6440000000002, "y": 428.4196}, {"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=[]) @@ -128,3 +126,145 @@ def test_complex_polygon(self): "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, "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=[]) + + 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": [], "bounding_box": bounding_box}], + "dataset": "None", + } + + 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}], + [ + {"x": 251.75, "y": 169.77}, + {"x": 251.75, "y": 154.34}, + {"x": 251.08, "y": 151.84}, + {"x": 249.25, "y": 150.01}, + ], + ] + + 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=[]) + + 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": [], "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", + }