将YOLO格式数据集转换为COCO格式需要处理图像、标注文件以及生成COCO格式的JSON文件。以下Python代码实现,考虑了各种可能的因素,包括图像尺寸、类别映射、标注框的归一化处理等。
YOLO_6">YOLO格式说明
- 标注文件:每个图像对应一个
.txt
文件,每行格式为class_id x_center y_center width height
,其中坐标和尺寸是归一化的(相对于图像宽度和高度)。 - 图像文件:通常与标注文件同名,格式为
.jpg
或.png
。 - 类别文件:
classes.txt
,每行一个类别名称。
COCO格式说明
- JSON 文件:包含以下主要字段:
images
: 图像信息(id、文件名、宽度、高度)。annotations
: 标注信息(id、图像id、类别id、边界框、面积等)。categories
: 类别信息(id、类别名称)。
转换代码
import os
import json
import cv2
from tqdm import tqdmdef yolo_to_coco(yolo_dir, output_json_path):"""将YOLO格式数据集转换为COCO格式。:param yolo_dir: YOLO格式数据集的根目录,包含images、labels文件夹和classes.txt。:param output_json_path: 输出的COCO格式JSON文件路径。"""# 路径设置images_dir = os.path.join(yolo_dir, 'images')labels_dir = os.path.join(yolo_dir, 'labels')classes_file = os.path.join(yolo_dir, 'classes.txt')# 检查路径是否存在if not os.path.exists(images_dir) or not os.path.exists(labels_dir):raise FileNotFoundError("images 或 labels 文件夹不存在!")if not os.path.exists(classes_file):raise FileNotFoundError("classes.txt 文件不存在!")# 读取类别with open(classes_file, 'r') as f:categories = [line.strip() for line in f.readlines()]categories = [{"id": i + 1, "name": name} for i, name in enumerate(categories)]# 初始化COCO数据结构coco_data = {"images": [],"annotations": [],"categories": categories}# 遍历图像image_id = 1annotation_id = 1for image_name in tqdm(os.listdir(images_dir)):if not image_name.endswith(('.jpg', '.png', '.jpeg')):continue# 读取图像尺寸image_path = os.path.join(images_dir, image_name)image = cv2.imread(image_path)height, width, _ = image.shape# 添加图像信息coco_data["images"].append({"id": image_id,"file_name": image_name,"width": width,"height": height})# 读取对应的标注文件label_name = os.path.splitext(image_name)[0] + '.txt'label_path = os.path.join(labels_dir, label_name)if not os.path.exists(label_path):continuewith open(label_path, 'r') as f:lines = f.readlines()# 解析标注for line in lines:parts = line.strip().split()if len(parts) != 5:continueclass_id, x_center, y_center, bbox_width, bbox_height = map(float, parts)# 将归一化坐标转换为绝对坐标x_center *= widthy_center *= heightbbox_width *= widthbbox_height *= height# 计算边界框的左上角坐标x_min = x_center - (bbox_width / 2)y_min = y_center - (bbox_height / 2)# 计算面积area = bbox_width * bbox_height# 添加标注信息coco_data["annotations"].append({"id": annotation_id,"image_id": image_id,"category_id": int(class_id) + 1, # YOLO类别从0开始,COCO从1开始"bbox": [x_min, y_min, bbox_width, bbox_height],"area": area,"iscrowd": 0})annotation_id += 1image_id += 1# 保存为COCO格式的JSON文件with open(output_json_path, 'w') as f:json.dump(coco_data, f, indent=4)print(f"转换完成!COCO格式文件已保存到: {output_json_path}")# 示例调用
yolo_dir = "path/to/yolo_dataset" # YOLO数据集根目录
output_json_path = "output/coco_format.json" # 输出的COCO格式JSON文件路径
yolo_to_coco(yolo_dir, output_json_path)
代码说明
- 路径检查:确保
images
、labels
文件夹和classes.txt
文件存在。 - 类别映射:从
classes.txt
读取类别名称,并映射到COCO格式的categories
。 - 图像处理:遍历图像文件夹,读取每张图像的尺寸,并添加到
images
字段。 - 标注处理:
- 解析YOLO格式的
.txt
文件。 - 将归一化的边界框坐标转换为绝对坐标。
- 计算边界框的面积。
- 添加到
annotations
字段。
- 解析YOLO格式的
- 保存JSON:将生成的COCO格式数据保存为JSON文件。
注意事项
- 图像格式:代码支持
.jpg
、.png
和.jpeg
格式的图像。如果需要支持其他格式,可以修改代码。 - 类别ID:YOLO格式的类别ID从0开始,而COCO格式从1开始,因此在转换时需要加1。
- 边界框归一化:YOLO格式的边界框坐标是归一化的,需要乘以图像尺寸转换为绝对坐标。
- 空标注文件:如果某个图像没有对应的标注文件,代码会跳过该图像。
示例目录结构
yolo_dataset/
├── images/
│ ├── image1.jpg
│ ├── image2.jpg
├── labels/
│ ├── image1.txt
│ ├── image2.txt
└── classes.txt
运行代码后,生成的COCO格式JSON文件可以直接用于训练COCO格式的目标检测模型。