Skip to content

Commit 4430cac

Browse files
committed
json corrected
1 parent bc3adf9 commit 4430cac

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+150
-169
lines changed

superannotate/input_converters/converters/coco_converters/coco_api.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def _area(bitmask):
103103

104104
def _toBbox(bitmask):
105105
contours, _ = cv2.findContours(
106-
bitmask.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
106+
bitmask.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE
107107
)
108108
segments = []
109109
for contour in contours:
@@ -115,7 +115,7 @@ def _toBbox(bitmask):
115115
ymin = min(segments[1::2])
116116
ymax = max(segments[1::2])
117117

118-
return [xmin, ymin, xmax - xmin, ymax - ymin]
118+
return [xmin, ymin, xmax - xmin + 1, ymax - ymin + 1]
119119

120120

121121
def _merge(list_of_bitmask):
@@ -130,12 +130,13 @@ def _merge(list_of_bitmask):
130130
def _polytoMask(polygons, height, width):
131131
masks = []
132132
for polygon in polygons:
133-
polygon = np.round(polygon)
134-
bitmask = np.zeros((height, width)).astype(np.uint8)
133+
polygon = np.array(polygon, dtype=np.uint16)
135134
pts = np.array(
136135
[polygon[2 * i:2 * (i + 1)] for i in range(len(polygon) // 2)],
137136
dtype=np.int32
138137
)
138+
bitmask = np.zeros((height, width)).astype(np.uint8)
139139
cv2.fillPoly(bitmask, [pts], 1)
140+
140141
masks.append(bitmask)
141142
return masks

superannotate/input_converters/converters/coco_converters/coco_strategies.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,19 @@ def _prepare_single_image_commons_pixel(self, id_, json_path):
9696
rm_len = len('___pixel.json')
9797

9898
sa_json = json.load(open(json_path))
99-
# sa_ann_json = json.load(open(json_path))
10099
sa_ann_json = sa_json['instances']
101100

102101
sa_bluemask_path = str(json_path)[:-rm_len] + '___save.png'
103102

104-
# image_info = self.__make_image_info(json_path, id_, self.project_type)
105103
image_info = self.__make_image_info(id_, sa_json['metadata'])
106104

105+
if image_info['height'] is None or image_info['width'] is None:
106+
img_height, img_width = self.get_dimensions(
107+
json_path, self.project_type
108+
)
109+
image_info['height'] = img_height
110+
image_info['width'] = img_width
111+
107112
sa_bluemask_rgb = np.asarray(
108113
Image.open(sa_bluemask_path).convert('RGB'), dtype=np.uint32
109114
)
@@ -121,15 +126,16 @@ def _prepare_single_image_commons_pixel(self, id_, json_path):
121126

122127
return res
123128

124-
# def __make_image_info(self, json_path, id_, source_type):
125-
# if source_type == 'Pixel':
126-
# rm_len = len('___pixel.json')
127-
# elif source_type == 'Vector':
128-
# rm_len = len('___objects.json')
129+
def get_dimensions(self, json_path, source_type):
130+
if source_type == 'Pixel':
131+
rm_len = len('___pixel.json')
132+
elif source_type == 'Vector':
133+
rm_len = len('___objects.json')
129134

130-
# image_path = str(json_path)[:-rm_len]
135+
image_path = str(json_path)[:-rm_len]
136+
img_width, img_height = Image.open(image_path).size
137+
return img_height, img_width
131138

132-
# img_width, img_height = Image.open(image_path).size
133139
def __make_image_info(self, id_, sa_meta_json):
134140
image_info = {
135141
'id': id_,
@@ -144,11 +150,9 @@ def __make_image_info(self, id_, sa_meta_json):
144150
def _prepare_single_image_commons_vector(self, id_, json_path):
145151
ImgCommons = namedtuple('ImgCommons', ['image_info', 'sa_ann_json'])
146152

147-
# sa_ann_json = json.load(open(json_path))
148153
sa_json = json.load(open(json_path))
149154
sa_ann_json = sa_json['instances']
150155

151-
# image_info = self.__make_image_info(json_path, id_, self.project_type)
152156
image_info = self.__make_image_info(id_, sa_json['metadata'])
153157

154158
res = ImgCommons(image_info, sa_ann_json)

superannotate/input_converters/converters/coco_converters/coco_to_sa_pixel.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def coco_panoptic_segmentation_to_sa_pixel(coco_path, output_dir):
7575
'width': img_id_to_shape[str(annot['image_id'])]['width'],
7676
'height': img_id_to_shape[str(annot['image_id'])]['height']
7777
}
78-
json_template = _create_sa_json(sa_instances, metadata)
78+
json_template = _create_sa_json(sa_instances, sa_metadata)
7979
write_to_json(output_dir / file_name, json_template)
8080
(output_dir / ("%s.png" % annot_name)).unlink()
8181

superannotate/input_converters/converters/coco_converters/sa_pixel_to_coco.py

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import numpy as np
33

44
from .coco_api import (encode, _toBbox, _area)
5-
# from ....pycocotools_sa import mask as cocomask
65

76

87
def __instance_object_commons_per_instance(
@@ -24,11 +23,7 @@ def __instance_object_commons_per_instance(
2423
databytes, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE
2524
)
2625

27-
# coco_instance_mask = cocomask.encode(np.asfortranarray(instance_bitmask))
28-
# coco_instance_mask = encode(instance_bitmask.astype(np.uint8))
29-
# bbox = cocomask.toBbox(coco_instance_mask).tolist()
30-
bbox = list(_toBbox(instance_bitmask.astype(np.uint8)))
31-
# area = int(cocomask.area(coco_instance_mask))
26+
bbox = list(_toBbox(instance_bitmask))
3227
area = int(_area(instance_bitmask.astype(np.uint8)))
3328
return (bbox, area, contours, category_id, anno_id)
3429

@@ -96,14 +91,7 @@ def sa_pixel_to_coco_panoptic_segmentation(
9691
instance_bitmask = np.isin(flat_mask, parts)
9792
segment_id = next(id_generator)
9893
ann_mask[instance_bitmask] = segment_id
99-
# coco_instance_mask = cocomask.encode(
100-
# np.asfortranarray(instance_bitmask)
101-
# )
102-
# bbox = cocomask.toBbox(coco_instance_mask).tolist()
103-
# area = int(cocomask.area(coco_instance_mask))
104-
105-
# coco_instance_mask = encode(instance_bitmask.astype(np.uint8))
106-
bbox = list(_toBbox(instance_bitmask.astype(np.uint8)))
94+
bbox = list(_toBbox(instance_bitmask))
10795
area = int(_area(instance_bitmask.astype(np.uint8)))
10896

10997
segment_info = {

superannotate/input_converters/converters/coco_converters/sa_vector_to_coco.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import json
22
import logging
3-
4-
from .coco_api import (encode, _toBbox, _merge, _area, _polytoMask)
5-
6-
from ....pycocotools_sa import mask as cocomask
3+
import numpy as np
4+
import cv2
5+
from .coco_api import (_toBbox, _merge, _area, _polytoMask)
76

87
logger = logging.getLogger("superannotate-python-sdk")
98

@@ -82,12 +81,6 @@ def sa_vector_to_coco_instance_segmentation(
8281
for cat_id, polygons in polygon_group.items():
8382
anno_id = next(id_generator)
8483
try:
85-
# masks = cocomask.frPyObjects(
86-
# polygons, image_info['height'], image_info['width']
87-
# )
88-
# mask = cocomask.merge(masks)
89-
# area = int(cocomask.area(mask))
90-
# bbox = cocomask.toBbox(mask).tolist()
9184
masks = _polytoMask(
9285
polygons, image_info['height'], image_info['width']
9386
)
@@ -165,7 +158,7 @@ def __make_annotations(template, id_generator, cat_id, image_id):
165158
images = []
166159

167160
for path_ in json_paths:
168-
json_data = __load_one_json(path_)
161+
json_data = __load_one_json(path_)['instances']
169162

170163
for instance in json_data:
171164
if instance['type'] == 'template' and 'templateId' not in instance:

superannotate/input_converters/converters/dataloop_converters/dataloop_to_sa_vector.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ def dataloop_to_sa(input_dir, task, output_dir):
2525
comment_type = 'note'
2626

2727
for json_file in json_data:
28+
dl_data = json.load(open(json_file))
29+
2830
sa_metadata = {}
2931
if 'itemMetadata' in dl_data and 'system' in dl_data['itemMetadata']:
3032
temp = dl_data['itemMetadata']['system']
@@ -36,8 +38,6 @@ def dataloop_to_sa(input_dir, task, output_dir):
3638
sa_tags = []
3739
sa_comments = []
3840

39-
dl_data = json.load(open(json_file))
40-
4141
for ann in dl_data['annotations']:
4242
if ann['type'] in instance_types:
4343
classes = _update_classes_dict(
@@ -91,9 +91,7 @@ def dataloop_to_sa(input_dir, task, output_dir):
9191
sa_comment = _create_comment(points, comments)
9292
sa_comments.append(sa_comment)
9393
elif ann['type'] == tags_type:
94-
sa_tags.append(ann['labe'])
95-
# sa_tags = {'type': 'tag', 'name': ann['label']}
96-
# sa_instances.append(sa_tags)
94+
sa_tags.append(ann['label'])
9795

9896
if 'name' in sa_metadata:
9997
file_name = '%s___objects.json' % sa_metadata['name']

superannotate/input_converters/converters/supervisely_converters/supervisely_to_sa_vector.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ def supervisely_to_sa(json_files, class_id_map, task, output_dir):
1919
]
2020

2121
for json_file in json_files:
22+
json_data = json.load(open(json_file))
2223
file_name = '%s___objects.json' % Path(json_file).stem
2324
sa_metadata = {
2425
'name': Path(json_file).stem,
2526
'width': json_data['size']['width'],
2627
'height': json_data['size']['height']
2728
}
2829

29-
json_data = json.load(open(json_file))
3030
sa_instances = []
3131
for obj in json_data['objects']:
3232
if 'classTitle' in obj and obj['classTitle'] in class_id_map.keys():

superannotate/input_converters/sa_conversion.py

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import cv2
99
import numpy as np
1010

11-
from ..common import blue_color_generator, hex_to_rgb
11+
from ..common import (blue_color_generator, hex_to_rgb, write_to_json)
1212
from ..exceptions import SABaseException
1313

1414
logger = logging.getLogger("superannotate-python-sdk")
@@ -18,8 +18,8 @@ def copy_file(src_path, dst_path):
1818
shutil.copy(src_path, dst_path)
1919

2020

21-
def from_pixel_to_vector(json_paths):
22-
sa_jsons = {}
21+
def from_pixel_to_vector(json_paths, output_dir):
22+
img_names = []
2323
for json_path in json_paths:
2424
file_name = str(json_path.name
2525
).replace('___pixel.json', '___objects.json')
@@ -28,13 +28,14 @@ def from_pixel_to_vector(json_paths):
2828
img = cv2.imread(mask_name)
2929
H, W, _ = img.shape
3030

31-
sa_loader = []
32-
instances = json.load(open(json_path))
31+
sa_json = json.load(open(json_path))
32+
instances = sa_json['instances']
3333
idx = 0
34+
sa_instances = []
3435
for instance in instances:
3536
if 'parts' not in instance.keys():
3637
if 'type' in instance.keys() and instance['type'] == 'meta':
37-
sa_loader.append(instance)
38+
sa_instances.append(instance)
3839
continue
3940

4041
parts = instance['parts']
@@ -68,22 +69,24 @@ def from_pixel_to_vector(json_paths):
6869
temp['groupId'] = group_id
6970
temp['type'] = 'polygon'
7071
temp['points'] = polygon
71-
sa_loader.append(temp.copy())
72+
sa_instances.append(temp.copy())
7273
temp['type'] = 'bbox'
7374
temp['points'] = {
7475
'x1': min(polygon[::2]),
7576
'x2': max(polygon[::2]),
7677
'y1': min(polygon[1::2]),
7778
'y2': max(polygon[1::2])
7879
}
79-
sa_loader.append(temp.copy())
80+
sa_instances.append(temp.copy())
8081

81-
sa_jsons[file_name] = {'json': sa_loader, 'mask': None}
82-
return sa_jsons
82+
sa_json['instances'] = sa_instances
83+
write_to_json(output_dir / file_name, sa_json)
84+
img_names.append(file_name.replace('___objects.json', ''))
85+
return img_names
8386

8487

85-
def from_vector_to_pixel(json_paths):
86-
sa_jsons = {}
88+
def from_vector_to_pixel(json_paths, output_dir):
89+
img_names = []
8790
for json_path in json_paths:
8891
file_name = str(json_path.name
8992
).replace('___objects.json', '___pixel.json')
@@ -92,10 +95,11 @@ def from_vector_to_pixel(json_paths):
9295
img = cv2.imread(img_name)
9396
H, W, _ = img.shape
9497

98+
sa_json = json.load(open(json_path))
99+
instances = sa_json['instances']
95100
mask = np.zeros((H, W, 4))
96-
sa_loader = []
97101

98-
instances = json.load(open(json_path))
102+
sa_instances = []
99103
blue_colors = blue_color_generator(len(instances))
100104
instances_group = {}
101105
for idx, instance in enumerate(instances):
@@ -105,7 +109,7 @@ def from_vector_to_pixel(json_paths):
105109
else:
106110
instances_group[instance['groupId']] = [instance]
107111
elif instance['type'] == 'meta':
108-
sa_loader.append(instance)
112+
sa_instances.append(instance)
109113

110114
idx = 0
111115
for key, instances in instances_group.items():
@@ -127,7 +131,7 @@ def from_vector_to_pixel(json_paths):
127131
del instance['pointLabels']
128132
del instance['groupId']
129133
instance['parts'] = [{'color': blue_colors[idx]}]
130-
sa_loader.append(instance.copy())
134+
sa_instances.append(instance.copy())
131135
idx += 1
132136
else:
133137
parts = []
@@ -150,45 +154,38 @@ def from_vector_to_pixel(json_paths):
150154
del instance['pointLabels']
151155
del instance['groupId']
152156
instance['parts'] = parts
153-
sa_loader.append(instance.copy())
157+
sa_instances.append(instance.copy())
154158

155-
sa_jsons[file_name] = {'json': sa_loader, 'mask': mask}
159+
mask_name = file_name.replace('___pixel.json', '___save.png')
160+
cv2.imwrite(str(output_dir.joinpath(mask_name)), mask)
156161

157-
return sa_jsons
162+
sa_json['instances'] = sa_instances
163+
write_to_json(output_dir / file_name, sa_json)
164+
img_names.append(file_name.replace('___pixel.json', ''))
165+
return img_names
158166

159167

160168
def sa_convert_project_type(input_dir, output_dir):
161-
json_generator = input_dir.glob('*.json')
162-
json_paths = list(json_generator)
169+
json_paths = list(input_dir.glob('*.json'))
170+
171+
output_dir.joinpath('classes').mkdir(parents=True)
172+
copy_file(
173+
input_dir.joinpath('classes', 'classes.json'),
174+
output_dir.joinpath('classes', 'classes.json')
175+
)
163176

164-
extension = ''
165177
if '___pixel.json' in json_paths[0].name:
166-
sa_jsons = from_pixel_to_vector(json_paths)
167-
extension = '___objects.json'
178+
img_names = from_pixel_to_vector(json_paths, output_dir)
168179
elif '__objects.json' in json_paths[0].name:
169-
sa_jsons = from_vector_to_pixel(json_paths)
170-
extension = '___pixel.json'
180+
img_names = from_vector_to_pixel(json_paths, output_dir)
171181
else:
172182
raise SABaseException(
173183
0,
174184
"'input_dir' should contain JSON files with '[IMAGE_NAME]___objects.json' or '[IMAGE_NAME]___pixel.json' names structure."
175185
)
176186

177-
output_dir.joinpath('classes').mkdir(parents=True)
178-
copy_file(
179-
input_dir.joinpath('classes', 'classes.json'),
180-
output_dir.joinpath('classes', 'classes.json')
181-
)
182-
183-
for key, value in sa_jsons.items():
184-
with open(output_dir.joinpath(key), 'w') as fw:
185-
json.dump(value['json'], fw, indent=2)
186-
file_name = key.replace(extension, '')
187-
copy_file(input_dir.joinpath(file_name), output_dir.joinpath(file_name))
188-
189-
if value['mask'] is not None:
190-
mask_name = key.replace(extension, '___save.png')
191-
cv2.imwrite(str(output_dir.joinpath(mask_name)), value['mask'])
187+
for img_name in img_names:
188+
copy_file(input_dir.joinpath(img_name), output_dir.joinpath(img_name))
192189

193190

194191
def split_coco(

tests/converter_test/COCO/input/fromSuperAnnotate/cats_dogs_panoptic_segm/cat1.jpg___pixel.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"metadata": {
33
"name": "cat1.jpg",
4-
"width": null,
5-
"height": null,
4+
"width": 2000,
5+
"height": 2000,
66
"status": null,
77
"pinned": null,
88
"isPredicted": null,

0 commit comments

Comments
 (0)