|
8 | 8 | import cv2 |
9 | 9 | import numpy as np |
10 | 10 |
|
11 | | -from ..common import (blue_color_generator, hex_to_rgb, write_to_json) |
| 11 | +from ..common import blue_color_generator, hex_to_rgb, write_to_json |
12 | 12 | from ..exceptions import SABaseException |
13 | 13 |
|
14 | 14 | logger = logging.getLogger("superannotate-python-sdk") |
@@ -181,7 +181,7 @@ def sa_convert_project_type(input_dir, output_dir): |
181 | 181 | else: |
182 | 182 | raise SABaseException( |
183 | 183 | 0, |
184 | | - "'input_dir' should contain JSON files with '[IMAGE_NAME]___objects.json' or '[IMAGE_NAME]___pixel.json' names structure." |
| 184 | + "'input_dir' should contain JSON files with '[IMAGE_NAME]___objects.json' or '[IMAGE_NAME]___pixel.json' names structure." |
185 | 185 | ) |
186 | 186 |
|
187 | 187 | for img_name in img_names: |
@@ -239,3 +239,148 @@ def split_coco( |
239 | 239 | for file_name, value in groups.items(): |
240 | 240 | with open(output_dir / (file_name + '.json'), 'w') as fw: |
241 | 241 | json.dump(value, fw, indent=2) |
| 242 | + |
| 243 | + |
| 244 | +def upgrade_json(input_dir, output_dir): |
| 245 | + files_list = list(input_dir.glob('*.json')) |
| 246 | + ptype = 'Vector' |
| 247 | + if '___pixel' in str(files_list[0].name): |
| 248 | + ptype = "Pixel" |
| 249 | + |
| 250 | + converted_files = [] |
| 251 | + failed_files = [] |
| 252 | + for file in files_list: |
| 253 | + file_name = file.name |
| 254 | + try: |
| 255 | + output_json = _update_json_format(file, ptype) |
| 256 | + converted_files.append(file_name) |
| 257 | + write_to_json(output_dir / file_name, output_json) |
| 258 | + except Exception as e: |
| 259 | + failed_files.append(file_name) |
| 260 | + |
| 261 | + return converted_files |
| 262 | + |
| 263 | + |
| 264 | +def degrade_json(input_dir, output_dir): |
| 265 | + files_list = list(input_dir.glob('*.json')) |
| 266 | + |
| 267 | + converted_files = [] |
| 268 | + failed_files = [] |
| 269 | + for file in files_list: |
| 270 | + file_name = file.name |
| 271 | + try: |
| 272 | + output_json = _degrade_json_format(file) |
| 273 | + converted_files.append(output_dir / file_name) |
| 274 | + write_to_json(output_dir / file_name, output_json) |
| 275 | + except Exception as e: |
| 276 | + failed_files.append(file_name) |
| 277 | + |
| 278 | + return converted_files |
| 279 | + |
| 280 | + |
| 281 | +def _update_json_format(old_json_path, project_type): |
| 282 | + old_json_data = json.load(open(old_json_path)) |
| 283 | + new_json_data = { |
| 284 | + "metadata": {}, |
| 285 | + "instances": [], |
| 286 | + "tags": [], |
| 287 | + "comments": [] |
| 288 | + } |
| 289 | + |
| 290 | + meta_keys = [ |
| 291 | + "name", "width", "height", "status", "pinned", "isPredicted", |
| 292 | + "projectId", "annotatorEmail", "qaEmail" |
| 293 | + ] |
| 294 | + if project_type == "Pixel": |
| 295 | + meta_keys.append("isSegmented") |
| 296 | + |
| 297 | + new_json_data["metadata"] = dict.fromkeys(meta_keys) |
| 298 | + |
| 299 | + #set image name |
| 300 | + suffix = "___objects.json" if project_type == "Vector" else "___pixel.json" |
| 301 | + # image_name = os.path.basename(old_json_path).split(suffix)[0] |
| 302 | + image_name = str(old_json_path.name).split(suffix)[0] |
| 303 | + metadata = new_json_data["metadata"] |
| 304 | + metadata["name"] = image_name |
| 305 | + |
| 306 | + for item in old_json_data: |
| 307 | + object_type = item.get("type") |
| 308 | + #add metadata |
| 309 | + if object_type == "meta": |
| 310 | + meta_name = item["name"] |
| 311 | + if meta_name == "imageAttributes": |
| 312 | + metadata["height"] = item.get("height") |
| 313 | + metadata["width"] = item.get("width") |
| 314 | + metadata["status"] = item.get("status") |
| 315 | + metadata["pinned"] = item.get("pinned") |
| 316 | + if meta_name == "lastAction": |
| 317 | + metadata["lastAction"] = dict.fromkeys(["email", "timestamp"]) |
| 318 | + metadata["lastAction"]["email"] = item.get("userId") |
| 319 | + metadata["lastAction"]["timestamp"] = item.get("timestamp") |
| 320 | + #add tags |
| 321 | + elif object_type == "tag": |
| 322 | + new_json_data["tags"].append(item.get("name")) |
| 323 | + #add comments |
| 324 | + elif object_type == "comment": |
| 325 | + item.pop("type") |
| 326 | + item["correspondence"] = item["comments"] |
| 327 | + for comment in item["correspondence"]: |
| 328 | + comment["email"] = comment["id"] |
| 329 | + comment.pop("id") |
| 330 | + item.pop("comments") |
| 331 | + new_json_data["comments"].append(item) |
| 332 | + #add instances |
| 333 | + else: |
| 334 | + new_json_data["instances"].append(item) |
| 335 | + |
| 336 | + return new_json_data |
| 337 | + |
| 338 | + |
| 339 | +def _degrade_json_format(new_json_path): |
| 340 | + sa_loader = [] |
| 341 | + new_json_data = json.load(open(new_json_path)) |
| 342 | + |
| 343 | + meta = {'type': 'meta', 'name': 'imageAttributes'} |
| 344 | + meta_keys = ['height', 'width', 'status', 'pinned'] |
| 345 | + for meta_key in meta_keys: |
| 346 | + if meta_key in new_json_data['metadata']: |
| 347 | + meta[meta_key] = new_json_data['metadata'][meta_key] |
| 348 | + sa_loader.append(meta) |
| 349 | + |
| 350 | + if 'lastAction' in new_json_data['metadata']: |
| 351 | + meta = { |
| 352 | + 'type': 'meta', |
| 353 | + 'name': 'lastAction', |
| 354 | + 'userId': new_json_data['metadata']['lastAction']['email'], |
| 355 | + 'timestamp': new_json_data['metadata']['lastAction']['timestamp'] |
| 356 | + } |
| 357 | + sa_loader.append(meta) |
| 358 | + |
| 359 | + for item in new_json_data['instances']: |
| 360 | + sa_loader.append(item) |
| 361 | + |
| 362 | + for item in new_json_data['comments']: |
| 363 | + comments = [] |
| 364 | + for item2 in item['correspondence']: |
| 365 | + comments.append({'text': item2['text'], 'id': item2['email']}) |
| 366 | + item['comments'] = comments |
| 367 | + item['createdAt'] = item['correspondence'][0]['timestamp'] |
| 368 | + item['createdBy'] = { |
| 369 | + 'email': item['correspondence'][0]['email'], |
| 370 | + 'role': item['correspondence'][0]['role'] |
| 371 | + } |
| 372 | + item['updatedAt'] = item['correspondence'][-1]['timestamp'] |
| 373 | + item['updatedBy'] = { |
| 374 | + 'email': item['correspondence'][-1]['email'], |
| 375 | + 'role': item['correspondence'][-1]['role'] |
| 376 | + } |
| 377 | + item.pop('correspondence') |
| 378 | + item['type'] = 'comment' |
| 379 | + item['comments'] = comments |
| 380 | + sa_loader.append(item) |
| 381 | + |
| 382 | + for item in new_json_data['tags']: |
| 383 | + tag = {'type': 'tag', 'name': item} |
| 384 | + sa_loader.append(tag) |
| 385 | + |
| 386 | + return sa_loader |
0 commit comments