|
1 | 1 | import json |
2 | 2 | from pathlib import Path |
3 | | -from typing import Any, Dict, Iterable, Iterator |
| 3 | +from typing import Any, Dict, Iterable |
| 4 | + |
| 5 | +import deprecation |
4 | 6 |
|
5 | 7 | import darwin.datatypes as dt |
6 | 8 | from darwin.exporter.formats.numpy_encoder import NumpyEncoder |
| 9 | +from darwin.version import __version__ |
| 10 | + |
| 11 | +DEPRECATION_MESSAGE = """This function is going to be turned into private. This means that breaking |
| 12 | +changes in its interface and implementation are to be expected. We encourage using ``export`` |
| 13 | +instead of calling this low-level function directly.""" |
7 | 14 |
|
8 | 15 |
|
9 | | -def export(annotation_files: Iterator[dt.AnnotationFile], output_dir: Path) -> None: |
| 16 | +def export(annotation_files: Iterable[dt.AnnotationFile], output_dir: Path) -> None: |
| 17 | + """ |
| 18 | + Exports the given ``AnnotationFile``s into the dataloop format inside of the given ``output_dir``. |
| 19 | +
|
| 20 | + Parameters |
| 21 | + ---------- |
| 22 | + annotation_files : Iterable[dt.AnnotationFile] |
| 23 | + The ``AnnotationFile``s to be exported. |
| 24 | + output_dir : Path |
| 25 | + The folder where the new coco file will be. |
| 26 | + """ |
10 | 27 | for id, annotation_file in enumerate(annotation_files): |
11 | | - export_file(annotation_file, id, output_dir) |
| 28 | + _export_file(annotation_file, id, output_dir) |
12 | 29 |
|
13 | 30 |
|
| 31 | +@deprecation.deprecated( |
| 32 | + deprecated_in="0.7.8", |
| 33 | + removed_in="0.8.0", |
| 34 | + current_version=__version__, |
| 35 | + details=DEPRECATION_MESSAGE, |
| 36 | +) |
14 | 37 | def export_file(annotation_file: dt.AnnotationFile, id: int, output_dir: Path) -> None: |
15 | | - output: Dict[str, Any] = build_json(annotation_file, id) |
| 38 | + output: Dict[str, Any] = _build_json(annotation_file, id) |
16 | 39 | output_file_path: Path = (output_dir / annotation_file.filename).with_suffix(".json") |
17 | 40 | with open(output_file_path, "w") as f: |
18 | 41 | json.dump(output, f, cls=NumpyEncoder, indent=1) |
19 | 42 |
|
20 | 43 |
|
| 44 | +@deprecation.deprecated( |
| 45 | + deprecated_in="0.7.8", |
| 46 | + removed_in="0.8.0", |
| 47 | + current_version=__version__, |
| 48 | + details=DEPRECATION_MESSAGE, |
| 49 | +) |
21 | 50 | def build_json(annotation_file: dt.AnnotationFile, id: int) -> Dict[str, Any]: |
22 | 51 | return { |
23 | 52 | "_id": id, |
24 | 53 | "filename": annotation_file.filename, |
25 | 54 | "itemMetadata": [], |
26 | | - "annotations": build_annotations(annotation_file, id), |
| 55 | + "annotations": _build_annotations(annotation_file, id), |
27 | 56 | } |
28 | 57 |
|
29 | 58 |
|
| 59 | +@deprecation.deprecated( |
| 60 | + deprecated_in="0.7.8", |
| 61 | + removed_in="0.8.0", |
| 62 | + current_version=__version__, |
| 63 | + details=DEPRECATION_MESSAGE, |
| 64 | +) |
30 | 65 | def build_annotations(annotation_file: dt.AnnotationFile, id: int) -> Iterable[Dict[str, Any]]: |
31 | 66 | output = [] |
32 | 67 | for annotation_id, annotation in enumerate(annotation_file.annotations): |
@@ -62,3 +97,56 @@ def build_annotations(annotation_file: dt.AnnotationFile, id: int) -> Iterable[D |
62 | 97 | output.append(entry) |
63 | 98 |
|
64 | 99 | return output |
| 100 | + |
| 101 | + |
| 102 | +def _export_file(annotation_file: dt.AnnotationFile, id: int, output_dir: Path) -> None: |
| 103 | + output: Dict[str, Any] = _build_json(annotation_file, id) |
| 104 | + output_file_path: Path = (output_dir / annotation_file.filename).with_suffix(".json") |
| 105 | + with open(output_file_path, "w") as f: |
| 106 | + json.dump(output, f, cls=NumpyEncoder, indent=1) |
| 107 | + |
| 108 | + |
| 109 | +def _build_annotations(annotation_file: dt.AnnotationFile, id: int) -> Iterable[Dict[str, Any]]: |
| 110 | + output = [] |
| 111 | + for annotation_id, annotation in enumerate(annotation_file.annotations): |
| 112 | + print(annotation) |
| 113 | + if annotation.annotation_class.annotation_type == "bounding_box": |
| 114 | + entry = { |
| 115 | + "id": annotation_id, |
| 116 | + "datasetId": "darwin", |
| 117 | + "type": "box", |
| 118 | + "label": annotation.annotation_class.name, |
| 119 | + "attributes": [], |
| 120 | + "coordinates": [ |
| 121 | + {"x": annotation.data["x"], "y": annotation.data["y"], "z": 0}, |
| 122 | + { |
| 123 | + "x": annotation.data["x"] + annotation.data["w"], |
| 124 | + "y": annotation.data["y"] + annotation.data["h"], |
| 125 | + "z": 0, |
| 126 | + }, |
| 127 | + ], |
| 128 | + "metadata": {}, |
| 129 | + } |
| 130 | + output.append(entry) |
| 131 | + elif annotation.annotation_class.annotation_type == "polygon": |
| 132 | + entry = { |
| 133 | + "id": annotation_id, |
| 134 | + "datasetId": "darwin", |
| 135 | + "type": "segment", |
| 136 | + "label": annotation.annotation_class.name, |
| 137 | + "attributes": [], |
| 138 | + "coordinates": [{"x": point["x"], "y": point["y"], "z": 0} for point in annotation.data["path"]], |
| 139 | + "metadata": {}, |
| 140 | + } |
| 141 | + output.append(entry) |
| 142 | + |
| 143 | + return output |
| 144 | + |
| 145 | + |
| 146 | +def _build_json(annotation_file: dt.AnnotationFile, id: int) -> Dict[str, Any]: |
| 147 | + return { |
| 148 | + "_id": id, |
| 149 | + "filename": annotation_file.filename, |
| 150 | + "itemMetadata": [], |
| 151 | + "annotations": _build_annotations(annotation_file, id), |
| 152 | + } |
0 commit comments