はじめに
COCO形式のアノテーションファイルをYOLO形式に変換する必要が生じた際に少し躓いてしまったので、最終的に上手くいったコードを備忘録として残しておきます。(YOLOv8にて動作確認済)
なお、COCO形式とYOLO形式の違いとして重要な部分が以下の2点になり、これらに注意をしながらコードを作成しております。
- バウンディングボックスの座標の取り方
- 画像1枚に複数のアノテーションがある場合のアノテーションのやり方
変換コード
以下のコードを用いることで、COCO形式のアノテーションファイルをYOLO形式に変換するここができます。
import os
import json
# パスの設定
coco_json_path = '変換したいjsonファイルのパス'
yolo_txt_save_dir = 'YOLO形式のtxtファイルを出力したい場所'
# JSONファイルの読み込み
with open(coco_json_path, 'r') as json_file:
json_load = json.load(json_file)
annotations = json_load['annotations']
images = json_load['images']
# 画像IDとファイル名の対応辞書を作成
image_id_to_file_name = {image['id']: image for image in images}
# 各アノテーションに対して処理
for annotation in annotations:
image_info = image_id_to_file_name[annotation['image_id']]
file_name = image_info['file_name']
im_w = image_info['width']
im_h = image_info['height']
# テキストファイルのパスを作成
txt_path = os.path.join(yolo_txt_save_dir, os.path.splitext(os.path.basename(file_name))[0] + '.txt')
# バウンディングボックスの座標を変換
bbox = annotation['bbox']
x_center = bbox[0] + bbox[2] / 2
y_center = bbox[1] + bbox[3] / 2
bbox_converted = [x_center / im_w, y_center / im_h, bbox[2] / im_w, bbox[3] / im_h]
# カテゴリーIDを取得
cls = int(annotation['category_id'])
# 書き込む行を作成
line = (cls, *bbox_converted)
# テキストファイルに追記モードで書き込み
with open(txt_path, 'a') as f:
f.write(('%g ' * len(line)).rstrip() % line + '\n')
この記事は以下の情報を参考にして執筆しました。