json格式的标记文件转yolo格式(txt)的标记文件

背景

我在使用anylabeling标记软件时发现导出的标记文件格式只能是json格式,而我yolov8训练模型的标记文件需要时txt格式的,所以我需要写一个转换脚本

脚本

1. 脚本1

这个脚本是针对于矩形框标记的转换,也就是目标检测

import json
import os

def convert_json_to_yolo(json_file_path, output_dir, class_mapping):
    """
    将单个JSON文件转换为YOLO格式的TXT文件
    :param json_file_path: JSON文件路径
    :param output_dir: 输出目录
    :param class_mapping: 类别名称到类别索引的映射
    """
    with open(json_file_path, 'r', encoding='utf-8') as json_file:  # 显式指定文件编码为utf-8
        data = json.load(json_file)

    # 获取图片宽度和高度
    img_width = data['imageWidth']
    img_height = data['imageHeight']

    # 创建输出文件名
    txt_file_name = os.path.splitext(os.path.basename(json_file_path))[0] + '.txt'
    txt_file_path = os.path.join(output_dir, txt_file_name)

    with open(txt_file_path, 'w') as txt_file:
        for shape in data['shapes']:
            # 获取类别名称
            class_name = shape['label']
            if class_name not in class_mapping:
                raise ValueError(f"类别 '{class_name}' 未在类别映射中找到。请检查类别映射是否正确。")

            class_id = class_mapping[class_name]

            # 获取标注框坐标
            points = shape['points']
            x_min = min(points[0][0], points[1][0])
            y_min = min(points[0][1], points[1][1])
            x_max = max(points[0][0], points[1][0])
            y_max = max(points[0][1], points[1][1])

            # 转换为YOLO格式
            x_center = (x_min + x_max) / 2.0 / img_width
            y_center = (y_min + y_max) / 2.0 / img_height
            width = (x_max - x_min) / img_width
            height = (y_max - y_min) / img_height

            # 写入TXT文件
            txt_file.write(f"{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}\n")
def main():
    # 输入和输出目录
    # input_dir = r"D:\picture\CI1\labels1\val"
    # output_dir = r"D:\picture\CI1\labels\val"
    input_dir = r"C:\电脑桌面\lala\j"
    output_dir = r"C:\电脑桌面\lala\t"
    # 确保输出目录存在
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # 类别映射(根据你的数据集修改)
    class_mapping = {
        "可乐": 0,
        "东鹏特饮": 1,
        # 添加更多类别
    }

    # 遍历输入目录中的所有JSON文件
    for filename in os.listdir(input_dir):
        if filename.endswith('.json'):
            json_file_path = os.path.join(input_dir, filename)
            convert_json_to_yolo(json_file_path, output_dir, class_mapping)
            print(f"已转换 {filename}{output_dir}")

if __name__ == "__main__":
    main()

2. 脚本2

这个是针对多边形的标记文件,可从这个多边形中提取出矩形的标记文件(因为anylabeling能多边形标记)

import json
import os

def convert_polygon_to_bbox(points, img_width, img_height):
    """
    将多边形的点转换为边界框
    :param points: 多边形的点列表,每个点是一个 [x, y] 列表
    :param img_width: 图像宽度
    :param img_height: 图像高度
    :return: 边界框的坐标 [x_min, y_min, x_max, y_max]
    """
    x_coords = [point[0] for point in points]
    y_coords = [point[1] for point in points]
    x_min, x_max = min(x_coords), max(x_coords)
    y_min, y_max = min(y_coords), max(y_coords)
    return [x_min, y_min, x_max, y_max]

def convert_json_to_yolo(json_file_path, output_dir, class_mapping):
    """
    将单个 JSON 文件转换为 YOLO 格式的 TXT 文件
    :param json_file_path: JSON 文件路径
    :param output_dir: 输出目录
    :param class_mapping: 类别名称到类别索引的映射
    """
    with open(json_file_path, 'r', encoding='utf-8') as json_file:
        data = json.load(json_file)

    img_width = data['imageWidth']
    img_height = data['imageHeight']

    txt_file_name = os.path.splitext(os.path.basename(json_file_path))[0] + '.txt'
    txt_file_path = os.path.join(output_dir, txt_file_name)

    with open(txt_file_path, 'w') as txt_file:
        for shape in data['shapes']:
            class_name = shape['label']
            if class_name not in class_mapping:
                raise ValueError(f"类别 '{class_name}' 未在类别映射中找到。请检查类别映射是否正确。")
            class_id = class_mapping[class_name]

            points = shape['points']
            x_min, y_min, x_max, y_max = convert_polygon_to_bbox(points, img_width, img_height)

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

            txt_file.write(f"{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}\n")

def main():
    input_dir = r"D:\picture\CI1\labels1\val"
    output_dir = r"D:\picture\CV2\labels\val"
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    class_mapping = {
        "可乐": 0,
        "东鹏特饮": 1,
        # 添加更多类别
    }

    for filename in os.listdir(input_dir):
        if filename.endswith('.json'):
            json_file_path = os.path.join(input_dir, filename)
            convert_json_to_yolo(json_file_path, output_dir, class_mapping)
            print(f"已转换 {filename}{output_dir}")

if __name__ == "__main__":
    main()

你可能感兴趣的:(json,YOLO,python)