告别手动转换!用Python脚本一键批量处理AnyLabeling标注到YOLO格式

张开发
2026/6/6 23:39:06 15 分钟阅读
告别手动转换!用Python脚本一键批量处理AnyLabeling标注到YOLO格式
告别手动转换用Python脚本一键批量处理AnyLabeling标注到YOLO格式在计算机视觉项目中数据标注是模型训练前的关键步骤。AnyLabeling作为一款高效的标注工具凭借其用户友好的界面和丰富的功能成为许多开发者的首选。然而当标注完成后如何将这些数据快速转换为YOLO格式往往成为项目流程中的瓶颈。手动转换不仅耗时耗力还容易出错特别是在处理大规模数据集时。本文将介绍一个完整的Python脚本解决方案帮助开发者实现从AnyLabeling标注格式到YOLO格式的一键批量转换。这个方案不仅考虑了基本的格式转换需求还融入了错误处理、路径配置和类别映射等实用功能确保转换过程既高效又可靠。1. 理解AnyLabeling与YOLO格式差异在开始编写转换脚本前我们需要清楚理解两种格式的区别。AnyLabeling默认生成的标注文件是JSON格式包含以下关键信息{ version: 0.1.0, flags: {}, shapes: [ { label: cat, points: [[100, 150], [200, 250]], shape_type: rectangle } ], imagePath: example.jpg, imageData: null, imageHeight: 480, imageWidth: 640 }而YOLO格式则更为简洁每个标注对象对应一个文本文件内容格式为class_id x_center y_center width height其中坐标值都是相对于图像宽度和高度的归一化值0-1之间。关键转换步骤解析JSON文件中的边界框坐标计算中心点坐标和宽高将绝对坐标转换为相对坐标根据类别映射字典转换类别名称到ID将结果写入对应的TXT文件2. 构建模块化转换脚本一个健壮的转换脚本应该具备模块化设计便于维护和扩展。以下是脚本的主要模块划分2.1 核心转换函数def anylabeling_to_yolo(json_path, cls2id_dict): 将单个AnyLabeling JSON文件转换为YOLO格式标注 参数: json_path: AnyLabeling生成的JSON文件路径 cls2id_dict: 类别名称到ID的映射字典 返回: list: 包含所有标注对象的YOLO格式字符串列表 try: with open(json_path, r, encodingutf-8) as f: data json.load(f) img_width data[imageWidth] img_height data[imageHeight] labels [] for shape in data[shapes]: if shape[shape_type].lower() ! rectangle: continue # 只处理矩形标注 points shape[points] x1, y1 points[0] x2, y2 points[1] # 计算中心点和宽高 x_center (x1 x2) / 2 / img_width y_center (y1 y2) / 2 / img_height width abs(x2 - x1) / img_width height abs(y2 - y1) / img_height # 获取类别ID class_id cls2id_dict.get(shape[label], -1) if class_id -1: continue # 跳过未定义类别 labels.append(f{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) return labels except Exception as e: print(fError processing {json_path}: {str(e)}) return []2.2 批量处理与文件写入def batch_convert(json_dir, save_dir, cls2id_dict): 批量转换JSON标注文件为YOLO格式 参数: json_dir: 包含JSON标注文件的目录 save_dir: 保存YOLO格式TXT文件的目录 cls2id_dict: 类别名称到ID的映射字典 if not os.path.exists(save_dir): os.makedirs(save_dir) for json_file in os.listdir(json_dir): if not json_file.endswith(.json): continue json_path os.path.join(json_dir, json_file) txt_file os.path.splitext(json_file)[0] .txt txt_path os.path.join(save_dir, txt_file) labels anylabeling_to_yolo(json_path, cls2id_dict) if labels: with open(txt_path, w, encodingutf-8) as f: f.write(\n.join(labels)) print(fConverted {json_file} successfully)3. 配置与错误处理3.1 路径配置策略在实际项目中数据集的组织方式可能各不相同。我们的脚本需要灵活适应不同的目录结构。建议采用以下配置方式# 配置示例 config { image_dir: path/to/images, # 原始图像目录 json_dir: path/to/json_labels, # JSON标注文件目录 yolo_dir: path/to/yolo_labels, # 输出YOLO标注目录 class_mapping: { # 类别映射 person: 0, car: 1, dog: 2 } }3.2 常见错误处理错误类型检测方法处理方式路径不存在os.path.exists()创建目录或提示用户JSON格式错误json.JSONDecodeError跳过文件并记录错误类别未定义dict.get()返回-1跳过该标注或使用默认类别图像尺寸缺失检查imageWidth/Height使用默认尺寸或从图像读取提示在生产环境中建议将错误记录到日志文件中方便后续排查问题。4. 高级功能扩展4.1 多线程批量处理对于大规模数据集可以使用多线程加速处理from concurrent.futures import ThreadPoolExecutor def parallel_convert(json_dir, save_dir, cls2id_dict, workers4): 多线程批量转换 json_files [f for f in os.listdir(json_dir) if f.endswith(.json)] with ThreadPoolExecutor(max_workersworkers) as executor: futures [] for json_file in json_files: json_path os.path.join(json_dir, json_file) txt_file os.path.splitext(json_file)[0] .txt txt_path os.path.join(save_dir, txt_file) future executor.submit( process_single_file, json_path, txt_path, cls2id_dict ) futures.append(future) for future in futures: future.result() # 等待所有任务完成4.2 与数据增强流程集成转换脚本可以很容易地集成到数据增强流程中def process_dataset(input_dir, output_dir, augmentFalse): 完整的数据处理流程 # 1. 转换标注格式 batch_convert( os.path.join(input_dir, labels_json), os.path.join(output_dir, labels_yolo), CLASS_MAPPING ) # 2. 可选的数据增强 if augment: apply_augmentation( os.path.join(input_dir, images), os.path.join(output_dir, images_aug), os.path.join(output_dir, labels_yolo), os.path.join(output_dir, labels_yolo_aug) ) # 3. 生成数据集配置文件 generate_yaml( output_dir, classeslist(CLASS_MAPPING.keys()) )4.3 可视化验证工具转换完成后建议添加一个简单的可视化验证脚本import cv2 import numpy as np def visualize_yolo_label(image_path, label_path, class_names): 可视化YOLO格式标注 image cv2.imread(image_path) h, w image.shape[:2] with open(label_path, r) as f: lines f.readlines() for line in lines: parts line.strip().split() if len(parts) ! 5: continue class_id, x, y, w, h map(float, parts) 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(image, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(image, class_names[int(class_id)], (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (36, 255, 12), 2) cv2.imshow(Preview, image) cv2.waitKey(0) cv2.destroyAllWindows()5. 实际应用建议在实际项目中应用这个转换脚本时有几个实用技巧值得分享路径管理使用pathlib模块代替os.path代码更简洁跨平台配置文件将路径和类别映射放在单独的YAML/JSON配置文件中进度显示添加tqdm进度条提升用户体验单元测试为关键函数编写测试用例确保转换准确性异常恢复实现断点续转功能避免大规模数据集处理中断一个典型的项目目录结构建议如下project/ ├── config.yaml # 配置文件 ├── scripts/ │ ├── convert.py # 转换脚本 │ └── visualize.py # 可视化脚本 ├── data/ │ ├── raw/ # 原始数据 │ │ ├── images/ # 图像文件 │ │ └── labels_json/ # AnyLabeling JSON标注 │ └── processed/ # 处理后的数据 │ ├── images/ # (可选)处理后的图像 │ └── labels_yolo/ # YOLO格式标注 └── tests/ # 测试用例将转换脚本集成到你的计算机视觉项目中可以节省大量手动操作时间让开发者更专注于模型设计和优化。根据实际需求你可以进一步扩展脚本功能比如添加对多边形标注的支持或者集成到自动化训练流程中。

更多文章