如何将COCO Json转换为YOLOv8分割格式

huangapple go评论71阅读模式
英文:

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
                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)

希望这对您有所帮助。如果您需要进一步的协助,请随时告诉我。

英文:

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

答案1

得分: 1

这对我有用

我已经加载了images/all_images目录中的所有图像。我分别使用了coco .json注释来进行训练/测试/验证。您可以根据需要进行更改。确保自己创建目录。

import os
import json
import shutil

# 加载json和标签训练/验证/测试目录
coco_file = 'labels/val.json'
save_folder = 'labels/val'

# 卡车为0,汽车为1
category = 1

# 所有图像的来源和训练/测试/验证的目标文件夹
source_path = "images/all_images"
destination_path = "images/val"

# 使用os.listdir()获取文件夹中的文件名列表
file_names = os.listdir(source_path)

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(save_folder, exist_ok=True)

for ann in annotations:
    image = next(img for img in images if (img['id'] == ann['image_id']))
    if (image["file_name"] not in file_names):
        continue

    width, height = image['width'], image['height']
    x_coco, y_coco, width_coco, height_coco = ann['bbox']

    category_id = ann['category_id']

    image_id = ann['image_id']

    filename = image['file_name']
    label_filename = filename.split('.jpg')[0]
    label_path = os.path.join(save_folder, f'{label_filename}.txt')
    with open(label_path, 'a') as f:

        segmentation_points_list = []
        for segmentation in ann['segmentation']:
            # 检查分割中是否有任何元素是字符串
            if any(isinstance(point, str) for point in segmentation):
                continue  # 如果包含字符串,则跳过此分割

            segmentation_points = [str(float(point) / (width-1) if i % 2 == 0 else float(point) / (height-1)) for i, point in enumerate(segmentation)]
            segmentation_points_list.append(' '.join(segmentation_points))
            segmentation_points_string = ' '.join(segmentation_points_list)
            line = '{} {}\n'.format(category, segmentation_points_string)
            f.write(line)
            segmentation_points_list.clear()
    image_source = source_path + f'/{image["file_name"]}'
    shutil.copy(image_source, destination_path)
import os
import json
import shutil

# 加载json和标签训练/验证/测试目录
coco_file = 'labels/val.json'
save_folder = 'labels/val'

# 所有图像的来源和训练/测试/验证的目标文件夹
source_path = "images/all_images"
destination_path = "images/val"

# 使用os.listdir()获取文件夹中的文件名列表
file_names = os.listdir(source_path)

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(save_folder, exist_ok=True)

for ann in annotations:
    image = next(img for img in images if (img['id'] == ann['image_id']))
    if (image["file_name"] not in file_names):
        continue

    width, height = image['width'], image['height']
    x_center = (ann['bbox'][0] + ann['bbox'][2] / 2) / width
    y_center = (ann['bbox'][1] + ann['bbox'][3] / 2) / height
    bbox_width = ann['bbox'][2] / width
    bbox_height = ann['bbox'][3] / height
    category_id = ann['category_id']
    image_id = ann['image_id']

    filename = image['file_name']
    label_filename = filename.split('.jpg')[0]
    label_path = os.path.join(save_folder, f'{label_filename}.txt')
    with open(label_path, 'a') as f:

        segmentation_points_list = []
        for segmentation in ann['segmentation']:
            # 检查分割中是否有任何元素是字符串
            if any(isinstance(point, str) for point in segmentation):
                continue  # 如果包含字符串,则跳过此分割

            segmentation_points = [str(float(point) / width) for point in segmentation]
            segmentation_points_list.append(' '.join(segmentation_points))
            segmentation_points_string = ' '.join(segmentation_points_list)
            line = '{} {}\n'.format(categories, segmentation_points_string)
            f.write(line)
            segmentation_points_list.clear()
    image_source = source_path + f'/{image["file_name"]}'
    shutil.copy(image_source, destination_path)

希望这对你有帮助。

英文:

This works for me

I have loaded all the images in images/all_images directory. I used coco .json annotations differently for train/test/val. You can change accordingly. Make sure to create directory yourself.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

import os
import json
import shutil
# load json and save directory for labels train/val/test
coco_file = &#39;labels/val.json&#39;
save_folder = &#39;labels/val&#39;
# 0 for truck, 1 for car
category = 1
#source of all the images and destination folder for train/test/val
source_path = &quot;images/all_images&quot;
destination_path = &quot;images/val&quot;
# Use os.listdir() to get a list of filenames in the folder
file_names = os.listdir(source_path)
with open(coco_file) as f:
coco = json.load(f)
images = coco[&#39;images&#39;]
annotations = coco[&#39;annotations&#39;] 
categories = {cat[&#39;id&#39;]: cat[&#39;name&#39;] for cat in coco[&#39;categories&#39;]}
#os.makedirs(save_folder, exist_ok=True)
for ann in annotations:
image = next(img for img in images if (img[&#39;id&#39;] == ann[&#39;image_id&#39;]))
if (image[&quot;file_name&quot;] not in file_names):
continue
width, height = image[&#39;width&#39;], image[&#39;height&#39;]
x_coco, y_coco, width_coco, height_coco = ann[&#39;bbox&#39;]
category_id = ann[&#39;category_id&#39;]
image_id = ann[&#39;image_id&#39;]
filename = image[&#39;file_name&#39;]
label_filename = filename.split(&#39;.jpg&#39;)[0]
label_path = os.path.join(save_folder, f&#39;{label_filename}.txt&#39;)
with open(label_path, &#39;a&#39;) as f:
segmentation_points_list = []
for segmentation in ann[&#39;segmentation&#39;]:
# Check if any element in segmentation is a string
if any(isinstance(point, str) for point in segmentation):
continue  # Skip this segmentation if it contains strings
segmentation_points = [str(float(point) / (width-1) if i % 2 == 0 else float(point) / (height-1)) for i, point in enumerate(segmentation)]
segmentation_points_list.append(&#39; &#39;.join(segmentation_points))
segmentation_points_string = &#39; &#39;.join(segmentation_points_list)
line = &#39;{} {}\n&#39;.format(category, segmentation_points_string)
f.write(line)
segmentation_points_list.clear()
image_source = source_path + f&#39;/{image[&quot;file_name&quot;]}&#39;
shutil.copy(image_source, destination_path)

<!-- end snippet -->

<!-- language: lang-html -->

import os
import json
import shutil
# load json and save directory for labels train/val/test
coco_file = &#39;labels/val.json&#39;
save_folder = &#39;labels/val&#39;
#source of all the images and destination folder for train/test/val
source_path = &quot;images/all_images&quot;
destination_path = &quot;images/val&quot;
# Use os.listdir() to get a list of filenames in the folder
file_names = os.listdir(source_path)
with open(coco_file) as f:
coco = json.load(f)
images = coco[&#39;images&#39;]
annotations = coco[&#39;annotations&#39;] 
categories = {cat[&#39;id&#39;]: cat[&#39;name&#39;] for cat in coco[&#39;categories&#39;]}
#os.makedirs(save_folder, exist_ok=True)
for ann in annotations:
image = next(img for img in images if (img[&#39;id&#39;] == ann[&#39;image_id&#39;]))
if (image[&quot;file_name&quot;] not in file_names):
continue
#print(f&quot;image in annotations =   {type(image[&#39;id&#39;])}&quot;)
width, height = image[&#39;width&#39;], image[&#39;height&#39;]
x_center = (ann[&#39;bbox&#39;][0] + ann[&#39;bbox&#39;][2] / 2) / width
y_center = (ann[&#39;bbox&#39;][1] + ann[&#39;bbox&#39;][3] / 2) / height
bbox_width = ann[&#39;bbox&#39;][2] / width
bbox_height = ann[&#39;bbox&#39;][3] / height
category_id = ann[&#39;category_id&#39;]
image_id = ann[&#39;image_id&#39;]
filename = image[&#39;file_name&#39;]
label_filename = filename.split(&#39;.jpg&#39;)[0]
label_path = os.path.join(save_folder, f&#39;{label_filename}.txt&#39;)
with open(label_path, &#39;a&#39;) as f:
segmentation_points_list = []
for segmentation in ann[&#39;segmentation&#39;]:
# Check if any element in segmentation is a string
if any(isinstance(point, str) for point in segmentation):
continue  # Skip this segmentation if it contains strings
segmentation_points = [str(float(point) / width) for point in segmentation]
segmentation_points_list.append(&#39; &#39;.join(segmentation_points))
segmentation_points_string = &#39; &#39;.join(segmentation_points_list)
line = &#39;{} {}\n&#39;.format(categories, segmentation_points_string)
f.write(line)
segmentation_points_list.clear()
image_source = source_path + f&#39;/{image[&quot;file_name&quot;]}&#39;
shutil.copy(image_source, destination_path)

<!-- end snippet -->

答案2

得分: 0

请查看此脚本中使用的标签格式:

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

例如,用于实例分割的格式如下:类别 x1 y1 x2 y2 ... xn yn。因此,我建议将此行更改为:

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

实例分割标签格式:https://docs.ultralytics.com/datasets/segment/

英文:

Look at the label format used in this script:

line = &#39;{} {} {} {} {} {}&#39;.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 = &#39;{} {}&#39;.format(label_id, segmentation_points_str)

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

huangapple
  • 本文由 发表于 2023年4月4日 17:42:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/75927857.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定