当前位置: 首页 > news >正文

从X-AnyLabeling到YOLO:一站式JSON标签转换实战指南(附Python脚本)

1. 为什么需要JSON到YOLO的标签转换

当你用X-AnyLabeling标注完几百张行人姿态图片后,发现YOLO模型根本不认这些JSON文件,这时候你就需要格式转换了。这就像你写了一封情书,对方却只收电报——不是内容不对,只是格式不匹配。

我去年处理过一个商场监控项目,客户给的就是X-AnyLabeling标注的JSON文件。直接打开看会发现,它记录的是每个标注框的绝对坐标和类别名称。但YOLO需要的是相对坐标和数字编号,就像把"站立"变成数字"0",把坐标从"像素值"变成"0到1之间的小数"。

最常见的三类问题:

  1. 坐标计算错误:有人直接用左上角坐标当中心点,导致目标框漂移
  2. 类别映射遗漏:漏掉"弯腰"这类特殊姿态,训练时直接报错
  3. 批量处理崩溃:脚本没做异常处理,遇到空文件就中断

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)。这就涉及到两个关键计算:

  1. 从四边形到外接矩形的转换
  2. 绝对坐标到相对坐标的归一化

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, height

3.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 高级技巧

  1. 多进程加速:用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(processes=4) as pool: pool.map(worker, files)
  1. 可视化校验:用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.jsqmd.com/news/651390/

相关文章:

  • 从模型检测实战看三大逻辑:CTL、PLTL与mu-演算的选型指南
  • 批处理脚本进阶:环境隔离、参数轮转与流式处理
  • 某手App反爬核心sig3算法解析:从Unidbg服务部署到接口调用的完整链路
  • Unity3d Cinemachine篇(一)— 初探Virtual Camera:从零搭建你的首个智能镜头
  • 手把手教你用Glean搭建企业知识图谱:从Slack到Confluence的完整配置流程
  • 避坑指南:部署完kube-prometheus后,为什么Grafana/Prometheus页面还是打不开?
  • 合宙ESP32C3实战:MPU6500六轴传感器数据读取与校准全解析
  • 用CY7C68013A模拟MDIO时序?这些GPIO配置细节你可能不知道
  • 央视曝光 AI 涉灰产业链:技术红利正被滥用,监管必须跟上
  • 从源码到一键安装包:教你用PyInstaller打包定制版LabelImg(解决闪退和预置标签问题)
  • 《TRAE从入门到精通全攻略》,零基础也能快速上手,助力你快速成长为程序员
  • 雷达信号分析入门:脉内脉间调制到底在玩什么花样?
  • 基于 MATLAB 实现的可视密码图示法设计
  • PCB设计老鸟的AD21 DRC设置清单:如何为你的高速板与低速板定制专属检查规则
  • 终极Windows ISO补丁集成指南:一键制作最新补丁安装镜像的完整教程
  • 科学化学工管理:让教育更高效,让学生更满意
  • DRV8701E双电机驱动电路实战:从原理图困惑到PCB布局的避坑指南
  • Nginx正向代理实战:从源码编译到HTTPS支持的全流程指南
  • 如何用Python自动化脚本破解大麦网抢票难题:技术原理与实战指南
  • 提前72小时预警,巡检提效60%!华电集团联合吉泰智能斩获《火电燃料技术创新大奖》
  • PiliPlus:跨平台B站客户端终极指南,简单快速享受高清视频体验
  • 新手小白实战教程:用 TRAE 从零创建一个“个人日记本”网页应用
  • 【25考研】人大计算机复试:从参考书目到实战面试的避坑指南
  • TVS选型实战指南:从参数到应用的精准匹配
  • 【Pytorch】利用torchvision.utils.save_image高效实现tensor到图片的批量转换与保存
  • 边走边聊 Python 3.8:Chapter 10:Tkinter 桌面小工具
  • 别再手动点Model Explorer了!用Matlab脚本批量修改Stateflow参数,效率翻倍
  • SpringBoot与knife4j无缝集成实战(零基础到精通)
  • 用100块的普通摄像头,我让机械臂学会了‘盲抓’:YOLOv5+Depth-Anything+AnyGrasp实战避坑
  • TimesFM时间序列预测:谷歌基础模型让零样本预测变得如此简单