Skip to content

Commit 4067f81

Browse files
committed
2 parents e08b760 + 5040c49 commit 4067f81

File tree

6 files changed

+57
-59
lines changed

6 files changed

+57
-59
lines changed

.coveragerc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[report]
22
exclude_lines =
3-
raise AOBaseException\(
3+
raise SABaseException\(

docs/source/tutorial.sdk.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ to convert them to other annotation formats:
239239

240240
.. code-block:: python
241241
242-
sa.export_annotation_format("<input_folder>", "<output_folder>", "<dataset_format>", "<dataset_name>",
242+
sa.export_annotation_format("<input_folder>", "<output_folder>", "<dataset_format>", "<dataset_name>",
243243
"<project_type>", "<task>", "<platform>")
244244
245245
.. note::
@@ -256,7 +256,7 @@ You can find more information annotation format conversion :ref:`here <ref_conve
256256
257257
# From SA panoptic format to COCO panoptic format
258258
sa.export_annotation_format(
259-
"tests/converter_test/COCO/input/fromSuperAnnotate/cats_dogs_panoptic_segm",
259+
"tests/converter_test/COCO/input/fromSuperAnnotate/cats_dogs_panoptic_segm",
260260
"tests/converter_test/COCO/output/panoptic",
261261
"COCO", "panoptic_test", "Pixel","panoptic_segmentation","Web"
262262
)
@@ -277,8 +277,8 @@ You can find more information annotation format conversion :ref:`here <ref_conve
277277
278278
# YOLO annotation format to SA Web platform annotation format
279279
sa.import_annotation_format(
280-
'tests/converter_test/YOLO/input/toSuperAnnotate',
281-
'tests/converter_test/YOLO/output',
280+
'tests/converter_test/YOLO/input/toSuperAnnotate',
281+
'tests/converter_test/YOLO/output',
282282
'YOLO', '', 'Vector', 'object_detection', 'Web'
283283
)
284284

superannotate/analytics/common.py

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import json
22
import logging
33
from pathlib import Path
4+
import glob
45

56
import pandas as pd
67
from ..exceptions import SABaseException
@@ -215,21 +216,46 @@ def __get_image_metadata(image_name, annotations):
215216
break
216217
return image_metadata
217218

219+
def __get_user_metadata(annotation):
220+
annotation_created_at = pd.to_datetime(annotation.get("createdAt"))
221+
annotation_created_by = annotation.get("createdBy")
222+
annotation_creator_email = None
223+
annotation_creator_role = None
224+
if annotation_created_by:
225+
annotation_creator_email = annotation_created_by.get("email")
226+
annotation_creator_role = annotation_created_by.get("role")
227+
annotation_creation_type = annotation.get("creationType")
228+
annotation_updated_at = pd.to_datetime(annotation.get("updatedAt"))
229+
annotation_updated_by = annotation.get("updatedBy")
230+
annotation_updator_email = None
231+
annotation_updator_role = None
232+
if annotation_updated_by:
233+
annotation_updator_email = annotation_updated_by.get("email")
234+
annotation_updator_role = annotation_updated_by.get("role")
235+
user_metadata = {
236+
"createdAt": annotation_created_at,
237+
"creatorRole": annotation_creator_role,
238+
"creatorEmail": annotation_creator_email,
239+
"creationType": annotation_creation_type,
240+
"updatedAt": annotation_updated_at,
241+
"updatorRole": annotation_updator_role,
242+
"updatorEmail": annotation_updator_email
243+
}
244+
return user_metadata
245+
218246
annotations_paths = []
219-
247+
220248
for path in Path(project_root).glob('*.json'):
221-
if path.name.endswith('___objects.json'
222-
) or path.name.endswith('___pixel.json'):
223-
annotations_paths.append(path)
249+
annotations_paths.append(path)
224250

225251
if not annotations_paths:
226252
logger.warning(
227253
"No annotations found in project export root %s", project_root
228254
)
229-
255+
type_postfix = "___objects.json" if glob.glob("{}/*___objects.json".format(project_root)) else "___pixel.json"
230256
for annotation_path in annotations_paths:
231257
annotation_json = json.load(open(annotation_path))
232-
image_name = annotation_path.name.split("___objects.json")[0]
258+
image_name = annotation_path.name.split(type_postfix)[0]
233259
image_metadata = __get_image_metadata(image_name, annotation_json)
234260
annotation_instance_id = 0
235261
for annotation in annotation_json:
@@ -249,8 +275,9 @@ def __get_image_metadata(image_name, annotations):
249275
"meta": comment_meta,
250276
"commentResolved": comment_resolved,
251277
}
278+
user_metadata = __get_user_metadata(annotation)
279+
annotation_dict.update(user_metadata)
252280
annotation_dict.update(image_metadata)
253-
254281
__append_annotation(annotation_dict)
255282
continue
256283
if annotation_type == "tag":
@@ -276,21 +303,6 @@ def __get_image_metadata(image_name, annotations):
276303
annotation_locked = annotation.get("locked")
277304
annotation_visible = annotation.get("visible")
278305
annotation_tracking_id = annotation.get("trackingId")
279-
annotation_created_at = annotation.get("createdAt")
280-
annotation_created_by = annotation.get("createdBy")
281-
annotation_creator_email = None
282-
annotation_creator_role = None
283-
if annotation_created_by:
284-
annotation_creator_email = annotation_created_by.get("email")
285-
annotation_creator_role = annotation_created_by.get("role")
286-
annotation_creation_type = annotation.get("creationType")
287-
annotation_updated_at = annotation.get("updatedAt")
288-
annotation_updated_by = annotation.get("updatedBy")
289-
annotation_updator_email = None
290-
annotation_updator_role = None
291-
if annotation_updated_by:
292-
annotation_updator_email = annotation_updated_by.get("email")
293-
annotation_updator_role = annotation_updated_by.get("role")
294306
annotation_meta = None
295307
if annotation_type in ["bbox", "polygon", "polyline", "cuboid"]:
296308
annotation_meta = {"points": annotation["points"]}
@@ -315,7 +327,7 @@ def __get_image_metadata(image_name, annotations):
315327
annotation_probability = annotation.get("probability")
316328
annotation_point_labels = annotation.get("pointLabels")
317329
attributes = annotation.get("attributes")
318-
330+
user_metadata = __get_user_metadata(annotation)
319331
if not attributes:
320332
annotation_dict = {
321333
"imageName": image_name,
@@ -331,14 +343,8 @@ def __get_image_metadata(image_name, annotations):
331343
"pointLabels": annotation_point_labels,
332344
"classColor": annotation_class_color,
333345
"groupId": annotation_group_id,
334-
"createdAt": annotation_created_at,
335-
"creatorRole": annotation_creator_role,
336-
"creatorEmail": annotation_creator_email,
337-
"creationType": annotation_creation_type,
338-
"updatedAt": annotation_updated_at,
339-
"updatorRole": annotation_updator_role,
340-
"updatorEmail": annotation_updator_email
341346
}
347+
annotation_dict.update(user_metadata)
342348
annotation_dict.update(image_metadata)
343349
__append_annotation(annotation_dict)
344350
else:
@@ -375,14 +381,8 @@ def __get_image_metadata(image_name, annotations):
375381
"pointLabels": annotation_point_labels,
376382
"classColor": annotation_class_color,
377383
"groupId": annotation_group_id,
378-
"createdAt": annotation_created_at,
379-
"creatorRole": annotation_creator_role,
380-
"creatorEmail": annotation_creator_email,
381-
"creationType": annotation_creation_type,
382-
"updatedAt": annotation_updated_at,
383-
"updatorRole": annotation_updator_role,
384-
"updatorEmail": annotation_updator_email
385384
}
385+
annotation_dict.update(user_metadata)
386386
annotation_dict.update(image_metadata)
387387
__append_annotation(annotation_dict)
388388

superannotate/db/projects.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ def upload_images_from_folder_to_project(
529529
if not isinstance(project, dict):
530530
project = get_project_metadata(project)
531531
if recursive_subfolders:
532-
logger.warning(
532+
logger.info(
533533
"When using recursive subfolder parsing same name images in different subfolders will overwrite each other."
534534
)
535535
if exclude_file_patterns is None:
@@ -910,14 +910,14 @@ def upload_annotations_from_folder_to_project(
910910
):
911911
"""Finds and uploads all JSON files in the folder_path as annotations to the project.
912912
913-
WARNING: The JSON files should follow specific naming convention. For Vector
913+
The JSON files should follow specific naming convention. For Vector
914914
projects they should be named "<image_filename>___objects.json" (e.g., if
915915
image is cats.jpg the annotation filename should be cats.jpg___objects.json), for Pixel projects
916916
JSON file should be named "<image_filename>___pixel.json" and also second mask
917917
image file should be present with the name "<image_name>___save.png". In both cases
918918
image with <image_name> should be already present on the platform.
919919
920-
WARNING: Existing annotations will be overwritten.
920+
Existing annotations will be overwritten.
921921
922922
:param project: project name or metadata of the project to upload annotations to
923923
:type project: str or dict
@@ -932,15 +932,15 @@ def upload_annotations_from_folder_to_project(
932932
:rtype: list of strs
933933
"""
934934
if recursive_subfolders:
935-
logger.warning(
935+
logger.info(
936936
"When using recursive subfolder parsing same name annotations in different subfolders will overwrite each other."
937937
)
938938

939-
logger.warning(
939+
logger.info(
940940
"The JSON files should follow specific naming convention. For Vector projects they should be named '<image_name>___objects.json', for Pixel projects JSON file should be names '<image_name>___pixel.json' and also second mask image file should be present with the name '<image_name>___save.png'. In both cases image with <image_name> should be already present on the platform."
941941
)
942942

943-
logger.warning("Existing annotations will be overwritten.")
943+
logger.info("Existing annotations will be overwritten.")
944944
if not isinstance(project, dict):
945945
project = get_project_metadata(project)
946946

@@ -1155,14 +1155,14 @@ def upload_preannotations_from_folder_to_project(
11551155
):
11561156
"""Finds and uploads all JSON files in the folder_path as pre-annotations to the project.
11571157
1158-
WARNING: The JSON files should follow specific naming convention. For Vector
1158+
The JSON files should follow specific naming convention. For Vector
11591159
projects they should be named "<image_filename>___objects.json" (e.g., if
11601160
image is cats.jpg the annotation filename should be cats.jpg___objects.json), for Pixel projects
11611161
JSON file should be named "<image_filename>___pixel.json" and also second mask
11621162
image file should be present with the name "<image_name>___save.png". In both cases
11631163
image with <image_name> should be already present on the platform.
11641164
1165-
WARNING: Existing pre-annotations will be overwritten.
1165+
Existing pre-annotations will be overwritten.
11661166
11671167
:param project: project name or metadata of the project to upload pre-annotations to
11681168
:type project: str or dict
@@ -1177,14 +1177,14 @@ def upload_preannotations_from_folder_to_project(
11771177
:rtype: list of strs
11781178
"""
11791179
if recursive_subfolders:
1180-
logger.warning(
1180+
logger.info(
11811181
"When using recursive subfolder parsing same name pre-annotations in different subfolders will overwrite each other."
11821182
)
1183-
logger.warning(
1183+
logger.info(
11841184
"The JSON files should follow specific naming convention. For Vector projects they should be named '<image_name>___objects.json', for Pixel projects JSON file should be names '<image_name>___pixel.json' and also second mask image file should be present with the name '<image_name>___save.png'. In both cases image with <image_name> should be already present on the platform."
11851185
)
11861186

1187-
logger.warning(
1187+
logger.info(
11881188
"Identically named existing pre-annotations will be overwritten."
11891189
)
11901190
if not isinstance(project, dict):

superannotate/input_converters/conversion.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ def import_annotation_format(
321321
:type input_dir: str
322322
:param output_dir: Path to the folder, where you want to have converted dataset.
323323
:type output_dir: str
324-
:param dataset_format: Annotation format to convert SuperAnnotate annotation format. Available candidates are: ["COCO", "VOC", "LabelBox", "DataLoop",
324+
:param dataset_format: Annotation format to convert SuperAnnotate annotation format. Available candidates are: ["COCO", "VOC", "LabelBox", "DataLoop",
325325
"Supervisely", 'VGG', 'YOLO', 'SageMake', 'VoTT', 'GoogleCloud']
326326
:type dataset_format: str
327327
:param dataset_name: Name of the json file in the input_dir, which should be converted.

superannotate/input_converters/import_to_sa_conversions.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
"""
2-
Module which will run converters and convert from other
2+
Module which will run converters and convert from other
33
annotation formats to superannotate annotation format
44
"""
5-
import sys
6-
import os
75
import glob
8-
import shutil
96
import logging
10-
from argparse import Namespace
7+
import os
8+
import shutil
119

1210
from .converters.converters import Converter
1311
from ..exceptions import SABaseException

0 commit comments

Comments
 (0)