Link to this sectionCách chuyển đổi chú thích COCO sang định dạng YOLO#
Việc huấn luyện các mô hình Ultralytics YOLO yêu cầu các chú thích ở định dạng YOLO, nhưng nhiều công cụ annotation phổ biến lại xuất dữ liệu dưới định dạng COCO JSON. Hướng dẫn này sẽ chỉ cho bạn cách chuyển đổi chú thích COCO sang định dạng YOLO để bắt đầu huấn luyện các mô hình object detection, instance segmentation và pose estimation.
Để huấn luyện trực tiếp trên COCO JSON mà không cần tạo tệp .txt, hãy xem Huấn luyện YOLO trên COCO JSON mà không cần chuyển đổi.
Link to this sectionTại sao cần chuyển đổi từ COCO sang YOLO?#
Định dạng COCO JSON lưu trữ tất cả các annotation trong một tệp duy nhất, trong khi YOLO sử dụng một tệp văn bản cho mỗi hình ảnh với các tọa độ đã được chuẩn hóa. Việc chuyển đổi là cần thiết vì:
- Các mô hình YOLO yêu cầu các tệp nhãn
.txtvới mỗi tệp cho mỗi ảnh, chứaclass x_center y_center width heighttheo tọa độ được chuẩn hóa. - COCO JSON sử dụng tọa độ điểm ảnh theo định dạng
[x_min, y_min, width, height]với một tệp JSON duy nhất cho tất cả các ảnh. - Class ID khác nhau — COCO sử dụng các giá trị
category_idtùy ý, trong khi YOLO yêu cầu các Class ID bắt đầu từ 0.
| Tính năng | COCO JSON | YOLO TXT |
|---|---|---|
| Cấu trúc | Một tệp JSON cho tất cả các ảnh | Một tệp .txt cho mỗi ảnh |
| Định dạng Bbox | [x_min, y_min, width, height] theo pixel | class x_center y_center width height đã chuẩn hóa (0-1) |
| Class ID | category_id (có thể bắt đầu từ bất kỳ số nào) | Chỉ số bắt đầu từ 0 |
| Segmentation | Các mảng đa giác trong trường segmentation | Tọa độ đa giác sau Class ID |
| Keypoints | [x, y, visibility, ...] theo pixel | [x, y, visibility, ...] đã chuẩn hóa |
Link to this sectionBắt đầu nhanh#
Cách nhanh nhất để chuyển đổi chú thích COCO và bắt đầu huấn luyện:
from ultralytics.data.converter import convert_coco
convert_coco(
labels_dir="my_dataset/annotations/", # directory containing your JSON files
save_dir="my_dataset/converted/", # where to save converted labels
cls91to80=False, # set False for custom datasets (see warning below)
)Sau khi chuyển đổi, hãy tổ chức cấu trúc thư mục, tạo tệp dataset.yaml và bắt đầu huấn luyện. Xem đầy đủ hướng dẫn từng bước bên dưới.
Giá trị mặc định cls91to80=True chỉ được thiết kế cho tập dữ liệu COCO tiêu chuẩn với 80 lớp đối tượng, giúp ánh xạ 91 ID danh mục không liên tục sang 80 ID lớp liên tục. Đối với bất kỳ tập dữ liệu tùy chỉnh nào, bạn phải đặt cls91to80=False — nếu không, ID lớp của bạn sẽ bị ánh xạ sai một cách âm thầm và model của bạn sẽ học các lớp không chính xác.
Link to this sectionHướng dẫn chuyển đổi từng bước#
Link to this section1. Chuẩn bị tập dữ liệu COCO của bạn#
Một tập dữ liệu định dạng COCO điển hình được xuất từ các công cụ annotation có cấu trúc sau:
my_dataset/
├── images/
│ ├── train/
│ │ ├── img_001.jpg
│ │ ├── img_002.jpg
│ │ └── ...
│ └── val/
│ ├── img_100.jpg
│ └── ...
└── annotations/
├── instances_train.json
└── instances_val.jsonMỗi tệp JSON tuân theo đặc tả COCO data format với ba trường bắt buộc — images, annotations và categories:
{
"images": [{ "id": 1, "file_name": "img_001.jpg", "width": 640, "height": 480 }],
"annotations": [
{
"id": 1,
"image_id": 1,
"category_id": 1,
"bbox": [100, 50, 200, 150],
"area": 30000,
"iscrowd": 0
}
],
"categories": [
{ "id": 1, "name": "helmet" },
{ "id": 2, "name": "vest" }
]
}Link to this section2. Chuyển đổi chú thích#
Sử dụng hàm convert_coco() để chuyển đổi các chú thích COCO JSON sang định dạng .txt của YOLO:
from ultralytics.data.converter import convert_coco
convert_coco(
labels_dir="my_dataset/annotations/",
save_dir="my_dataset/converted/",
cls91to80=False,
)convert_coco() ghi một tệp .txt cho mỗi ảnh được gán nhãn vào thư mục con labels/ được đặt tên theo từng tệp JSON, với tiền tố instances_ đã bị loại bỏ (vì vậy instances_train.json sẽ tạo ra labels/train/). Các ảnh không có nhãn sẽ bị bỏ qua và không nhận được tệp nhãn nào, do đó cấu trúc cây labels/ có thể không phản ánh chính xác từng ảnh:
my_dataset/converted/
└── labels/
├── train/ # from instances_train.json
│ ├── img_001.txt
│ └── ...
└── val/ # from instances_val.json
└── ...convert_coco() không bao giờ ghi đè lên save_dir đã tồn tại: nếu my_dataset/converted/ đã tồn tại, việc chạy lại sẽ ghi vào my_dataset/converted-2/ thay thế. Hãy xóa kết quả đầu ra trước đó (hoặc thay đổi save_dir) trước khi chạy lại, nếu không các bước tiếp theo sẽ đọc nhãn cũ.
Link to this section3. Tổ chức cấu trúc thư mục#
Sau khi chuyển đổi, các tệp nhãn cần được đặt cùng với các hình ảnh của bạn. YOLO yêu cầu một thư mục labels/ phản chiếu thư mục images/:
import shutil
from pathlib import Path
converted_dir = Path("my_dataset/converted/labels")
dataset_dir = Path("my_dataset")
# convert_coco names each subdirectory after its JSON file (minus the "instances_" prefix),
# so iterate the actual subdirectories instead of assuming "train"/"val".
for src in converted_dir.iterdir():
if not src.is_dir():
continue
dst = dataset_dir / "labels" / src.name
dst.mkdir(parents=True, exist_ok=True)
for f in src.glob("*.txt"):
shutil.move(str(f), str(dst / f.name))Cấu trúc tập dữ liệu cuối cùng của bạn sẽ trông như sau:
my_dataset/
├── images/
│ ├── train/
│ │ ├── img_001.jpg
│ │ └── ...
│ └── val/
│ └── ...
├── labels/
│ ├── train/
│ │ ├── img_001.txt
│ │ └── ...
│ └── val/
│ └── ...
└── dataset.yamlLink to this section4. Tạo dataset.yaml#
Tạo tệp cấu hình dataset.yaml để ánh xạ các danh mục COCO của bạn sang tên lớp YOLO. Tệp này thông báo cho YOLO vị trí dữ liệu của bạn và các lớp cần phát hiện:
import json
from pathlib import Path
import yaml
# Read categories from your COCO JSON
with open("my_dataset/annotations/instances_train.json") as f:
coco = json.load(f)
# Build class names matching convert_coco output (category_id - 1)
categories = sorted(coco["categories"], key=lambda x: x["id"])
names = {cat["id"] - 1: cat["name"] for cat in categories}
# NOTE: convert_coco maps class IDs as category_id - 1, so category_id must
# start from 1. If your categories start from 0, add 1 to each ID first.
# Create dataset.yaml
dataset = {
"path": str(Path("my_dataset").resolve()),
"train": "images/train",
"val": "images/val",
"names": names,
}
with open("my_dataset/dataset.yaml", "w") as f:
yaml.dump(dataset, f, default_flow_style=False)Tệp YAML thu được:
path: /absolute/path/to/my_dataset
train: images/train
val: images/val
names:
0: helmet
1: vestĐể biết thêm chi tiết về định dạng YAML của tập dữ liệu, hãy xem hướng dẫn cấu hình tập dữ liệu.
Link to this section5. Huấn luyện mô hình YOLO của bạn#
Với tập dữ liệu đã chuyển đổi sẵn sàng, hãy huấn luyện mô hình YOLO:
from ultralytics import YOLO
model = YOLO("yolo26n.pt") # load a pretrained model
results = model.train(data="my_dataset/dataset.yaml", epochs=100, imgsz=640)Để biết các mẹo và thực tiễn tốt nhất khi huấn luyện, hãy xem hướng dẫn huấn luyện mô hình.
Link to this section6. Xác minh quá trình chuyển đổi của bạn#
Trước khi huấn luyện, hãy kiểm tra ngẫu nhiên một vài tệp nhãn để xác nhận Class ID và tọa độ là chính xác:
from pathlib import Path
label_file = Path("my_dataset/labels/train/img_001.txt")
for line in label_file.read_text().strip().splitlines():
parts = line.split()
cls_id = int(parts[0])
coords = [float(v) for v in parts[1:5]]
assert cls_id >= 0, f"Negative class ID {cls_id} — category_id in your JSON may start from 0"
assert all(0 <= v <= 1 for v in coords), f"Coordinates out of [0, 1] range: {coords}"Nếu bạn thấy các Class ID âm, tệp COCO JSON của bạn có khả năng sử dụng category_id bắt đầu từ 0. Hãy cộng thêm 1 vào tất cả các giá trị category_id trong tệp JSON của bạn trước khi chạy convert_coco(), vì nó ánh xạ các Class ID là category_id - 1.
Link to this sectionKhắc phục các sự cố thường gặp#
Link to this sectionSai Class ID sau khi chuyển đổi#
Nếu mô hình của bạn huấn luyện được nhưng phát hiện sai các lớp đối tượng, có khả năng bạn đang sử dụng cls91to80=True (mặc định) cho một tập dữ liệu tùy chỉnh. Điều này ánh xạ các giá trị category_id của bạn thông qua bảng tra cứu COCO 91-sang-80, vốn chỉ đúng cho COCO dataset tiêu chuẩn.
Giải pháp: Luôn sử dụng cls91to80=False cho các tập dữ liệu tùy chỉnh.
Link to this sectionKhông tìm thấy nhãn trong quá trình huấn luyện#
Nếu quá trình huấn luyện hiển thị WARNING: No labels found hoặc 0 images, N backgrounds, các tệp nhãn của bạn không nằm trong thư mục dự kiến. convert_coco() lưu nhãn vào một thư mục đầu ra riêng (ví dụ: save_dir/labels/train/), nhưng YOLO yêu cầu thư mục labels/ song song với images/ bên trong thư mục tập dữ liệu của bạn.
Giải pháp: Di chuyển các tệp nhãn để khớp với cấu trúc thư mục dự kiến. Đảm bảo labels/train/ nằm cùng cấp với images/train/.
Link to this sectionKeyError trong quá trình chuyển đổi#
Nếu bạn gặp lỗi KeyError: 'bbox' hoặc các lỗi tương tự khi chạy convert_coco(), thư mục labels_dir của bạn có thể chứa các tệp JSON không phải dạng instance (ví dụ: captions_train2017.json) vốn có cấu trúc chú thích khác.
Giải pháp: Chỉ đặt các tệp JSON chú thích instance (ví dụ: instances_train2017.json) vào thư mục labels_dir.
Link to this sectionCác tệp nhãn trống sau khi chuyển đổi#
Nếu quá trình chuyển đổi hoàn tất nhưng các tệp .txt trống hoặc thiếu, tất cả các chú thích có thể có iscrowd: 1 (phổ biến với các mask được tạo bởi SAM), hoặc bounding boxes có chiều rộng hoặc chiều cao bằng 0.
Giải pháp: Kiểm tra các chú thích JSON của bạn để tìm giá trị iscrowd. Nếu sử dụng mask SAM, hãy tiền xử lý JSON để đặt iscrowd: 0.
Link to this sectionKhoảng trống Class ID trong các nhãn đã chuyển đổi#
Nếu Class ID trong các tệp nhãn không liên tục (ví dụ: 0, 4, 9 thay vì 0, 1, 2), công cụ annotation của bạn sử dụng các giá trị category_id không liên tục.
Giải pháp: Xác minh các Class ID trong tệp .txt của bạn khớp với từ điển names trong dataset.yaml. Ánh xạ lại các ID thành các giá trị liên tục nếu cần.
Để biết chi tiết API đầy đủ và mô tả tham số, hãy xem convert_coco API reference.
Link to this sectionCâu hỏi thường gặp#
Link to this sectionLàm thế nào để chuyển đổi chú thích COCO JSON sang định dạng YOLO?#
Sử dụng hàm convert_coco() từ Ultralytics để chuyển đổi chú thích COCO JSON sang định dạng .txt của YOLO. Đặt cls91to80=False cho các tập dữ liệu tùy chỉnh:
from ultralytics.data.converter import convert_coco
convert_coco(labels_dir="path/to/annotations/", save_dir="output/", cls91to80=False)Sau khi chuyển đổi, hãy sắp xếp lại các tệp nhãn của bạn để labels/ phản chiếu thư mục images/, sau đó tạo tệp dataset.yaml. Xem hướng dẫn từng bước để biết quy trình làm việc đầy đủ.
Link to this sectionTại sao quá trình huấn luyện YOLO hiển thị "No labels found" sau khi chuyển đổi COCO?#
Điều này xảy ra do convert_coco() lưu nhãn vào thư mục con bên trong save_dir/labels/ (ví dụ: save_dir/labels/train/) thay vì trực tiếp vào labels/train/ trong tập dữ liệu của bạn cùng với images/train/. YOLO mong đợi các nhãn nằm song song với hình ảnh — ví dụ, images/train/img.jpg cần có labels/train/img.txt. Di chuyển các nhãn đã chuyển đổi để khớp với cấu trúc này. Xem sửa cấu trúc thư mục.
Link to this sectioncls91to80 làm gì trong convert_coco()?#
Tham số cls91to80 kiểm soát cách các giá trị category_id của COCO được ánh xạ sang ID lớp YOLO. Khi là True (mặc định), nó áp dụng bảng tra cứu coco91_to_coco80_class() được thiết kế cho tập dữ liệu COCO tiêu chuẩn, vốn có 80 lớp với các ID không liên tục (1-90). Đối với các tập dữ liệu tùy chỉnh, hãy luôn đặt cls91to80=False — thao tác này sẽ chỉ đơn giản là trừ đi 1 từ mỗi category_id để tạo ra các ID lớp bắt đầu bằng 0.
Link to this sectionTôi có thể huấn luyện YOLO trực tiếp trên COCO JSON mà không cần chuyển đổi không?#
Không thể với quy trình huấn luyện YOLO hiện tại — các chú thích phải ở định dạng .txt của YOLO với một tệp cho mỗi ảnh. Sử dụng convert_coco() để chuyển đổi COCO JSON của bạn trước, sau đó làm theo hướng dẫn này để tổ chức và huấn luyện. Để biết thêm về các định dạng được hỗ trợ, hãy xem dataset formats.
Link to this sectionTôi có thể chuyển đổi chú thích segmentation của COCO sang định dạng YOLO không?#
Có, hãy sử dụng use_segments=True khi gọi convert_coco() để bao gồm các mask segmentation đa giác vào các nhãn YOLO đã chuyển đổi. Điều này tạo ra các tệp nhãn tương thích với YOLO segmentation models:
from ultralytics.data.converter import convert_coco
convert_coco(labels_dir="annotations/", save_dir="output/", use_segments=True, cls91to80=False)Link to this sectionLàm thế nào để chuyển đổi chú thích keypoint COCO sang định dạng YOLO?#
Sử dụng use_keypoints=True để chuyển đổi các chú thích keypoint COCO cho việc huấn luyện pose estimation:
from ultralytics.data.converter import convert_coco
convert_coco(labels_dir="annotations/", save_dir="output/", use_keypoints=True, cls91to80=False)Lưu ý rằng nếu cả use_segments và use_keypoints đều được đặt là True, chỉ các keypoint mới được ghi vào tệp nhãn — các segment sẽ bị bỏ qua một cách âm thầm.