Spaces:
Runtime error
Runtime error
#!/usr/bin/env python | |
# ------------------------------------------------------------------------------ | |
# Reference: https://github.com/cocodataset/panopticapi/blob/master/converters/panoptic2detection_coco_format.py | |
# Modified by Jitesh Jain (https://github.com/praeclarumjj3) | |
# ------------------------------------------------------------------------------ | |
''' | |
This script converts panoptic COCO format to detection COCO format. More | |
information about the formats can be found here: | |
http://cocodataset.org/#format-data. All segments will be stored in RLE format. | |
Additional option: | |
- using option '--things_only' the script can discard all stuff | |
segments, saving segments of things classes only. | |
''' | |
from __future__ import absolute_import | |
from __future__ import division | |
from __future__ import print_function | |
from __future__ import unicode_literals | |
import os, sys | |
import argparse | |
import numpy as np | |
import json | |
import time | |
import multiprocessing | |
import PIL.Image as Image | |
from panopticapi.utils import get_traceback, rgb2id, save_json | |
try: | |
# set up path for pycocotools | |
# sys.path.append('./cocoapi-master/PythonAPI/') | |
from pycocotools import mask as COCOmask | |
except Exception: | |
raise Exception("Please install pycocotools module from https://github.com/cocodataset/cocoapi") | |
def convert_panoptic_to_detection_coco_format_single_core( | |
proc_id, annotations_set, categories, segmentations_folder, things_only | |
): | |
annotations_detection = [] | |
for working_idx, annotation in enumerate(annotations_set): | |
if working_idx % 100 == 0: | |
print('Core: {}, {} from {} images processed'.format(proc_id, | |
working_idx, | |
len(annotations_set))) | |
file_name = '{}.png'.format(annotation['file_name'].rsplit('.')[0]) | |
try: | |
pan_format = np.array( | |
Image.open(os.path.join(segmentations_folder, file_name)), dtype=np.uint32 | |
) | |
except IOError: | |
raise KeyError('no prediction png file for id: {}'.format(annotation['image_id'])) | |
pan = rgb2id(pan_format) | |
for segm_info in annotation['segments_info']: | |
if things_only and categories[segm_info['category_id']]['isthing'] != 1: | |
continue | |
mask = (pan == segm_info['id']).astype(np.uint8) | |
mask = np.expand_dims(mask, axis=2) | |
segm_info.pop('id') | |
segm_info['image_id'] = annotation['image_id'] | |
rle = COCOmask.encode(np.asfortranarray(mask))[0] | |
rle['counts'] = rle['counts'].decode('utf8') | |
segm_info['segmentation'] = rle | |
annotations_detection.append(segm_info) | |
print('Core: {}, all {} images processed'.format(proc_id, len(annotations_set))) | |
return annotations_detection | |
def convert_panoptic_to_detection_coco_format(input_json_file, | |
segmentations_folder, | |
output_json_file, | |
categories_json_file, | |
things_only): | |
start_time = time.time() | |
if segmentations_folder is None: | |
segmentations_folder = input_json_file.rsplit('.', 1)[0] | |
print("CONVERTING...") | |
print("COCO panoptic format:") | |
print("\tSegmentation folder: {}".format(segmentations_folder)) | |
print("\tJSON file: {}".format(input_json_file)) | |
print("TO") | |
print("COCO detection format") | |
print("\tJSON file: {}".format(output_json_file)) | |
if things_only: | |
print("Saving only segments of things classes.") | |
print('\n') | |
print("Reading annotation information from {}".format(input_json_file)) | |
with open(input_json_file, 'r') as f: | |
d_coco = json.load(f) | |
annotations_panoptic = d_coco['annotations'] | |
with open(categories_json_file, 'r') as f: | |
categories_list = json.load(f) | |
categories = {category['id']: category for category in categories_list} | |
cpu_num = multiprocessing.cpu_count() | |
annotations_split = np.array_split(annotations_panoptic, cpu_num) | |
print("Number of cores: {}, images per core: {}".format(cpu_num, len(annotations_split[0]))) | |
workers = multiprocessing.Pool(processes=cpu_num) | |
processes = [] | |
for proc_id, annotations_set in enumerate(annotations_split): | |
p = workers.apply_async(convert_panoptic_to_detection_coco_format_single_core, | |
(proc_id, annotations_set, categories, segmentations_folder, things_only)) | |
processes.append(p) | |
annotations_coco_detection = [] | |
for p in processes: | |
annotations_coco_detection.extend(p.get()) | |
for idx, ann in enumerate(annotations_coco_detection): | |
ann['id'] = idx | |
d_coco['annotations'] = annotations_coco_detection | |
categories_coco_detection = [] | |
for category in d_coco['categories']: | |
if things_only and category['isthing'] != 1: | |
continue | |
category.pop('isthing') | |
categories_coco_detection.append(category) | |
d_coco['categories'] = categories_coco_detection | |
save_json(d_coco, output_json_file) | |
t_delta = time.time() - start_time | |
print("Time elapsed: {:0.2f} seconds".format(t_delta)) | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser( | |
description="The script converts panoptic COCO format to detection \ | |
COCO format. See this file's head for more information." | |
) | |
parser.add_argument('--things_only', action='store_true', | |
help="discard stuff classes") | |
args = parser.parse_args() | |
_root = os.getenv("DETECTRON2_DATASETS", "datasets") | |
root = os.path.join(_root, "coco") | |
input_json_file = os.path.join(root, "annotations", "panoptic_val2017.json") | |
output_json_file = os.path.join(root, "annotations", "panoptic2instances_val2017.json") | |
categories_json_file = "datasets/panoptic_coco_categories.json" | |
segmentations_folder = os.path.join(root, "panoptic_val2017") | |
convert_panoptic_to_detection_coco_format(input_json_file, | |
segmentations_folder, | |
output_json_file, | |
categories_json_file, | |
args.things_only) | |