import os import json import cv2 import random import time from PIL import Image # 部分同学都用的autodl, 用antodl举例 # 使用绝对路径 #数据集 txt格式-labels标签文件夹 txt_labels_path='/mnt/e/datasets/cocomini/val/labels' #数据集图片images文件夹 datasets_img_path='/mnt/e/datasets/cocomini/val/images' # 这里 voc 为数据集文件名字,可以改成自己的路径 # xx.json生成之后存放的地址 save_path='/mnt/e/basic model/contrast experiment/yolov12-main/yolov12-main/TXTToCOCO' #自己数据集的类别, 一行一个类 例如: class.txt文件 # car # phone # ... classes_txt='/mnt/e/basic model/contrast experiment/yolov12-main/yolov12-main/TXTToCOCO/class.txt' with open(classes_txt,'r') as fr: lines1=fr.readlines() categories=[] for j,label in enumerate(lines1): label=label.strip() categories.append({'id':j,'name':label,'supercategory':'None'}) print(categories) write_json_context=dict() write_json_context['info']= {'description': 'For object detection', 'url': '', 'version': '', 'year': 2021, 'contributor': '', 'date_created': '2021'} write_json_context['licenses']=[{'i解释
时间: 2025-06-25 12:07:16 浏览: 16
### 将YOLO TXT格式转换为COCO JSON格式
以下是将YOLO格式的TXT标注文件转换为COCO格式JSON文件的完整代码实现。此代码会处理类别、图片以及标注信息。
#### 转换逻辑说明
1. YOLO格式的标注文件通常存储在`.txt`文件中,每行表示一个目标框,格式为:
`<class_id> <x_center> <y_center> <width> <height>` (归一化坐标)。
2. COCO格式是一个复杂的JSON结构,包含多个字段,如`images`, `annotations`, 和 `categories`。需要将其映射到对应的字段。
3. 需要提供以下输入:
- 图像路径(用于获取图像尺寸)
- 标注路径(YOLO `.txt` 文件所在的目录)
- 类别列表(保存在`classes.txt`)
---
```python
import os
import json
from PIL import Image
def yolo_to_coco(image_dir, label_dir, classes_file, output_json):
"""
Convert YOLO format annotations to COCO format.
:param image_dir: Directory containing images.
:param label_dir: Directory containing YOLO .txt labels.
:param classes_file: File with class names.
:param output_json: Output path for the COCO-format JSON file.
"""
# Load categories from classes.txt
with open(classes_file, 'r') as f:
categories = [{'id': idx + 1, 'name': line.strip()} for idx, line in enumerate(f.readlines())]
images = []
annotations = []
annotation_id = 1 # Annotation ID starts at 1
# Iterate over all files in the label directory
for txt_file_name in sorted(os.listdir(label_dir)):
if not txt_file_name.endswith('.txt'):
continue
img_file_name = txt_file_name.replace('.txt', '.jpg')
img_path = os.path.join(image_dir, img_file_name)
try:
with Image.open(img_path) as img:
width, height = img.size
except FileNotFoundError:
print(f"Image {img_file_name} not found.")
continue
# Add image entry
image_info = {
"id": len(images) + 1,
"file_name": img_file_name,
"width": width,
"height": height
}
images.append(image_info)
# Parse and convert bounding boxes
with open(os.path.join(label_dir, txt_file_name), 'r') as f:
lines = f.readlines()
for line in lines:
parts = line.strip().split(' ')
category_id = int(parts[0]) + 1 # Category IDs start at 1
# Convert normalized coordinates back to absolute values
x_center_norm, y_center_norm, w_norm, h_norm = map(float, parts[1:])
x_center_abs = x_center_norm * width
y_center_abs = y_center_norm * height
box_w = w_norm * width
box_h = h_norm * height
# Calculate top-left corner of bbox
x_min = max(0, round(x_center_abs - box_w / 2))
y_min = max(0, round(y_center_abs - box_h / 2))
area = box_w * box_h
# Create annotation object
annotation = {
"id": annotation_id,
"image_id": image_info["id"],
"category_id": category_id,
"bbox": [x_min, y_min, box_w, box_h],
"area": area,
"iscrowd": 0
}
annotations.append(annotation)
annotation_id += 1
# Build final COCO structure
coco_data = {
"info": {"description": "Converted dataset"},
"licenses": [],
"categories": categories,
"images": images,
"annotations": annotations
}
# Save to JSON file
with open(output_json, 'w') as f:
json.dump(coco_data, f)
# Example usage
if __name__ == "__main__":
IMAGE_DIR = "./images"
LABEL_DIR = "./labels"
CLASSES_FILE = "./classes.txt"
OUTPUT_JSON = "./output/coco_annotations.json"
yolo_to_coco(IMAGE_DIR, LABEL_DIR, CLASSES_FILE, OUTPUT_JSON)
```
---
### 参数解释
- **`image_dir`**: 存储图像的目录路径。
- **`label_dir`**: 存储YOLO格式标注文件的目录路径。
- **`classes_file`**: 包含类别名称的文本文件路径,每一类占一行。
- **`output_json`**: 输出的COCO格式JSON文件路径。
---
### 注意事项
1. 如果某些图像缺少对应标签文件,则这些图像不会被加入最终的JSON文件中[^1]。
2. 假设所有图像均为JPEG格式;如果存在其他格式,请调整扩展名匹配部分。
3. 使用PIL库读取图像大小时,需确保安装依赖项:`pip install pillow`.
---
阅读全文