LoginSignup
2
4

More than 3 years have passed since last update.

Python で アノテーションJSONファイルを整形

Last updated at Posted at 2020-12-26

機械学習のデータセットのアノテーションのフォーマットはまちまちです。
望んだトレーニング用のフォーマットに変える方法をケーススタディでご紹介します。

ケーススタディ

個別ファイルのアノテーションを一つのファイルまとめ、ラベルマップを付与する

たとえば、JSONファイル一つにつき画像一枚の
・ラベル名
・ボックス
を書き込んであるアノテーションセットがあるとします。

train_000.json
{"labels": {"cat": [[1200, 700, 1800, 1300], [900, 1200, 1300, 1500], [12, 1100, 500, 1400]]}}

これを以下のように一つのファイルにまとめ、COCOデータセットのようにラベルID番号やファイル名もつけるコードがこちら。

train_annotations.json

{
   "categories": [
      {
         "id": 1,
         "name": "cat"
      },
      {
         "id": 2,
         "name": "dog"
      }
   ],
   "annotations": [
      {
         "filename": "train_000.jpg",
         "labels": [
            1,
            1,
            1,
         ],
         "label_texts": [
            "cat",
            "cat",
            "cat"
         ],
         "boxes": [
            [
               [
                  1200,
                  700,
                  1800,
                  1300
               ],
               [
                  900,
                  1200,
                  1300,
                  1500
               ],
               [
                  12,
                  1100,
                  500,
                  1400
               ]
            ]
         ]
      },
      {
         "filename": "train_001.jpg",
         "labels": [
            1,
            1,
            1,
            2,
            2,
            2,
            2,
         ],
         "label_texts": [
            "cat",
            "cat",
            "cat",
            "dog",
            "dog",
            "dog",
            "dog"
         ],
         "boxes": [
            [
               [
                  1800,
                  500,
                  3000,
                  1200
               ],
               [
                  1900,
                  1300,
                  2300,
                  1500
               ],
               [
                  1276,
                  761,
                  1816,
                  1285
               ],
               [
                  654,
                  982,
                  1273,
                  1572
               ]
            ],
            [
               [
                  1,
                  395,
                  1243,
                  853
               ],
               [
                  1,
                  955,
                  541,
                  1463
               ]
            ]
      },


}
import json #jsonの読み書き用ライブラリ
import os
from natsort import natsorted #ファイルのソート用
from collections import OrderedDict #順番を保った辞書を作る
import glob

json_dir = './train_annotations'

json_paths = natsorted(glob.glob(json_dir + '/*.json')) #jsonファイルたちの名前を保持

annotated_dicts = OrderedDict() #書き込み用の辞書
annotations_list = [] #書き込み用の辞書のアノテーション要素となるリスト

for json_path in json_paths: #jsonファイルたちから読み込んでいく
  if os.path.exists(json_path):
    with open(json_path, 'r') as f:
      df = json.load(f)
      filename = os.path.splitext(os.path.basename(json_path))[0] + '.jpg' #jsonファイルのファイル名(画像名に対応)を取得して画像名にする
      annotated_dict = OrderedDict() #個々の画像に対するアノテーションの辞書
      labels = [] #個々の画像に対するアノテーション要素の配列を作成
      label_texts = []
      boxes = []
      for key,value in df['labels'].items():
       for box in value:
          label_texts.append(key) #元ファイルのラベル名をラベル名の配列へ入れる
          boxes.append(box) #元ファイルのボックスをボックスの配列へ入れる

          if key == 'cat':
            labels.append(1) #catならID1をラベルIDの配列へ
          elif key == 'dog':
            labels.append(2) #dogならID2をラベルIDの配列へ

      #以下で、ここまで作った要素を個々の画像に対するアノテーションの辞書に入れていく
      annotated_dict['filename'] = filename
      annotated_dict['labels'] = labels
      annotated_dict['label_texts'] = label_texts
      annotated_dict['boxes'] = boxes
      annotations_list.append(annotated_dict)

annotated_dicts['categories'] = [{'id':1,'name':'cat'},
                                 {'id':2,'name':'dog'}
                                 ] #書き込み用の辞書のカテゴリー要素となるリスト

annotated_dicts['annotations'] = annotations_list #最後に、全ての画像のアノテーション辞書を書き込み用の辞書のアノテーション要素とする
with open('./edit_train_annotations.json', 'w') as f:
  json.dump(annotated_dicts, f, indent=3, ensure_ascii=False) #書き込み用の辞書をjsonファイルをとして書き込む。

🐣


フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

Twitter
Medium

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4