Pynote

Python、機械学習、画像処理について

Deep Learing - MS COCO データセットの概要

MSCOCO データセット

MS COCO (Microsoft Common Object in Context) データセットは、Microsoft が提供しているアノテーション付きの画像のデータセットである。
以下のタスクの学習に利用できる。

  • 画像分類 (image classification)
  • 物体検出 (object detection)
  • セマンティックセグメンテーション (semantic segmentation)
  • インスタンスセグメンテーション (instance segmentation)
  • キャプション生成 (caption generation)
  • 姿勢推定 (pose estimation)

MS COCO データセットのダウンロード

こちら からダウンロードできる。

wget -q http://images.cocodataset.org/zips/train2017.zip
wget -q http://images.cocodataset.org/zips/val2017.zip
wget -q http://images.cocodataset.org/annotations/annotations_trainval2017.zip
unzip train2017.zip val2017.zip annotations_trainval2017.zip

ダウンロードして解凍すると、以下のディレクティブ構造になっている。

/data
├── train2017: 学習用の画像
├── val2017: バリデーション用の画像
└── annotations: アノテーションデータ
          ├── captions_train2017.json: キャプション生成用のアノテーション情報 (学習用)
          ├── captions_val2017.json: キャプション生成用のアノテーション情報 (バリデーション用)
          ├── instances_train2017.json: 物体検出、セグメンテーション用のアノテーション情報 (学習用)
          ├── instances_val2017.json: 物体検出、セグメンテーション用のアノテーション情報 (バリデーション用)
          ├── person_keypoints_train2017.json: 姿勢推定用のアノテーション情報 (学習用)
          └── person_keypoints_val2017.json: 姿勢推定用のアノテーション情報 (バリデーション用)

MSCOCO API をインストールする。

MSCOCO API は MSCOCO から提供されているデータセットアノテーション情報を取得するライブラリである。
アノテーションjson ファイルに記載されているため、json モジュールで読み込んで取得することもできるが、json ファイルは 500MB 程あるため、処理にかなり時間がかかる。
一方、MSCOCO API は Cython で高速化されているため、処理が高速に行えるメリットがある。

MSCOCO APIPython 版は以下でインストールできる。

# pycocotools のビルドに Cython が必要
pip install cython
pip install pycocotools

MSCOCO API の使い方

用語

  • カテゴリ: クラス名と同義。
  • カテゴリ ID: カテゴリに割り当てられた 1, 2, ... の整数値。
  • 上位カテゴリ: いくつかのカテゴリをまとめたカテゴリ。(例: vehicle は bicycle, car, track などの乗り物のカテゴリを配下にもつ上位カテゴリ)

COCO オブジェクトを作成する。

コンストラクタ引数にはアノテーション情報が記載された json のパスを指定する。

from pycocotools.coco import COCO

anno_path = "/data/annotations/instances_train2017.json"
coco = COCO(anno_path)

カテゴリ ID を取得する。

getCatIds で指定したカテゴリのカテゴリ ID が取得できる。

  • 引数
    • catNms: 指定したカテゴリに対応するカテゴリ ID を取得する。
    • supNms: 指定した上位カテゴリに属するカテゴリ ID を取得する。
# 指定したカテゴリに対応するカテゴリ ID を取得する。
print(coco.getCatIds(catNms=["dog", "cat"]))  # [17, 18]

# 指定した上位カテゴリに属するカテゴリ ID を取得する。
print(coco.getCatIds(supNms=["vehicle"]))  # [2, 3, 4, 5, 6, 7, 8, 9]

カテゴリの情報を取得する。

loadCats で指定したカテゴリ ID の情報を取得できる。

  • 引数
    • ids: カテゴリ ID
cats = coco.loadCats([1, 2, 3])
for cat in cats:
    print(cat)
# {'supercategory': 'person', 'id': 1, 'name': 'person'}
# {'supercategory': 'vehicle', 'id': 2, 'name': 'bicycle'}
# {'supercategory': 'vehicle', 'id': 3, 'name': 'car'}

画像 ID を取得する。

getImgIds で指定したカテゴリ ID の物体がすべて存在する画像 ID の一覧を取得する。
例えば、人と犬のカテゴリ ID を指定した場合、人と犬両方が存在する画像 ID の一覧を返す。

  • 引数
    • catIds: このカテゴリ ID がすべて存在する画像の ID 一覧を返す。
# カテゴリ ID の一覧を取得する。
cat_ids = coco.getCatIds(catNms=["person", "car", "dog"])

# 指定したカテゴリ ID の物体がすべて存在する画像の ID 一覧を取得する。
img_ids = coco.getImgIds(catIds=cat_ids)
print(img_ids)  # [338624, 424162, 407083, 67213, 421455, 395801, 151962, 139099, 324158]

画像の情報を取得する。

loadImgs で指定した画像 ID の情報を取得できる。

  • 引数
    • ids: 画像 ID
# 指定した画像 ID の情報を取得する。
imgs = coco.loadImgs(407083)

from pprint import pprint
pprint(imgs)
# [{'coco_url': 'http://images.cocodataset.org/val2017/000000407083.jpg',
#   'date_captured': '2013-11-17 13:57:37',
#   'file_name': '000000407083.jpg',
#   'flickr_url': 'http://farm5.staticflickr.com/4074/4879760560_c9db4b024a_z.jpg',
#   'height': 640,
#   'id': 407083,
#   'license': 3,
#   'width': 480}]

アノテーション ID を取得する。

getImgIds で指定条件に該当するアノテーション ID の一覧を取得する。

# 指定した 画像 ID に対応するアノテーション ID を取得する。
anno_ids = coco.getAnnIds(407083)
print(anno_ids)  # [4987, 195294, 2041260]

アノテーションの情報を取得する。

loadAnns で指定したアノテーション ID の情報を取得する。

# 指定した 画像 ID に対応するアノテーション ID を取得する。
anno_ids = coco.getAnnIds(407083)
print(anno_ids)  # [4987, 195294, 2041260]

annos = coco.loadAnns(anno_ids[0])
from pprint import pprint
pprint(annos)
# [{'area': 70246.92454999998,
#   'bbox': [5.18, 215.71, 405.51, 414.57],
#   'category_id': 18,
#   'id': 4987,
#   'image_id': 407083,
#   'iscrowd': 0,
#   'segmentation': [[304.45,
#                     259.76,
#                     200.81,
#                     328.42,
#                     130.85,
#                     377.65,
#                     71.26,
#                     456.68,
#                     25.91,
#                     537.0,
#                     12.96,
#                     599.19,
#                     5.18,
#                     627.69,
#                     143.81,
#                     630.28,
#                     200.81,
#                     627.69,
#                     221.54,
#                     525.34,
#                     252.63,
#                     473.52,
#                     294.09,
#                     441.13,
#                     340.73,
#                     345.26,
#                     373.12,
#                     331.01,
#                     383.48,
#                     347.85,
#                     399.03,
#                     337.49,
#                     397.73,
#                     329.72,
#                     410.69,
#                     327.13,
#                     408.1,
#                     308.99,
#                     395.14,
#                     297.33,
#                     382.19,
#                     258.46,
#                     375.71,
#                     250.69,
#                     364.05,
#                     215.71,
#                     343.32,
#                     242.91,
#                     334.25,
#                     233.85,
#                     325.18,
#                     217.0,
#                     304.45,
#                     248.1]]}]

アノテーションを可視化する。

showAnns でアノテーションを matplotlib の Axes 上に描画できる。
画像は別途自分で読み込んで、imshow() しておく必要がある。

img_id = 494089

# 指定した画像 ID に対応する画像の情報を取得する。
img_info, = coco.loadImgs(img_id)
img_path = Path("/data/train2017") / img_info["file_name"]
print(img_path)  # /data/train2017/000000494089.jpg

# 指定した 画像 ID に対応するアノテーション ID を取得する。
anno_ids = coco.getAnnIds(img_id)

# 指定したアノテーション ID に対応するアノテーションの情報を取得する。
annos = coco.loadAnns(anno_ids)

# 画像を読み込む。
img = plt.imread(img_path)

# 画像を描画する。
plt.imshow(img)

# アノテーション結果を描画する。
coco.showAnns(annos)