大家在使用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()