# ref : https://www.immersivelimit.com/create-coco-annotations-from-scratch def create_sub_mask_annotation(sub_mask, image_id, category_id, annotation_id, is_crowd): # Find contours (boundary lines) around each sub-mask # Note: there could be multiple contours if the object # is partially occluded. (E.g. an elephant behind a tree) sub_mask = np.array(sub_mask) # <- ref code not consider shape function. so, convert numpy array for shape function contours = measure.find_contours(sub_mask, 0.5, positive_orientation='low') segmentations = [] polygons = [] for contour in contours: # Flip from (row, col) representation to (x, y) # and subtract the padding pixel for i in range(len(contour)): row, col = contour[i] contour[i] = (col - 1, row - 1) # Make a polygon and simplify it poly = Polygon(contour) poly = poly.simplify(1.0, preserve_topology=False) polygons.append(poly) segmentation = np.array(poly.exterior.coords).ravel().tolist() segmentations.append(segmentation) # Combine the polygons to calculate the bounding box and area multi_poly = MultiPolygon(polygons) x, y, max_x, max_y = multi_poly.bounds width = max_x - x height = max_y - y bbox = (x, y, width, height) area = multi_poly.area annotation = { 'segmentation': segmentations, 'iscrowd': is_crowd, 'image_id': image_id, 'category_id': category_id, 'id': annotation_id, 'bbox': bbox, 'area': area } return annotation