Skip to content

Commit fda7544

Browse files
committed
refactored input converters
1 parent fef499b commit fda7544

File tree

16 files changed

+137
-253
lines changed

16 files changed

+137
-253
lines changed

superannotate/common.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import numpy as np
12
import functools
23
import logging
34
from pathlib import Path
@@ -138,3 +139,26 @@ def rgb_to_hex(rgb_tuple):
138139
"""Converts RGB values to HEX values
139140
"""
140141
return '#%02x%02x%02x' % rgb_tuple
142+
143+
144+
def blue_color_generator(n, hex_values=True):
145+
""" Blue colors generator for SuperAnnotate blue mask.
146+
"""
147+
hex_colors = []
148+
for i in range(n + 1):
149+
int_color = i * 15
150+
bgr_color = np.array(
151+
[
152+
int_color & 255, (int_color >> 8) & 255,
153+
(int_color >> 16) & 255, 255
154+
],
155+
dtype=np.uint8
156+
)
157+
hex_color = '#' + "{:02x}".format(
158+
bgr_color[2]
159+
) + "{:02x}".format(bgr_color[1], ) + "{:02x}".format(bgr_color[0])
160+
if hex_values:
161+
hex_colors.append(hex_color)
162+
else:
163+
hex_colors.append(hex_to_rgb(hex_color))
164+
return hex_colors[1:]

superannotate/input_converters/converters/coco_converters/coco_converter.py

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,14 @@
1414

1515

1616
class CoCoConverter(object):
17-
def __init__(
18-
self,
19-
dataset_name_,
20-
export_root_,
21-
project_type_,
22-
output_dir_,
23-
task_=None
24-
):
25-
self.project_type = project_type_
26-
self.dataset_name = dataset_name_
27-
self.export_root = export_root_
28-
self.output_dir = output_dir_
29-
self.task = task_
17+
def __init__(self, args):
18+
self.project_type = args.project_type
19+
self.dataset_name = args.dataset_name
20+
self.export_root = args.export_root
21+
self.output_dir = args.output_dir
22+
self.task = args.task
23+
self.direction = args.direction
24+
3025
self.failed_conversion_cnt = 0
3126

3227
def _create_single_category(self, item):

superannotate/input_converters/converters/coco_converters/coco_strategies.py

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,11 @@
1414
from .coco_to_sa_vector import coco_keypoint_detection_to_sa_vector, coco_instance_segmentation_to_sa_vector
1515

1616

17-
class PanopticConverterStrategy(CoCoConverter):
17+
class CocoPanopticConverterStrategy(CoCoConverter):
1818
name = "Panoptic converter"
1919

20-
def __init__(
21-
self, dataset_name, export_root, project_type, output_dir, direction
22-
):
23-
super().__init__(dataset_name, export_root, project_type, output_dir)
24-
self.direction = direction
20+
def __init__(self, args):
21+
super().__init__(args)
2522
self.__setup_conversion_algorithm()
2623

2724
def __setup_conversion_algorithm(self):
@@ -100,17 +97,11 @@ def to_sa_format(self):
10097
# loader = self.conversion_algorithm(json_data, self.output_dir)
10198

10299

103-
class ObjectDetectionStrategy(CoCoConverter):
100+
class CocoObjectDetectionStrategy(CoCoConverter):
104101
name = "ObjectDetection converter"
105102

106-
def __init__(
107-
self, dataset_name, export_root, project_type, output_dir, task,
108-
direction
109-
):
110-
self.direction = direction
111-
super().__init__(
112-
dataset_name, export_root, project_type, output_dir, task
113-
)
103+
def __init__(self, args):
104+
super().__init__(args)
114105
self.__setup_conversion_algorithm()
115106

116107
def __setup_conversion_algorithm(self):
@@ -220,16 +211,11 @@ def to_sa_format(self):
220211
# loader = self.conversion_algorithm(json_data, self.output_dir)
221212

222213

223-
class KeypointDetectionStrategy(CoCoConverter):
214+
class CocoKeypointDetectionStrategy(CoCoConverter):
224215
name = 'Keypoint Detection Converter'
225216

226-
def __init__(
227-
self, dataset_name, export_root, project_type, output_dir, direction
228-
):
229-
super().__init__(
230-
dataset_name, export_root, project_type, output_dir, direction
231-
)
232-
self.direction = direction
217+
def __init__(self, args):
218+
super().__init__(args)
233219
self.__setup_conversion_algorithm()
234220

235221
def __str__(self):

superannotate/input_converters/converters/coco_converters/coco_to_sa_pixel.py

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,12 @@
77
from panopticapi.utils import id2rgb
88
from tqdm import tqdm
99

10-
from ....common import hex_to_rgb
11-
12-
# def _rle_to_bitmask(coco_json, annotation):
13-
# return coco.annToMask(annotation)
14-
15-
16-
# Generates blue colors in range(n)
17-
def _blue_color_generator(n, hex_values=True):
18-
hex_colors = []
19-
for i in range(n):
20-
int_color = i * 15
21-
bgr_color = np.array(
22-
[
23-
int_color & 255, (int_color >> 8) & 255,
24-
(int_color >> 16) & 255, 255
25-
],
26-
dtype=np.uint8
27-
)
28-
hex_color = '#' + "{:02x}".format(
29-
bgr_color[2]
30-
) + "{:02x}".format(bgr_color[1], ) + "{:02x}".format(bgr_color[0])
31-
if hex_values:
32-
hex_colors.append(hex_color)
33-
else:
34-
hex_colors.append(hex_to_rgb(hex_color))
35-
return hex_colors
10+
from ....common import hex_to_rgb, blue_color_generator
3611

3712

3813
def coco_panoptic_segmentation_to_sa_pixel(coco_path, images_path):
3914
coco_json = json.load(open(coco_path))
40-
hex_colors = _blue_color_generator(len(coco_json["categories"]))
15+
hex_colors = blue_color_generator(len(coco_json["categories"]))
4116
annotate_list = coco_json["annotations"]
4217

4318
for annotate in tqdm(annotate_list, "Converting"):
@@ -55,18 +30,18 @@ def coco_panoptic_segmentation_to_sa_pixel(coco_path, images_path):
5530
H, W, C = img.shape
5631
img = img.reshape((H * W, C))
5732
segments = annotate["segments_info"]
58-
hex_colors = _blue_color_generator(len(segments) + 1)
33+
hex_colors = blue_color_generator(len(segments))
5934

6035
out_json = []
6136
for i, seg in enumerate(segments):
6237
img[np.all(img == id2rgb(seg["id"]),
63-
axis=1)] = hex_to_rgb(hex_colors[i + 1])
38+
axis=1)] = hex_to_rgb(hex_colors[i])
6439
dd = {
6540
"classId": seg["category_id"],
6641
"probability": 100,
6742
"visible": True,
6843
"parts": [{
69-
"color": hex_colors[i + 1]
44+
"color": hex_colors[i]
7045
}],
7146
"attributes": [],
7247
"attributeNames": [],
@@ -103,11 +78,15 @@ def coco_instance_segmentation_to_sa_pixel(coco_path, images_path):
10378
}
10479

10580
sa_json = {}
106-
for annot in tqdm(coco_json['annotations'], "Convertring annotations"):
81+
hexcolors = blue_color_generator(len(coco_json['annotations']))
82+
for i, annot in enumerate(coco_json['annotations']):
10783
if str(annot['image_id']) not in images_dict:
10884
continue
109-
color = np.random.choice(range(256), size=3)
110-
hexcolor = "#%02x%02x%02x" % tuple(color)
85+
86+
hexcolor = hexcolors[images_dict[str(annot['image_id'])]['segments_num']
87+
]
88+
color = hex_to_rgb(hexcolor)
89+
images_dict[str(annot['image_id'])]['segments_num'] += 1
11190

11291
images_dict[str(annot['image_id']
11392
)]['mask'][maskUtils.decode(annot['segmentation']) == 1

superannotate/input_converters/converters/converters.py

Lines changed: 29 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,10 @@
11
'''
2-
This may look over-engineered at this point however the idea is the following:
3-
1. We eventually might want to convert to and from other formats than COCO
4-
2. For each of these formats (COCO included) there should be different strategies
5-
for conversion. In COCO's case there are 5
6-
1.1 Panoptic
7-
1.2 Object Detection
8-
1.3 Stuff Detection
9-
1.4 Keypoint Detection
10-
1.5 Image Captioning
11-
3. We will have a general Converter object will not care about the format or the
12-
conversion strategy. It has to methods:
13-
3.1 convert from sa format to desired format` convert_from_sa()
14-
3.2 convert from some format to sa format` convert_to_sa()
15-
4. This object will receive the strategy from outside and will convert according to
2+
3+
This object will receive the strategy from outside and will convert according to
164
said strategy.
5+
176
'''
7+
188
import glob
199
import os
2010
import json
@@ -23,22 +13,17 @@
2313

2414
from tqdm import tqdm
2515

26-
from .coco_converters.coco_strategies import ObjectDetectionStrategy, KeypointDetectionStrategy, PanopticConverterStrategy
16+
from .coco_converters.coco_strategies import CocoObjectDetectionStrategy, CocoKeypointDetectionStrategy, CocoPanopticConverterStrategy
2717
from .voc_converters.voc_strategies import VocObjectDetectionStrategy
2818
from .labelbox_converters.labelbox_strategies import LabelBoxObjectDetectionStrategy
2919
from .dataloop_converters.dataloop_strategies import DataLoopObjectDetectionStrategy
3020
from .supervisely_converters.supervisely_strategies import SuperviselyObjectDetectionStrategy
3121

3222

3323
class Converter(object):
34-
def __init__(
35-
self, project_type, task, dataset_name, export_root, output_dir, method
36-
):
37-
self.export_root = export_root
38-
self.output_dir = output_dir
39-
self._select_strategy(
40-
project_type, task, dataset_name, export_root, output_dir, method
41-
)
24+
def __init__(self, args):
25+
self.output_dir = args.output_dir
26+
self._select_strategy(args)
4227

4328
def convert_from_sa(self):
4429
self.strategy.sa_to_output_format()
@@ -51,52 +36,29 @@ def convert_to_sa(self, platform):
5136
def __set_strategy(self, c_strategy):
5237
self.strategy = c_strategy
5338

54-
def _select_strategy(
55-
self, project_type, task, dataset_name, export_root, output_dir, method
56-
):
57-
if method.dataset_format == "COCO":
58-
if task == 'instance_segmentation' or task == 'object_detection':
59-
c_strategy = ObjectDetectionStrategy(
60-
dataset_name, export_root, project_type, output_dir, task,
61-
method.direction
62-
)
63-
if task == 'keypoint_detection':
64-
c_strategy = KeypointDetectionStrategy(
65-
dataset_name, export_root, project_type, output_dir,
66-
method.direction
67-
)
68-
if task == 'panoptic_segmentation':
69-
c_strategy = PanopticConverterStrategy(
70-
dataset_name, export_root, project_type, output_dir,
71-
method.direction
72-
)
73-
elif method.dataset_format == "VOC":
74-
if task == 'instance_segmentation' or task == 'object_detection':
75-
c_strategy = VocObjectDetectionStrategy(
76-
dataset_name, export_root, project_type, output_dir, task,
77-
method.direction
78-
)
79-
elif method.dataset_format == "LabelBox":
80-
if task == "object_detection" or task == 'instance_segmentation' or task == 'vector_annotation':
81-
c_strategy = LabelBoxObjectDetectionStrategy(
82-
dataset_name, export_root, project_type, output_dir, task,
83-
method.direction
84-
)
85-
elif method.dataset_format == "DataLoop":
86-
if task == 'object_detection' or task == 'instance_segmentation' or task == 'vector_annotation':
87-
c_strategy = DataLoopObjectDetectionStrategy(
88-
dataset_name, export_root, project_type, output_dir, task,
89-
method.direction
90-
)
91-
elif method.dataset_format == "Supervisely":
92-
if task == 'vector_annotation':
93-
c_strategy = SuperviselyObjectDetectionStrategy(
94-
dataset_name, export_root, project_type, output_dir, task,
95-
method.direction
96-
)
97-
39+
def _select_strategy(self, args):
40+
if args.dataset_format == "COCO":
41+
if args.task == 'instance_segmentation' or args.task == 'object_detection':
42+
c_strategy = CocoObjectDetectionStrategy(args)
43+
if args.task == 'keypoint_detection':
44+
c_strategy = CocoKeypointDetectionStrategy(args)
45+
if args.task == 'panoptic_segmentation':
46+
c_strategy = CocoPanopticConverterStrategy(args)
47+
elif args.dataset_format == "VOC":
48+
if args.task == 'instance_segmentation' or args.task == 'object_detection':
49+
c_strategy = VocObjectDetectionStrategy(args)
50+
elif args.dataset_format == "LabelBox":
51+
if args.task == "object_detection" or args.task == 'instance_segmentation' or args.task == 'vector_annotation':
52+
c_strategy = LabelBoxObjectDetectionStrategy(args)
53+
elif args.dataset_format == "DataLoop":
54+
if args.task == 'object_detection' or args.task == 'instance_segmentation' or args.task == 'vector_annotation':
55+
c_strategy = DataLoopObjectDetectionStrategy(args)
56+
elif args.dataset_format == "Supervisely":
57+
if args.task == 'vector_annotation':
58+
c_strategy = SuperviselyObjectDetectionStrategy(args)
9859
else:
9960
pass
61+
10062
self.__set_strategy(c_strategy)
10163

10264
def _merge_jsons(self, input_dir):
Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
class DataLoopConverter(object):
2-
def __init__(
3-
self, dataset_name_, exprot_root_, project_type_, output_dir_, task_
4-
):
5-
self.dataset_name = dataset_name_
6-
self.project_type = project_type_
7-
self.task = task_
8-
self.output_dir = output_dir_
9-
self.export_root = exprot_root_
2+
def __init__(self, args):
3+
self.dataset_name = args.dataset_name
4+
self.project_type = args.project_type
5+
self.task = args.task
6+
self.output_dir = args.output_dir
7+
self.export_root = args.export_root
8+
self.direction = args.direction
109

1110
def set_output_dir(self, output_dir_):
1211
self.output_dir = output_dir_
1312

14-
def set_export_root(self, exprot_root_):
15-
self.exprot_root = exprot_root_
13+
def set_export_root(self, export_root_):
14+
self.export_root = export_root_
1615

1716
def set_dataset_name(self, dname):
1817
self.dataset_name = dname

superannotate/input_converters/converters/dataloop_converters/dataloop_strategies.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,8 @@
88
class DataLoopObjectDetectionStrategy(DataLoopConverter):
99
name = "Object Detection converter"
1010

11-
def __init__(
12-
self, dataset_name, export_root, project_type, output_dir, task,
13-
direction
14-
):
15-
self.direction = direction
16-
super().__init__(
17-
dataset_name, export_root, project_type, output_dir, task
18-
)
19-
11+
def __init__(self, args):
12+
super().__init__(args)
2013
self.__setup_conversion_algorithm()
2114

2215
def __setup_conversion_algorithm(self):
Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
class LabelBoxConverter(object):
2-
def __init__(
3-
self, dataset_name_, exprot_root_, project_type_, output_dir_, task_
4-
):
5-
self.dataset_name = dataset_name_
6-
self.project_type = project_type_
7-
self.task = task_
8-
self.output_dir = output_dir_
9-
self.export_root = exprot_root_
2+
def __init__(self, args):
3+
self.dataset_name = args.dataset_name
4+
self.project_type = args.project_type
5+
self.task = args.task
6+
self.output_dir = args.output_dir
7+
self.export_root = args.export_root
8+
self.direction = args.direction
109

1110
def set_output_dir(self, output_dir_):
1211
self.output_dir = output_dir_
1312

14-
def set_export_root(self, exprot_root_):
15-
self.exprot_root = exprot_root_
13+
def set_export_root(self, export_root_):
14+
self.export_root = export_root_
1615

1716
def set_dataset_name(self, dname):
1817
self.dataset_name = dname

0 commit comments

Comments
 (0)