Skip to content

Commit 4bbedb9

Browse files
committed
CLI upload preannotations
1 parent 44f7beb commit 4bbedb9

File tree

6 files changed

+57
-40
lines changed

6 files changed

+57
-40
lines changed

docs/source/cli.rst

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ To upload preannotations from folder to project use:
9696
.. code-block:: bash
9797
9898
superannotate upload-preannotations --project <project_name> --folder <folder_path>
99-
[--format "COCO" or "SA"]
99+
[--format "COCO" or "SA"] [--dataset-name "<dataset_name_for_COCO_projects>"]
100+
[--task "<task_type_for_COCO_projects>]
100101
101102
102103
Optional argument *format* accepts input preannotation format. It can have COCO or SuperAnnotate values.
@@ -113,12 +114,12 @@ To upload annotations from folder to project use:
113114
114115
.. code-block:: bash
115116
116-
superannotate upload-preannotations --project <project_name> --folder <folder_path>
117-
[--recursive]
118-
119-
If optional argument *recursive* is given then subfolders of :file:`<folder_path>` are also recursively
120-
scanned for available preannotations.
117+
superannotate upload-annotations --project <project_name> --folder <folder_path>
118+
[--format "COCO" or "SA"] [--dataset-name "<dataset_name_for_COCO_projects>"]
119+
[--task "<task_type_for_COCO_projects>]
121120
121+
Optional argument *format* accepts input preannotation format. It can have COCO or SuperAnnotate values.
122+
If the argument is not given then SuperAnnotate (the native preannotation format) assumed.
122123

123124
----------
124125

superannotate/__main__.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
logger = logging.getLogger("superannotate-python-sdk")
1313

1414

15-
def ask_token(args):
15+
def ask_token():
1616
config_dir = Path.home() / ".superannotate"
1717
config_filename = "config.json"
1818
config_file = config_dir / config_filename
@@ -50,8 +50,10 @@ def main():
5050
video_upload(further_args)
5151
elif command == "upload-preannotations":
5252
preannotations_upload(further_args)
53+
elif command == "upload-annotations":
54+
preannotations_upload(further_args, annotations=True)
5355
elif command == "init":
54-
ask_token(further_args)
56+
ask_token()
5557
elif command == "export-project":
5658
export_project(further_args)
5759
elif command == "version":
@@ -64,7 +66,7 @@ def _list_str(values):
6466
return values.split(',')
6567

6668

67-
def preannotations_upload(args):
69+
def preannotations_upload(args, annotations=False):
6870
parser = argparse.ArgumentParser()
6971
parser.add_argument(
7072
'--project', required=True, help='Project name to upload'
@@ -84,7 +86,7 @@ def preannotations_upload(args):
8486
parser.add_argument(
8587
'--dataset-name',
8688
required=False,
87-
help='Input preannotations dataset name for COCO projects'
89+
help='Input annotations dataset name for COCO projects'
8890
)
8991
parser.add_argument(
9092
'--task',
@@ -97,7 +99,7 @@ def preannotations_upload(args):
9799
if args.format != "SuperAnnotate":
98100
if args.format != "COCO":
99101
raise sa.SABaseException(
100-
0, "Not supported preannotations format " + args.format
102+
0, "Not supported annotations format " + args.format
101103
)
102104
if args.dataset_name is None:
103105
raise sa.SABaseException(
@@ -107,7 +109,7 @@ def preannotations_upload(args):
107109
raise sa.SABaseException(
108110
0, "Task name should be present for COCO format upload."
109111
)
110-
logger.info("Preannotations in format %s.", args.format)
112+
logger.info("Annotations in format %s.", args.format)
111113
project_type = sa.project_type_int_to_str(
112114
sa.get_project_metadata(args.project)["type"]
113115
)
@@ -123,9 +125,14 @@ def preannotations_upload(args):
123125
)
124126
args.folder = tempdir_path
125127

126-
sa.upload_preannotations_from_folder_to_project(
127-
project=args.project, folder_path=args.folder
128-
)
128+
if annotations:
129+
sa.upload_annotations_from_folder_to_project(
130+
project=args.project, folder_path=args.folder
131+
)
132+
else:
133+
sa.upload_preannotations_from_folder_to_project(
134+
project=args.project, folder_path=args.folder
135+
)
129136

130137

131138
def video_upload(args):

superannotate/db/project_images.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def upload_image_to_project(
100100
s3_resource = s3_session.resource('s3')
101101
bucket = s3_resource.Bucket(res["bucket"])
102102
orig_image, lores_image, huge_image, thumbnail_image = get_image_array_to_upload(
103-
img, project["type"], image_quality_in_editor
103+
img, image_quality_in_editor
104104
)
105105
key = prefix + f'{img_name}'
106106
try:

superannotate/db/projects.py

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ def create_project(project_name, project_description, project_type):
8181
)
8282
return res
8383

84+
8485
def create_project_like_project(
8586
project_name,
8687
from_project,
@@ -93,9 +94,12 @@ def create_project_like_project(
9394
"""Deprecated. Function name changed to clone_project.
9495
"""
9596
logger.warning("Deprecated. Function name changed to clone_project.")
96-
clone_project(project_name, from_project, project_description,
97-
copy_annotation_classes, copy_settings,
98-
copy_workflow, copy_project_contributors)
97+
clone_project(
98+
project_name, from_project, project_description,
99+
copy_annotation_classes, copy_settings, copy_workflow,
100+
copy_project_contributors
101+
)
102+
99103

100104
def clone_project(
101105
project_name,
@@ -584,25 +588,30 @@ def upload_images_from_folder_to_project(
584588
)
585589

586590

587-
def get_image_array_to_upload(
588-
byte_io_orig, project_type, image_quality_in_editor
589-
):
591+
def get_image_array_to_upload(byte_io_orig, image_quality_in_editor):
590592
Image.MAX_IMAGE_PIXELS = None
591593
im = Image.open(byte_io_orig)
592594
im_format = im.format
593-
im = im.convert("RGB")
594595
width, height = im.size
595596

596-
if not image_quality_in_editor == 100 or im_format != "JPEG":
597-
byte_io_lores = io.BytesIO()
598-
im.save(
599-
byte_io_lores,
600-
'JPEG',
601-
subsampling=0 if image_quality_in_editor > 60 else 2,
602-
quality=image_quality_in_editor
603-
)
604-
else:
597+
if image_quality_in_editor == 100 and im_format in ['JPEG', 'JPG']:
605598
byte_io_lores = io.BytesIO(byte_io_orig.getbuffer())
599+
else:
600+
byte_io_lores = io.BytesIO()
601+
bg = Image.new('RGBA', im.size, (255, 255, 255))
602+
im = im.convert("RGBA")
603+
bg.paste(im, mask=im)
604+
bg = bg.convert('RGB')
605+
if image_quality_in_editor == 100:
606+
bg.save(
607+
byte_io_lores,
608+
'JPEG',
609+
quality=image_quality_in_editor,
610+
subsampling=0
611+
)
612+
else:
613+
bg.save(byte_io_lores, 'JPEG', quality=image_quality_in_editor)
614+
im = bg
606615

607616
byte_io_huge = io.BytesIO()
608617
hsize = int(height * 600.0 / width)
@@ -611,7 +620,7 @@ def get_image_array_to_upload(
611620
byte_io_thumbs = io.BytesIO()
612621
thumbnail_size = (128, 96)
613622
background = Image.new('RGB', thumbnail_size, "black")
614-
im.thumbnail(thumbnail_size)
623+
im.thumbnail(thumbnail_size, Image.ANTIALIAS)
615624
(w, h) = im.size
616625
background.paste(
617626
im, ((thumbnail_size[0] - w) // 2, (thumbnail_size[1] - h) // 2)
@@ -672,7 +681,7 @@ def __upload_images_to_aws_thread(
672681
file = io.BytesIO(f.read())
673682
try:
674683
orig_image, lores_image, huge_image, thumbnail_image = get_image_array_to_upload(
675-
file, project_type, image_quality_in_editor
684+
file, image_quality_in_editor
676685
)
677686
bucket.put_object(Body=orig_image, Key=key)
678687
bucket.put_object(Body=lores_image, Key=key + '___lores.jpg')

superannotate/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "2.3.0"
1+
__version__ = "2.3.1"

tests/test_preannotation_upload_cli.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
@pytest.mark.parametrize(
1111
"project_type,name,description,from_folder", [
1212
(
13-
"Vector", "Example Project test vector preannotation cli upload",
13+
"Vector", "Example Project test0 vector preannotation cli upload",
1414
"test vector", Path("./tests/sample_project_vector")
1515
),
1616
(
17-
"Pixel", "Example Project test pixel preannotation cli upload",
17+
"Pixel", "Example Project test0 pixel preannotation cli upload",
1818
"test pixel", Path("./tests/sample_project_pixel")
1919
)
2020
]
@@ -54,7 +54,7 @@ def test_preannotation_folder_upload_download_cli(
5454

5555
def test_preannotation_folder_upload_download_cli_vector_COCO(tmpdir):
5656
project_type = "Vector"
57-
name = "Example Project test vector preannotation cli upload coco vector"
57+
name = "Example Project test vector2 preannotation cli upload coco vector"
5858
description = "test"
5959
from_folder = "./tests/converter_test/COCO/input/toSuperAnnotate/keypoint_detection"
6060
task = "keypoint_detection"
@@ -92,7 +92,7 @@ def test_preannotation_folder_upload_download_cli_vector_COCO(tmpdir):
9292

9393
def test_preannotation_folder_upload_download_cli_vector_object_COCO(tmpdir):
9494
project_type = "Vector"
95-
name = "Example Project test vector preannotation cli upload coco object vector"
95+
name = "Example Project test vector1 preannotation cli upload coco object vector"
9696
description = "test"
9797
from_folder = "./tests/converter_test/COCO/input/toSuperAnnotate/instance_segmentation"
9898
task = "instance_segmentation"
@@ -120,7 +120,7 @@ def test_preannotation_folder_upload_download_cli_vector_object_COCO(tmpdir):
120120

121121
def test_preannotation_folder_upload_download_cli_pixel_object_COCO(tmpdir):
122122
project_type = "Pixel"
123-
name = "Example Project test pixel preannotation cli upload coco object pixel"
123+
name = "Example Project test pixel1 preannotation cli upload coco object pixel"
124124
description = "test"
125125
from_folder = "./tests/converter_test/COCO/input/toSuperAnnotate/panoptic_segmentation"
126126
task = "panoptic_segmentation"

0 commit comments

Comments
 (0)