Labelme标注完别急着训练!手把手教你批量把JSON转成YOLO能吃的TXT格式
Labelme标注数据转YOLO格式实战指南从原理到批量处理当你用Labelme完成数百张图片的标注满心欢喜准备开始YOLO模型训练时却发现训练脚本报错——原来YOLO无法直接读取Labelme生成的JSON文件。这不是代码问题而是格式不匹配的典型情况。本文将带你深入理解两种格式的本质区别并提供可立即投入使用的完整解决方案。1. 为什么需要格式转换JSON与YOLO TXT的本质差异Labelme生成的JSON文件是一个结构化的标注容器它保存了完整的标注元数据。打开一个典型的Labelme JSON文件你会看到这样的结构{ version: 5.0.1, flags: {}, shapes: [ { label: cat, points: [[125, 342], [256, 410]], shape_type: rectangle } ], imagePath: example.jpg, imageWidth: 640, imageHeight: 480 }而YOLO需要的TXT格式则极为精简每行表示一个物体标注格式为类别索引 中心x坐标 中心y坐标 宽度 高度关键差异对比表特征Labelme JSONYOLO TXT数据结构层级化嵌套平面文本坐标表示绝对像素值归一化相对值(0-1)标注类型支持多种形状仅矩形框图像信息包含完整元数据仅保留必要标注提示YOLO格式的归一化坐标计算方法是中心点x坐标 (x_min x_max)/2 / 图像宽度2. 核心转换逻辑解析与代码实现转换过程本质上是从JSON中提取关键信息并重新编码的过程。我们需要处理两种主要标注类型矩形标注(rectangle)直接取两个对角点多边形标注(polygon)计算所有点的最小外接矩形以下是通过Python实现的核心转换函数def json_to_yolo(json_path, output_dir, class_list): with open(json_path) as f: data json.load(f) img_w data[imageWidth] img_h data[imageHeight] annotations [] for shape in data[shapes]: label shape[label] if label not in class_list: continue class_id class_list.index(label) points shape[points] # 处理不同形状的标注 if shape[shape_type] rectangle: x1, y1 points[0] x2, y2 points[1] elif shape[shape_type] polygon: x_coords [p[0] for p in points] y_coords [p[1] for p in points] x1, x2 min(x_coords), max(x_coords) y1, y2 min(y_coords), max(y_coords) else: continue # 转换为YOLO格式 x_center ((x1 x2) / 2) / img_w y_center ((y1 y2) / 2) / img_h width (x2 - x1) / img_w height (y2 - y1) / img_h annotations.append(f{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) # 保存结果 txt_name os.path.splitext(os.path.basename(json_path))[0] .txt with open(os.path.join(output_dir, txt_name), w) as f: f.write(\n.join(annotations))3. 批量处理实战从单文件到完整数据集实际项目中我们需要处理的是成百上千个JSON文件。以下脚本实现了完整的批量转换流程import os import json from tqdm import tqdm def batch_convert(json_dir, output_dir, class_list): os.makedirs(output_dir, exist_okTrue) json_files [f for f in os.listdir(json_dir) if f.endswith(.json)] print(fFound {len(json_files)} JSON files to process) for json_file in tqdm(json_files): json_path os.path.join(json_dir, json_file) json_to_yolo(json_path, output_dir, class_list) print(fConversion complete! Results saved to {output_dir}) # 配置参数 CLASSES [person, car, dog] # 替换为你的类别 JSON_DIR /path/to/json_folder # JSON文件目录 OUTPUT_DIR /path/to/output # 输出目录 # 执行转换 batch_convert(JSON_DIR, OUTPUT_DIR, CLASSES)常见问题处理清单类别不匹配当JSON中的标签不在class_list中时脚本会自动跳过并提示坐标越界通过max(0, value)确保归一化坐标不会小于0空标注文件没有有效标注的图片会生成空TXT文件特殊字符处理自动处理文件名中的空格等特殊字符注意运行前请确保所有JSON文件与对应图片位于同一目录且文件名一致仅扩展名不同4. 高级技巧与质量检查完成基础转换后还需要进行质量验证。推荐使用以下方法检查转换结果可视化检查脚本import cv2 import random def visualize_yolo(image_path, txt_path, class_names): image cv2.imread(image_path) h, w image.shape[:2] with open(txt_path) as f: lines f.readlines() for line in lines: class_id, x, y, bw, bh map(float, line.strip().split()) x1 int((x - bw/2) * w) y1 int((y - bh/2) * h) x2 int((x bw/2) * w) y2 int((y bh/2) * h) color (random.randint(0,255), random.randint(0,255), random.randint(0,255)) cv2.rectangle(image, (x1,y1), (x2,y2), color, 2) cv2.putText(image, class_names[int(class_id)], (x1,y1-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1) cv2.imshow(Preview, image) cv2.waitKey(0) cv2.destroyAllWindows()数据集完整性检查清单确保每个JSON都有对应的图片文件验证转换后的TXT文件非空有标注的图片检查类别索引是否正确映射抽样可视化确认标注框位置准确确认归一化坐标值都在[0,1]范围内对于大型项目可以考虑使用以下优化策略并行处理使用Python的multiprocessing加速批量转换增量处理记录已处理文件避免重复转换自动验证编写脚本自动统计各类别的实例数量5. 工程化实践将转换流程集成到训练管道在实际项目中数据格式转换应该成为训练管道的一个标准化环节。以下是推荐的工程实践目录结构规范dataset/ ├── images/ # 原始图片 ├── labels_json/ # Labelme生成的JSON ├── labels_yolo/ # 转换后的YOLO格式 ├── train.txt # 训练集列表 └── val.txt # 验证集列表自动化脚本示例#!/bin/bash # convert.sh - 自动化转换脚本 JSON_DIR./labels_json YOLO_DIR./labels_yolo CLASSES(person car bicycle) # 执行转换 python convert.py --input $JSON_DIR --output $YOLO_DIR --classes ${CLASSES[]} # 生成训练/验证集划分 python split_dataset.py --images ./images --labels $YOLO_DIR --output .与训练脚本的集成# train.py 片段 class CustomDataset: def __init__(self, img_dir, label_dir, classes): self.img_dir img_dir self.label_dir label_dir self.classes classes def __getitem__(self, idx): img_path self.img_files[idx] txt_path os.path.join(self.label_dir, os.path.splitext(os.path.basename(img_path))[0] .txt) # 读取和处理YOLO格式标注...在处理特别大的数据集时可以考虑先将YOLO格式转换为更高效的二进制格式如TFRecord以加速训练时的数据加载。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2485705.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!