从X-AnyLabeling到YOLO:一站式JSON标签转换实战指南(附Python脚本)
1. 为什么需要JSON到YOLO的标签转换当你用X-AnyLabeling标注完几百张行人姿态图片后发现YOLO模型根本不认这些JSON文件这时候你就需要格式转换了。这就像你写了一封情书对方却只收电报——不是内容不对只是格式不匹配。我去年处理过一个商场监控项目客户给的就是X-AnyLabeling标注的JSON文件。直接打开看会发现它记录的是每个标注框的绝对坐标和类别名称。但YOLO需要的是相对坐标和数字编号就像把站立变成数字0把坐标从像素值变成0到1之间的小数。最常见的三类问题坐标计算错误有人直接用左上角坐标当中心点导致目标框漂移类别映射遗漏漏掉弯腰这类特殊姿态训练时直接报错批量处理崩溃脚本没做异常处理遇到空文件就中断2. 解剖X-AnyLabeling的JSON结构先看一个真实案例的JSON片段{ version: 0.1.0, flags: {}, shapes: [ { label: sitting, points: [[120, 240], [300, 240], [300, 360], [120, 360]], shape_type: polygon } ], imagePath: mall_001.jpg }关键字段解读shapes数组包含所有标注对象每个对象的points是四边形顶点坐标注意顺序label直接使用英文类别名特别注意X-AnyLabeling的坐标是[[x1,y1],[x2,y2],[x3,y3],[x4,y4]]的四边形表示而YOLO需要的是矩形中心点(x,y)和宽高(w,h)。这就涉及到两个关键计算从四边形到外接矩形的转换绝对坐标到相对坐标的归一化3. 手把手编写转换脚本3.1 基础版本单文件转换先看核心计算逻辑的Python实现def bbox_to_yolo(points, img_w, img_h): 将四边形坐标转换为YOLO格式 x_coords [p[0] for p in points] y_coords [p[1] for p in points] x_min, x_max min(x_coords), max(x_coords) y_min, y_max min(y_coords), max(y_coords) # 计算中心点和宽高 x_center (x_min x_max) / 2 / img_w y_center (y_min y_max) / 2 / img_h width (x_max - x_min) / img_w height (y_max - y_min) / img_h return x_center, y_center, width, height3.2 增强版本批量处理与异常处理实际项目中我推荐这样改进import traceback def process_batch(json_dir, output_dir): for filename in os.listdir(json_dir): if not filename.endswith(.json): continue try: with open(os.path.join(json_dir, filename)) as f: data json.load(f) # 获取图片实际尺寸更准确的做法 img_path os.path.join(json_dir, data[imagePath]) with Image.open(img_path) as img: img_w, img_h img.size # 处理每个标注 with open(f{output_dir}/{filename.replace(.json,.txt)}, w) as out_f: for shape in data[shapes]: # 添加类别验证 if shape[label] not in CLASS_MAPPING: raise ValueError(f未知类别: {shape[label]}) # 坐标转换 x, y, w, h bbox_to_yolo(shape[points], img_w, img_h) # 写入文件 out_f.write(f{CLASS_MAPPING[shape[label]]} {x:.6f} {y:.6f} {w:.6f} {h:.6f}\n) except Exception as e: print(f处理文件 {filename} 出错: {str(e)}) traceback.print_exc()4. 避坑指南与性能优化4.1 常见报错解决方案坐标超出[0,1]范围检查图片尺寸是否获取正确我曾遇到过EXIF旋转导致宽高颠倒的情况类别映射缺失建议在脚本开头定义完整的CLASS_MAPPING字典空文件处理添加if not data[shapes]: continue跳过无标注文件4.2 高级技巧多进程加速用multiprocessing.Pool处理上万文件时速度能提升5-8倍from multiprocessing import Pool def worker(args): json_file, output_dir args # 处理单个文件... if __name__ __main__: files [(f, output_dir) for f in os.listdir(json_dir)] with Pool(processes4) as pool: pool.map(worker, files)可视化校验用OpenCV绘制转换后的标注框确保没出错import cv2 def visualize_yolo(img_path, txt_path): img cv2.imread(img_path) h, w img.shape[:2] with open(txt_path) as f: for line in f: cls, x, y, w, h map(float, line.split()) # 转换回绝对坐标 x1 int((x - w/2) * w) y1 int((y - h/2) * h) x2 int((x w/2) * w) y2 int((y h/2) * h) cv2.rectangle(img, (x1,y1), (x2,y2), (0,255,0), 2) cv2.imshow(check, img) cv2.waitKey(0)5. 完整脚本与使用示例最终版的脚本应该包含以下功能自动创建输出目录支持相对/绝对路径详细的日志记录进度显示使用方法python convert.py \ --json-dir ./annotations \ --output-dir ./yolo_labels \ --class-map {standing:0, sitting:1} \ --workers 4建议在转换完成后随机抽查5%的文件进行可视化校验。这个习惯帮我避免过三次重大数据错误特别是在标注团队中途修改过标注规范的情况下。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2524095.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!