labelme和yolo格式互转

先把用到的记录一下。

  1. labelme格式是json格式,标签类型和坐标记录在一起,坐标是像素坐标
  2. yolo格式是txt格式,只用数字记录,标签类型用标号,坐标使用归一化坐标;另外有一个classes.txt保存标签类型,前面提到的标号就是在这里对应的。

包括根目录的文件目录结构:

E:/yolov8/20240624/escala/ # 根目录
    images/ # 存放图片数据集
        test/
        train/
        val/
    labels/ # 存放原先的yolo标注
        test/
        train/
        val/
        train/classes.txt
    labelmes/ # 存放生成的labelme标注
        test/
        train/
        val/

yolo转labelme:

import os
import json
from PIL import Image

# 基本路径
base_path = "E:/yolov8/20240624/escala/"
image_dirs = ["images/test", "images/train", "images/val"]
label_dirs = ["labels/test", "labels/train", "labels/val"]
output_dir = "labelmes/"

# 读取类别文件
classes_path = os.path.join(base_path, "labels/train/classes.txt")
with open(classes_path, 'r') as f:
    classes = f.read().strip().split('\n')

# 创建输出目录
for dir_name in image_dirs:
    os.makedirs(os.path.join(base_path, output_dir, os.path.basename(dir_name)), exist_ok=True)

# 遍历所有图片目录
for image_dir, label_dir in zip(image_dirs, label_dirs):
    image_dir_path = os.path.join(base_path, image_dir)
    label_dir_path = os.path.join(base_path, label_dir)
    output_dir_path = os.path.join(base_path, output_dir, os.path.basename(image_dir))

    for image_file in os.listdir(image_dir_path):
        if image_file.endswith('.jpg'):
            image_path = os.path.join(image_dir_path, image_file)
            yolo_anno_path = os.path.join(label_dir_path, os.path.splitext(image_file)[0] + '.txt')
            output_anno_path = os.path.join(output_dir_path, os.path.splitext(image_file)[0] + '.json')

            # 读取图片尺寸
            image = Image.open(image_path)
            img_width, img_height = image.size

            # 读取YOLOv8标注文件,如果文件不存在则跳过
            if not os.path.exists(yolo_anno_path):
                print(f"No annotation file for {image_file}, skipping...")
                continue

            with open(yolo_anno_path, 'r') as f:
                yolo_annotations = f.read().strip().split('\n')

            # 计算图片的相对路径,相对于输出目录
            relative_image_path = os.path.relpath(image_path, output_dir_path)

            # YOLOv8到LabelMe格式的转换
            labelme_annotations = {
                "version": "5.5.0",
                "flags": {},
                "shapes": [],
                "imagePath": relative_image_path,
                "imageData": None,
                "imageHeight": img_height,
                "imageWidth": img_width
            }

            for anno in yolo_annotations:
                class_id, x_center, y_center, width, height = map(float, anno.split())
                class_name = classes[int(class_id)]

                # YOLOv8的中心点和宽高转换为LabelMe的四个点
                x_min = (x_center - width / 2) * img_width
                y_min = (y_center - height / 2) * img_height
                x_max = (x_center + width / 2) * img_width
                y_max = (y_center + height / 2) * img_height

                shape = {
                    "label": class_name,
                    "points": [
                        [x_min, y_min],
                        [x_max, y_min],
                        [x_max, y_max],
                        [x_min, y_max]
                    ],
                    "group_id": None,
                    "shape_type": "polygon",
                    "flags": {}
                }

                labelme_annotations["shapes"].append(shape)

            # 保存为LabelMe格式的JSON文件
            with open(output_anno_path, 'w') as f:
                json.dump(labelme_annotations, f, indent=4)

            print(f"YOLOv8 annotations for {image_file} have been converted to LabelMe format and saved to {output_anno_path}")

labelme转yolo:

import os
import json

# 基本路径
base_path = "E:/yolov8/20240624/escala/"
image_dirs = ["images/test", "images/train", "images/val"]
label_dirs = ["labelmes/test", "labelmes/train", "labelmes/val"]
output_base_dir = "me2yolo/"

# 创建输出目录
for dir_name in image_dirs:
    os.makedirs(os.path.join(base_path, output_base_dir, os.path.basename(dir_name)), exist_ok=True)

# 遍历所有图片目录
for image_dir, label_dir in zip(image_dirs, label_dirs):
    image_dir_path = os.path.join(base_path, image_dir)
    label_dir_path = os.path.join(base_path, label_dir)
    output_dir_path = os.path.join(base_path, output_base_dir, os.path.basename(image_dir))

    classes_set = set()

    # 第一步,收集所有标签名称
    for image_file in os.listdir(image_dir_path):
        if image_file.endswith('.jpg'):
            labelme_anno_path = os.path.join(label_dir_path, os.path.splitext(image_file)[0] + '.json')

            if not os.path.exists(labelme_anno_path):
                continue

            with open(labelme_anno_path, 'r') as f:
                labelme_annotations = json.load(f)

            for shape in labelme_annotations["shapes"]:
                class_name = shape["label"]
                classes_set.add(class_name)

    sorted_classes = sorted(classes_set)
    class_name_to_id = {class_name: idx for idx, class_name in enumerate(sorted_classes)}

    # 保存类别文件
    classes_path = os.path.join(output_dir_path, "classes.txt")
    with open(classes_path, 'w') as f:
        f.write('\n'.join(sorted_classes))

    print(f"Classes file saved to {classes_path}")

    # 第二步,转换标注文件
    for image_file in os.listdir(image_dir_path):
        if image_file.endswith('.jpg'):
            image_path = os.path.join(image_dir_path, image_file)
            labelme_anno_path = os.path.join(label_dir_path, os.path.splitext(image_file)[0] + '.json')
            yolo_anno_path = os.path.join(output_dir_path, os.path.splitext(image_file)[0] + '.txt')

            if not os.path.exists(labelme_anno_path):
                print(f"No annotation file for {image_file}, skipping...")
                continue

            with open(labelme_anno_path, 'r') as f:
                labelme_annotations = json.load(f)

            img_width = labelme_annotations["imageWidth"]
            img_height = labelme_annotations["imageHeight"]

            yolo_annotations = []

            for shape in labelme_annotations["shapes"]:
                class_name = shape["label"]
                points = shape["points"]
                x_min = min(points, key=lambda p: p[0])[0]
                y_min = min(points, key=lambda p: p[1])[1]
                x_max = max(points, key=lambda p: p[0])[0]
                y_max = max(points, key=lambda p: p[1])[1]

                x_center = (x_min + x_max) / 2 / img_width
                y_center = (y_min + y_max) / 2 / img_height
                width = (x_max - x_min) / img_width
                height = (y_max - y_min) / img_height

                class_id = class_name_to_id[class_name]

                yolo_annotations.append(f"{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}")

            # 保存为YOLO格式的txt文件
            with open(yolo_anno_path, 'w') as f:
                f.write('\n'.join(yolo_annotations))

            print(f"LabelMe annotations for {image_file} have been converted to YOLO format and saved to {yolo_anno_path}")
@ 1313
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇