Skip to content

Commit 2d82336

Browse files
committed
coco updated
1 parent 960f2d7 commit 2d82336

File tree

16 files changed

+1936
-206
lines changed

16 files changed

+1936
-206
lines changed

superannotate/input_converters/conversion.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,11 @@ def export_annotation_format(
195195
196196
"""
197197

198+
if isinstance(input_dir, str):
199+
input_dir = Path(input_dir)
200+
if isinstance(output_dir, str):
201+
output_dir = Path(output_dir)
202+
198203
args = Namespace(
199204
input_dir=input_dir,
200205
output_dir=output_dir,
@@ -219,6 +224,7 @@ def import_annotation_format(
219224
project_type="Vector",
220225
task="object_detection",
221226
platform="Web",
227+
images_root=''
222228
):
223229
"""Converts other annotation formats to SuperAnnotate annotation format. Currently available (project_type, task) combinations for converter
224230
presented below:
@@ -344,6 +350,8 @@ def import_annotation_format(
344350
'vector_annotation' can be used to convert all annotations (point, ellipse, circule, cuboid and etc) to SuperAnnotate vector project.
345351
:param platform: SuperAnnotate has both 'Web' and 'Desktop' platforms. Choose to which platform you want convert. (Default: "Web")
346352
:type platform: str
353+
:param images_root: Additonal path to images directory in input_dir
354+
:type platform: str
347355
348356
"""
349357

@@ -360,6 +368,7 @@ def import_annotation_format(
360368
project_type=project_type,
361369
task=task,
362370
platform=platform,
371+
images_root=images_root
363372
)
364373

365374
_passes_sanity_checks(args)

superannotate/input_converters/converters/coco_converters/coco_converter.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,11 @@ def _create_skeleton(self):
9696
return out_json
9797

9898
def _load_sa_jsons(self):
99-
jsons = []
10099
if self.project_type == 'Pixel':
101-
jsons = glob.glob(os.path.join(self.export_root, '*pixel.json'))
100+
jsons_gen = self.export_root.glob('*pixel.json')
102101
elif self.project_type == 'Vector':
103-
jsons = glob.glob(os.path.join(self.export_root, '*objects.json'))
104-
102+
jsons_gen = self.export_root.glob('*objects.json')
103+
jsons = [path for path in jsons_gen]
105104
self.set_num_converted(len(jsons))
106105
return jsons
107106

@@ -113,11 +112,12 @@ def _prepare_single_image_commons_pixel(self, id_, json_path):
113112
]
114113
)
115114
rm_len = len('___pixel.json')
116-
image_path = json_path[:-rm_len
117-
] + '___lores.jpg' # maybe not use low res files?
115+
image_path = str(
116+
json_path
117+
)[:-rm_len] + '___lores.jpg' # maybe not use low res files?
118118

119-
sa_ann_json = json.load(open(os.path.join(json_path)))
120-
sa_bluemask_path = os.path.join(json_path[:-rm_len] + '___save.png')
119+
sa_ann_json = json.load(open(json_path))
120+
sa_bluemask_path = str(json_path)[:-rm_len] + '___save.png'
121121

122122
image_info = self.__make_image_info(json_path, id_, self.project_type)
123123

@@ -144,12 +144,12 @@ def __make_image_info(self, json_path, id_, source_type):
144144
elif source_type == 'Vector':
145145
rm_len = len('___objects.json')
146146

147-
image_path = json_path[:-rm_len]
147+
image_path = str(json_path)[:-rm_len]
148148

149149
img_width, img_height = Image.open(image_path).size
150150
image_info = {
151151
'id': id_,
152-
'file_name': image_path[len(self.output_dir):],
152+
'file_name': Path(image_path).name,
153153
'height': img_height,
154154
'width': img_width,
155155
'license': 1

superannotate/input_converters/converters/coco_converters/coco_strategies.py

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from collections import namedtuple
55
from datetime import datetime
66

7+
from pathlib import Path
78
from panopticapi.utils import IdGenerator, id2rgb
89
from PIL import Image
910
from tqdm import tqdm
@@ -18,7 +19,7 @@
1819
coco_keypoint_detection_to_sa_vector, coco_object_detection_to_sa_vector
1920
)
2021
from .sa_pixel_to_coco import (
21-
sa_pixel_to_coco_instance_segmentation, sa_pixel_to_coco_object_detection,
22+
sa_pixel_to_coco_instance_segmentation,
2223
sa_pixel_to_coco_panoptic_segmentation
2324
)
2425
from .sa_vector_to_coco import (
@@ -44,34 +45,32 @@ def __setup_conversion_algorithm(self):
4445
def __str__(self, ):
4546
return '{} object'.format(self.name)
4647

47-
def _sa_to_coco_single(self, id_, json_path, id_generator):
48+
def _sa_to_coco_single(self, id_, json_path, id_generator, cat_id_map):
4849

4950
image_commons = self._prepare_single_image_commons(id_, json_path)
50-
res = self.conversion_algorithm(image_commons, id_generator)
51+
res = self.conversion_algorithm(image_commons, id_generator, cat_id_map)
5152

5253
return res
5354

5455
def sa_to_output_format(self):
5556
out_json = self._create_skeleton()
5657
out_json['categories'] = self._create_categories(
57-
os.path.join(self.export_root, 'classes_mapper.json')
58+
self.export_root / 'classes_mapper.json'
5859
)
5960

60-
panoptic_root = os.path.join(
61-
self.dataset_name, "panoptic_{}".format(self.dataset_name)
62-
)
61+
cat_id_map = json.load(open(self.export_root / 'classes_mapper.json'))
6362

6463
images = []
6564
annotations = []
6665
id_generator = self._make_id_generator()
67-
jsons = glob.glob(
68-
os.path.join(self.export_root, '*pixel.json'), recursive=True
69-
)
66+
67+
jsons_gen = self.export_root.glob('*pixel.json')
68+
jsons = [path for path in jsons_gen]
7069

7170
for id_, json_ in tqdm(enumerate(jsons, 1)):
72-
res = self._sa_to_coco_single(id_, json_, id_generator)
71+
res = self._sa_to_coco_single(id_, json_, id_generator, cat_id_map)
7372

74-
panoptic_mask = json_[:-len('___pixel.json')] + '.png'
73+
panoptic_mask = str(json_)[:-len('___pixel.json')] + '.png'
7574

7675
Image.fromarray(id2rgb(res[2])).save(panoptic_mask)
7776

@@ -88,16 +87,15 @@ def sa_to_output_format(self):
8887
out_json['images'] = images
8988
json_data = json.dumps(out_json, indent=4)
9089
with open(
91-
os.path.join(self.output_dir, '{}.json'.format(self.dataset_name)),
92-
'w+'
90+
self.output_dir / '{}.json'.format(self.dataset_name), 'w+'
9391
) as coco_json:
9492

9593
coco_json.write(json_data)
9694

9795
self.set_num_converted(len(jsons))
9896

9997
def to_sa_format(self):
100-
json_data = os.path.join(self.export_root, self.dataset_name + ".json")
98+
json_data = self.export_root / (self.dataset_name + ".json")
10199
sa_classes = self._create_sa_classes(json_data)
102100
sa_jsons = self.conversion_algorithm(json_data, self.output_dir)
103101
self.dump_output(sa_classes, sa_jsons)
@@ -137,7 +135,7 @@ def __setup_conversion_algorithm(self):
137135
def __str__(self, ):
138136
return '{} object'.format(self.name)
139137

140-
def _sa_to_coco_single(self, id_, json_path, id_generator):
138+
def _sa_to_coco_single(self, id_, json_path, id_generator, cat_id_map):
141139

142140
image_commons = self._prepare_single_image_commons(id_, json_path)
143141
annotations_per_image = []
@@ -166,23 +164,28 @@ def make_annotation(
166164
return annotation
167165

168166
res = self.conversion_algorithm(
169-
make_annotation, image_commons, id_generator
167+
make_annotation, image_commons, id_generator, cat_id_map
170168
)
171169
return res
172170

173171
def sa_to_output_format(self):
174172

175173
out_json = self._create_skeleton()
176174
out_json['categories'] = self._create_categories(
177-
os.path.join(self.export_root, 'classes_mapper.json')
175+
self.export_root / 'classes_mapper.json'
178176
)
177+
178+
cat_id_map = json.load(open(self.export_root / 'classes_mapper.json'))
179+
179180
jsons = self._load_sa_jsons()
180181
images = []
181182
annotations = []
182183
id_generator = self._make_id_generator()
183184
for id_, json_ in tqdm(enumerate(jsons)):
184185
try:
185-
res = self._sa_to_coco_single(id_, json_, id_generator)
186+
res = self._sa_to_coco_single(
187+
id_, json_, id_generator, cat_id_map
188+
)
186189
except Exception as e:
187190
raise
188191
images.append(res[0])
@@ -195,16 +198,15 @@ def sa_to_output_format(self):
195198

196199
json_data = json.dumps(out_json, indent=4)
197200
with open(
198-
os.path.join(self.output_dir, '{}.json'.format(self.dataset_name)),
199-
'w+'
201+
self.output_dir / '{}.json'.format(self.dataset_name), 'w+'
200202
) as coco_json:
201203
coco_json.write(json_data)
202204
print("NUMBER OF IMAGES FAILED TO CONVERT", self.failed_conversion_cnt)
203205

204206
self.set_num_converted(len(jsons))
205207

206208
def to_sa_format(self):
207-
json_data = os.path.join(self.export_root, self.dataset_name + ".json")
209+
json_data = self.export_root / (self.dataset_name + ".json")
208210
sa_classes = self._create_sa_classes(json_data)
209211
sa_jsons = self.conversion_algorithm(json_data, self.output_dir)
210212
self.dump_output(sa_classes, sa_jsons)
@@ -232,12 +234,21 @@ def __make_image_info(self, json_path, id_, source_type):
232234
elif source_type == 'Vector':
233235
rm_len = len('___objects.json')
234236

235-
image_path = json_path[:-rm_len]
237+
img_width, img_height = 0, 0
238+
json_data = json.load(open(json_path))
239+
for annot in json_data:
240+
if 'type' in annot and annot['type'] == 'meta':
241+
img_height = annot['height']
242+
img_width = annot['width']
243+
244+
image_path = str(json_path)[:-rm_len]
245+
246+
if img_width == 0 and img_height == 0:
247+
img_width, img_height = Image.open(image_path).size
236248

237-
img_width, img_height = Image.open(image_path).size
238249
image_info = {
239250
'id': id_,
240-
'file_name': image_path[len(self.output_dir):],
251+
'file_name': Path(image_path).name,
241252
'height': img_height,
242253
'width': img_width,
243254
'license': 1
@@ -266,15 +277,14 @@ def sa_to_output_format(self):
266277
json_data = json.dumps(out_json, indent=4)
267278

268279
with open(
269-
os.path.join(self.output_dir, '{}.json'.format(self.dataset_name)),
270-
'w+'
280+
self.output_dir / '{}.json'.format(self.dataset_name), 'w+'
271281
) as coco_json:
272282
coco_json.write(json_data)
273283

274284
self.set_num_converted(len(out_json['images']))
275285

276286
def to_sa_format(self):
277-
json_data = os.path.join(self.export_root, self.dataset_name + ".json")
287+
json_data = self.export_root / (self.dataset_name + ".json")
278288
sa_classes = self._create_sa_classes(json_data)
279289
sa_jsons = self.conversion_algorithm(json_data, self.output_dir)
280290
self.dump_output(sa_classes, sa_jsons)

superannotate/input_converters/converters/coco_converters/coco_to_sa_pixel.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import cv2
55
import numpy as np
6+
from pathlib import Path
67
import pycocotools.mask as maskUtils
78
from panopticapi.utils import id2rgb
89
from tqdm import tqdm
@@ -39,12 +40,12 @@ def coco_panoptic_segmentation_to_sa_pixel(coco_path, images_path):
3940

4041
sa_jsons = {}
4142
for annotate in tqdm(annotate_list, "Converting"):
42-
annot_name = os.path.splitext(annotate["file_name"])[0]
43-
img_cv = cv2.imread(os.path.join(images_path, annot_name + ".png"))
43+
annot_name = Path(annotate["file_name"]).stem
44+
img_cv = cv2.imread(str(images_path / (annot_name + ".png")))
4445
if img_cv is None:
4546
print(
4647
"'{}' file dosen't exist!".format(
47-
os.path.join(images_path, annot_name + ".png")
48+
images_path / (annot_name + ".png")
4849
)
4950
)
5051
continue
@@ -74,13 +75,11 @@ def coco_panoptic_segmentation_to_sa_pixel(coco_path, images_path):
7475
out_json.append(dd)
7576

7677
img = cv2.cvtColor(img.reshape((H, W, C)), cv2.COLOR_RGB2BGR)
77-
cv2.imwrite(
78-
os.path.join(images_path, annot_name + ".jpg___save.png"), img
79-
)
78+
cv2.imwrite(str(images_path / (annot_name + ".jpg___save.png")), img)
8079

8180
file_name = annot_name + ".jpg___pixel.json"
8281
sa_jsons[file_name] = out_json
83-
os.remove(os.path.join(images_path, annot_name + ".png"))
82+
(images_path / (annot_name + ".png")).unlink()
8483
return sa_jsons
8584

8685

@@ -170,7 +169,7 @@ def coco_instance_segmentation_to_sa_pixel(coco_path, images_path):
170169

171170
for id_, value in images_dict.items():
172171
img = cv2.imwrite(
173-
os.path.join(images_path, value['file_name'] + '___save.png'),
172+
str(images_path / (value['file_name'] + '___save.png')),
174173
value['mask']
175174
)
176175

0 commit comments

Comments
 (0)