大家在使用labelme,或者labelimg标注完数据之后呢,想要训练yolo系列目标检测模型时会需要将标注文件的json格式转换为yolo所需要的txt格式。

下面废话不多说,直接安排对应的脚本。

需要修改的只有三个地方json_path,image_path,output_folder,分别代表json文件的存储路径,图片文件夹的路径,txt格式的结果路径。

转换完成之后根据自己的比例划分train和val,在自己建一个yaml即可训练自己的yolo模型

import cv2
import os
import json
import glob
import numpy as np

def convert_json_label_to_yolov_seg_label():
    json_path = r"D:\Desktop\label"  # JSON文件路径
    image_path = r"D:\Desktop\rock"  # 图片文件路径
    json_files = glob.glob(json_path + "/*.json")
    print("找到的JSON文件:", json_files)

    # 指定输出文件夹
    output_folder = r"D:\Desktop\txt"  # txt存放路径
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    for json_file in json_files:
        print(f"\n处理文件: {json_file}")
        with open(json_file, 'r') as f:
            json_info = json.load(f)

        # 获取图片文件名(去除相对路径)
        img_name = os.path.basename(json_info["imagePath"])
        img_path = os.path.join(image_path, img_name)
        print(f"图片路径: {img_path}")

        # 检查图片是否存在
        if not os.path.exists(img_path):
            print(f"警告: 图片不存在 {img_path}")
            continue

        # 读取图片
        img = cv2.imread(img_path)
        if img is None:
            print(f"警告: 无法读取图片 {img_path}")
            continue

        height, width, _ = img.shape
        np_w_h = np.array([[width, height]], np.int32)

        # 生成输出文件名
        txt_file = os.path.join(output_folder, os.path.splitext(img_name)[0] + ".txt")
        print(f"保存标注到: {txt_file}")

        # 写入标注信息
        with open(txt_file, "w") as f:
            for shape in json_info["shapes"]:
                # 获取每个形状的点
                points = shape["points"]
                # 转换为numpy数组
                np_points = np.array(points, np.float32)
                # 归一化坐标
                norm_points = np_points / np_w_h
                # 转换为列表
                norm_points_list = norm_points.tolist()
                # 生成标注内容
                txt_content = "0 " + " ".join(
                    [" ".join([str(cell[0]), str(cell[1])]) for cell in norm_points_list]
                ) + "\n"
                f.write(txt_content)

if __name__ == "__main__":
    convert_json_label_to_yolov_seg_label()

更多推荐