json转成yolo用的txt(json中没有宽高,需要自设宽高的)

发布于:2025-05-30 ⋅ 阅读:(21) ⋅ 点赞:(0)

第一章  导包

import os
import json
import argparse

第二章 类别 

class_mapping = {"自己的类别": 0}

第三章 多边形点集转换为边界框的函数

def convert_polygon_to_bbox(points):
    """将多边形点集转换为边界框"""
    x_coords = [point[0] for point in points]
    y_coords = [point[1] for point in points]
    xmin = min(x_coords)
    ymin = min(y_coords)
    xmax = max(x_coords)
    ymax = max(y_coords)
    return xmin, ymin, xmax, ymax

第四章 转换函数

def convert_json_to_yolo(json_path, txt_path, image_width, image_height):
    """将单个JSON文件转换为YOLO格式的TXT文件"""
    with open(json_path, 'r') as f:
        data = json.load(f)

    with open(txt_path, 'w') as f:
        for shape in data.get("shapes", []):
            label = shape["label"]
            if label not in class_mapping:
                print(f"警告: 未定义的类别 '{label}',跳过此对象")
                continue

            class_id = class_mapping[label]
            points = shape["points"]
            xmin, ymin, xmax, ymax = convert_polygon_to_bbox(points)

            # 计算归一化的边界框坐标
            x_center = (xmin + xmax) / (2 * image_width)
            y_center = (ymin + ymax) / (2 * image_height)
            width = (xmax - xmin) / image_width
            height = (ymax - ymin) / image_height

            # 写入YOLO格式的行
            f.write(f"{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}\n")

第五章 批量转换函数

def batch_convert(json_dir, txt_dir, image_width, image_height):
    """批量转换JSON文件夹中的所有文件"""
    # 确保输出目录存在
    os.makedirs(txt_dir, exist_ok=True)

    # 获取所有JSON文件
    json_files = [f for f in os.listdir(json_dir) if f.lower().endswith('.json')]

    if not json_files:
        print(f"错误: 在 {json_dir} 中未找到JSON文件")
        return

    total = len(json_files)
    success = 0

    print(f"开始批量转换: {total} 个JSON文件")

    for i, json_file in enumerate(json_files, 1):
        json_path = os.path.join(json_dir, json_file)
        txt_file = os.path.splitext(json_file)[0] + '.txt'
        txt_path = os.path.join(txt_dir, txt_file)

        try:
            convert_json_to_yolo(json_path, txt_path, image_width, image_height)
            success += 1
            print(f"[{i}/{total}] 成功转换: {json_file} -> {txt_file}")
        except Exception as e:
            print(f"[{i}/{total}] 转换失败: {json_file} - 错误: {str(e)}")

    print(f"转换完成: 成功 {success}/{total}")

第六章 主函数

def main():
    parser = argparse.ArgumentParser(description='批量将JSON标注文件转换为YOLO格式的TXT文件')
    parser.add_argument('--json_dir', required=True, help='JSON文件所在目录')
    parser.add_argument('--txt_dir', required=True, help='TXT文件输出目录')
    parser.add_argument('--img_width', type=int, required=True, help='图像宽度')
    parser.add_argument('--img_height', type=int, required=True, help='图像高度')

    args = parser.parse_args()

    batch_convert(args.json_dir, args.txt_dir, args.img_width, args.img_height)

第七章 主函数调用 

 

if __name__ == "__main__":
    main()

全部代码如下: 

import os
import json
import argparse

# 类别映射 - 根据实际情况修改
class_mapping = {"自己的类别": 0}


def convert_polygon_to_bbox(points):
    """将多边形点集转换为边界框"""
    x_coords = [point[0] for point in points]
    y_coords = [point[1] for point in points]
    xmin = min(x_coords)
    ymin = min(y_coords)
    xmax = max(x_coords)
    ymax = max(y_coords)
    return xmin, ymin, xmax, ymax


def convert_json_to_yolo(json_path, txt_path, image_width, image_height):
    """将单个JSON文件转换为YOLO格式的TXT文件"""
    with open(json_path, 'r') as f:
        data = json.load(f)

    with open(txt_path, 'w') as f:
        for shape in data.get("shapes", []):
            label = shape["label"]
            if label not in class_mapping:
                print(f"警告: 未定义的类别 '{label}',跳过此对象")
                continue

            class_id = class_mapping[label]
            points = shape["points"]
            xmin, ymin, xmax, ymax = convert_polygon_to_bbox(points)

            # 计算归一化的边界框坐标
            x_center = (xmin + xmax) / (2 * image_width)
            y_center = (ymin + ymax) / (2 * image_height)
            width = (xmax - xmin) / image_width
            height = (ymax - ymin) / image_height

            # 写入YOLO格式的行
            f.write(f"{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}\n")


def batch_convert(json_dir, txt_dir, image_width, image_height):
    """批量转换JSON文件夹中的所有文件"""
    # 确保输出目录存在
    os.makedirs(txt_dir, exist_ok=True)

    # 获取所有JSON文件
    json_files = [f for f in os.listdir(json_dir) if f.lower().endswith('.json')]

    if not json_files:
        print(f"错误: 在 {json_dir} 中未找到JSON文件")
        return

    total = len(json_files)
    success = 0

    print(f"开始批量转换: {total} 个JSON文件")

    for i, json_file in enumerate(json_files, 1):
        json_path = os.path.join(json_dir, json_file)
        txt_file = os.path.splitext(json_file)[0] + '.txt'
        txt_path = os.path.join(txt_dir, txt_file)

        try:
            convert_json_to_yolo(json_path, txt_path, image_width, image_height)
            success += 1
            print(f"[{i}/{total}] 成功转换: {json_file} -> {txt_file}")
        except Exception as e:
            print(f"[{i}/{total}] 转换失败: {json_file} - 错误: {str(e)}")

    print(f"转换完成: 成功 {success}/{total}")


def main():
    parser = argparse.ArgumentParser(description='批量将JSON标注文件转换为YOLO格式的TXT文件')
    parser.add_argument('--json_dir', required=True, help='JSON文件所在目录')
    parser.add_argument('--txt_dir', required=True, help='TXT文件输出目录')
    parser.add_argument('--img_width', type=int, required=True, help='图像宽度')
    parser.add_argument('--img_height', type=int, required=True, help='图像高度')

    args = parser.parse_args()

    batch_convert(args.json_dir, args.txt_dir, args.img_width, args.img_height)


if __name__ == "__main__":
    main()

# ""是文件路径
# 执行命令 python xx.py --json_dir "" --txt_dir "" --img_width 800 --img_height 600
# 传入四个参数
# --json_dir:json的文件夹路径
# --txt_dir:输出的txt的文件夹路径
# --img_width 图像宽
# --img_height 图像高


网站公告

今日签到

点亮在社区的每一天
去签到