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 extract_semantic_single_core(proc_id, annotations_set, segmentations_folder, output_json_file, semantic_seg_folder, categories, save_as_png, things_other): annotation_semantic_seg = [] 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))) try: pan_format = np.array( Image.open(os.path.join(segmentations_folder, annotation['file_name'])), dtype=np.uint32 ) except IOError: raise KeyError('no prediction png file for id: {}'.format(annotation['image_id'])) pan = rgb2id(pan_format) semantic = np.zeros(pan.shape, dtype=np.uint8) RLE_per_category = defaultdict(list) for segm_info in annotation['segments_info']: cat_id = segm_info['category_id'] if things_other and categories[cat_id]['isthing'] == 1: cat_id = OTHER_CLASS_ID mask = pan == segm_info['id'] if save_as_png: semantic[mask] = cat_id else: RLE = COCOmask.encode(np.asfortranarray(mask.astype('uint8'))) RLE_per_category[cat_id].append(RLE) if save_as_png: Image.fromarray(semantic).save(os.path.join(semantic_seg_folder, annotation['file_name'])) else: for cat_id, RLE_list in RLE_per_category.items(): if len(RLE_list) == 1: RLE = RLE_list[0] else: RLE = COCOmask.merge(RLE_list) semantic_seg_record = {} semantic_seg_record["image_id"] = annotation['image_id'] semantic_seg_record["category_id"] = cat_id semantic_seg_record["segmentation"] = RLE semantic_seg_record["area"] = int(COCOmask.area(RLE)) semantic_seg_record["bbox"] = list(COCOmask.toBbox(RLE)) semantic_seg_record["iscrowd"] = 0 annotation_semantic_seg.append(semantic_seg_record) print('Core: {}, all {} images processed'.format(proc_id, len(annotations_set))) return annotation_semantic_seg
def _open_panoptic_id_image(image_path): """Loads a COCO-format panoptic ID image from file.""" return panopticapi_utils.rgb2id( np.array(Image.open(image_path), dtype=np.uint32))
def main(image_id): # whether from the PNG are used or new colors are generated generate_new_colors = True json_file = 'panoptic_val2017.json' segmentations_folder = './panoptic_val2017/' pred_folder = './panoptic_pred2017/' img_folder = '/Users/wuyangxin/Desktop/cv/dataset/coco/val2017' panoptic_coco_categories = './panoptic_coco_categories.json' with open(json_file, 'r') as f: coco_d = json.load(f) # ann = np.random.choice(coco_d['annotations']) ann = None for a in coco_d['annotations']: if a['image_id'] == image_id: ann = a break with open(panoptic_coco_categories, 'r') as f: categories_list = json.load(f) categegories = {category['id']: category for category in categories_list} # find input img that correspond to the annotation img = None pred_img = None for image_info in coco_d['images']: if image_info['id'] == ann['image_id']: try: img = np.array( Image.open( os.path.join(img_folder, image_info['file_name']))) pred_img = Image.open( os.path.join(pred_folder, image_info['file_name'].replace('jpg', 'png'))) except: print("Undable to find correspoding input image.") break segmentation = np.array(Image.open( os.path.join(segmentations_folder, ann['file_name'])), dtype=np.uint8) segmentation_id = rgb2id(segmentation) # find segments boundaries boundaries = find_boundaries(segmentation_id, mode='thick') if generate_new_colors: segmentation[:, :, :] = 0 color_generator = IdGenerator(categegories) for segment_info in ann['segments_info']: color = color_generator.get_color(segment_info['category_id']) mask = segmentation_id == segment_info['id'] segmentation[mask] = color # depict boundaries # segmentation[boundaries] = [0, 0, 0] if img is None: plt.figure() plt.imshow(segmentation) plt.axis('off') else: plt.figure(figsize=(9, 5)) plt.subplot(131) plt.imshow(img) plt.axis('off') plt.subplot(132) plt.imshow(segmentation) plt.axis('off') plt.subplot(133) plt.imshow(pred_img) plt.axis('off') plt.tight_layout() plt.show()
# find input img that correspond to the annotation img = None for image_info in coco_d['images']: if image_info['id'] == ann['image_id']: try: img = np.array( Image.open( os.path.join(img_folder, image_info['file_name']))) except: print("Undable to find correspoding input image.") break segmentation = np.array(Image.open( os.path.join(segmentations_folder, ann['file_name'])), dtype=np.uint8) segmentation_id = rgb2id(segmentation) # find segments boundaries boundaries = find_boundaries(segmentation_id, mode='thick') if generate_new_colors: segmentation[:, :, :] = 0 color_generator = IdGenerator(categegories) for segment_info in ann['segments_info']: color = color_generator.get_color(segment_info['category_id']) mask = segmentation_id == segment_info['id'] segmentation[mask] = color # depict boundaries segmentation[boundaries] = [0, 0, 0] if img is None:
def pq_compute_single_core(proc_id, annotation_set, gt_folder, pred_folder, categories): pq_stat = PQStat() idx = 0 for gt_ann, pred_ann in annotation_set: if idx % 100 == 0: print('Core: {}, {} from {} images processed'.format( proc_id, idx, len(annotation_set))) idx += 1 pan_gt = np.array(Image.open( os.path.join(gt_folder, gt_ann['file_name'])), dtype=np.uint32) pan_gt = rgb2id(pan_gt) pan_pred = np.array(Image.open( os.path.join(pred_folder, pred_ann['file_name'])), dtype=np.uint32) pan_pred = rgb2id(pan_pred) gt_segms = {el['id']: el for el in gt_ann['segments_info']} pred_segms = {el['id']: el for el in pred_ann['segments_info']} # predicted segments area calculation + prediction sanity checks pred_labels_set = set(el['id'] for el in pred_ann['segments_info']) labels, labels_cnt = np.unique(pan_pred, return_counts=True) for label, label_cnt in zip(labels, labels_cnt): if label not in pred_segms: if label == VOID: continue raise KeyError( 'In the image with ID {} segment with ID {} is presented in PNG and not presented in JSON.' .format(gt_ann['image_id'], label)) pred_segms[label]['area'] = label_cnt pred_labels_set.remove(label) if pred_segms[label]['category_id'] not in categories: raise KeyError( 'In the image with ID {} segment with ID {} has unknown category_id {}.' .format(gt_ann['image_id'], label, pred_segms[label]['category_id'])) if len(pred_labels_set) != 0: raise KeyError( 'In the image with ID {} the following segment IDs {} are presented in JSON and not presented in PNG.' .format(gt_ann['image_id'], list(pred_labels_set))) # confusion matrix calculation pan_gt_pred = pan_gt.astype(np.uint64) * OFFSET + pan_pred.astype( np.uint64) gt_pred_map = {} labels, labels_cnt = np.unique(pan_gt_pred, return_counts=True) for label, intersection in zip(labels, labels_cnt): gt_id = label // OFFSET pred_id = label % OFFSET gt_pred_map[(gt_id, pred_id)] = intersection # count all matched pairs gt_matched = set() pred_matched = set() for label_tuple, intersection in gt_pred_map.items(): gt_label, pred_label = label_tuple if gt_label not in gt_segms: continue if pred_label not in pred_segms: continue if gt_segms[gt_label]['iscrowd'] == 1: continue if gt_segms[gt_label]['category_id'] != pred_segms[pred_label][ 'category_id']: continue union = pred_segms[pred_label]['area'] + gt_segms[gt_label][ 'area'] - intersection - gt_pred_map.get((VOID, pred_label), 0) iou = intersection / union if iou > 0.5: pq_stat[gt_segms[gt_label]['category_id']].tp += 1 pq_stat[gt_segms[gt_label]['category_id']].iou += iou gt_matched.add(gt_label) pred_matched.add(pred_label) # count false positives crowd_labels_dict = {} for gt_label, gt_info in gt_segms.items(): if gt_label in gt_matched: continue # crowd segments are ignored if gt_info['iscrowd'] == 1: crowd_labels_dict[gt_info['category_id']] = gt_label continue pq_stat[gt_info['category_id']].fn += 1 # count false positives for pred_label, pred_info in pred_segms.items(): if pred_label in pred_matched: continue # intersection of the segment with VOID intersection = gt_pred_map.get((VOID, pred_label), 0) # plus intersection with corresponding CROWD region if it exists if pred_info['category_id'] in crowd_labels_dict: intersection += gt_pred_map.get( (crowd_labels_dict[pred_info['category_id']], pred_label), 0) # predicted segment is ignored if more than half of the segment correspond to VOID and CROWD regions if intersection / pred_info['area'] > 0.5: continue pq_stat[pred_info['category_id']].fp += 1 print('Core: {}, all {} images processed'.format(proc_id, len(annotation_set))) return pq_stat