object-detectionimage-segmentationyoloyolov8

How to Convert COCO Json to YOLOv8 segmentation format


def convert_coco_to_yolov8(coco_file):

    with open(coco_file) as f:
        coco = json.load(f)


    images = coco['images']
    annotations = coco['annotations'] 
    categories = {cat['id']: cat['name'] for cat in coco['categories']}

    
    os.makedirs('labels', exist_ok=True)

 
    for image in tqdm(images, desc='Converting images'):
        image_id = image['id']
        filename = image['file_name']



        label_filename = filename.split('.png')[0]
        label_path = os.path.join('labels', f'{label_filename}.txt')
        with open(label_path, 'w') as f:

            for ann in annotations:
                if ann['image_id'] != image_id:
                    continue

                img_width = image['width']
                img_height = image['height']

                xmin, ymin, width, height = ann['bbox']
              
                xmax = xmin + width
                ymax = ymin + height
                xcen = (xmin + xmax) / 2
                ycen = (ymin + ymax) / 2
                # xcen = (xmin + xmax) / 2 / img_width
                # ycen = (ymin + ymax) / 2 / img_height
                w = xmax - xmin
                h = ymax - ymin
                label = categories[ann['category_id']]
                label_id = ann['category_id']
             
            

                segmentation_points_list = []
                for segmentation in ann['segmentation']:
                    segmentation_points = [str(point / img_width) for point in segmentation]
                    segmentation_points_list.append(' '.join(segmentation_points))
                segmentation_points_string = ' '.join(segmentation_points_list)


                                

             
                line = '{} {} {} {} {} {}\n'.format(label_id, xcen / img_width, ycen / img_height, w / img_width, h / img_height, segmentation_points_string )
                f.write(line)

the script is getting the labels but when i train for YOLOv8 the labels are seems wrong ,I need to convert a coco json to YOLOV8 txt file . label should contain segmentation also. Note my JSON file have different image size for all images


Solution

  • Look at the label format used in this script:

    line = '{} {} {} {} {} {}'.format(label_id, x_center, y_center, w_box, h_box, segmentation_points_str)
    

    For instance segmentation format use this: class x1 y1 x2 y2 ... xn yn. So I recommend changing this line to:

    line = '{} {}'.format(label_id, segmentation_points_str)
    

    Instance segmentation label format: https://docs.ultralytics.com/datasets/segment/