# -*- coding: utf-8 -*- import json import os import argparse from tqdm import tqdm def convert_label_json(json_dir, save_dir, classes): """ 将标注文件从 JSON 格式转换为 YOLO 格式的文本文件,并进行坐标归一化。 :param json_dir: 包含 JSON 文件的目录路径 :param save_dir: 保存转换后文本文件的目录路径 :param classes: 类别名称列表,用逗号分隔 """ # 获取目录中所有 JSON 文件的路径 json_paths = os.listdir(json_dir) # 将类别字符串转换为列表 classes = classes.split(',') # 遍历所有 JSON 文件 for json_path in tqdm(json_paths): # 构建 JSON 文件的完整路径 path = os.path.join(json_dir, json_path) # 打开并读取 JSON 文件 with open(path, 'r', encoding='utf-8') as load_f: json_dict = json.load(load_f) # 获取图像的高度和宽度 h, w = json_dict['imageHeight'], json_dict['imageWidth'] # 构建保存 TXT 文件的路径 txt_path = os.path.join(save_dir, json_path.replace('json', 'txt')) with open(txt_path, 'w') as txt_file: # 遍历每个形状(标注) for shape_dict in json_dict['shapes']: # 获取标注的类别标签 label = shape_dict['label'] # 获取类别的索引 label_index = classes.index(label) # 获取标注的点坐标 points = shape_dict['points'] # 用于存储归一化后的坐标 points_nor_list = [] # 归一化坐标 for point in points: points_nor_list.append(point[0] / w) points_nor_list.append(point[1] / h) # 将坐标转换为字符串格式 points_nor_list = list(map(lambda x: str(x), points_nor_list)) points_nor_str = ' '.join(points_nor_list) # 构建 YOLO 格式的标签字符串 label_str = str(label_index) + ' ' + points_nor_str + '\n' # 写入到 TXT 文件 txt_file.writelines(label_str) if __name__ == "__main__": """ 命令行用法示例: python json2txt_nomalize.py --json-dir my_datasets/color_rings/jsons --save-dir my_datasets/color_rings/txts --classes "cat,dog" """ # 设置命令行参数解析 parser = argparse.ArgumentParser(description='json 转换为 txt 参数') parser.add_argument('--json-dir', type=str, default="json", help='JSON 文件所在目录') parser.add_argument('--save-dir', type=str, default="dataset/train/labels", help='转换后 TXT 文件保存目录') parser.add_argument('--classes', type=str, default='wampee', help='类别列表,逗号分隔') # 解析命令行参数 args = parser.parse_args() json_dir = args.json_dir save_dir = args.save_dir classes = args.classes # 调用转换函数 convert_label_json(json_dir, save_dir, classes)