Python で COCO dataset API を使う

Python により COCO dataset API を使う方法の紹介

Python により COCO dataset API を使う方法の紹介
 ikath
 2019-07-26

COCO dataset とは

COCO datasetは物体検出やセマンティックセグメンテーション、キャプション(画像の説明文)がされているデータセットで、 他のデータセットと比べて豊富なアノテーションが提供されているのが特徴です。 COCO datasetを取得するためには、PythonやMatLabからCOCO APIを使用する必要があります。

COCO API

  1. cocodataset/cocoapi: COCO API

このパッケージは、Python、MatLab、Lua APIで提供されており、アノテーションのロード、構文解析、視覚化をサポートしてくれます。 この記事では、Python + ipython notebookからCOCO APIを使ってみます。

環境構築

リポジトリのクローン

まずは、COCO APIを使うためにcocoリポジトリをクローンします。

git clone https://github.com/pdollar/coco
cd ./coco/PythonAPI
make

アノテーションファイルの取得

次に、画像ファイルとアノテーションが書かれているjsonファイルを取得します。 画像ファイルに関しては今回 validation data 2017 (5000枚)だけを使います。 学習する方は Train data 2017 (枚数不明)もダウンロードしてください。

cd ..
wget http://images.cocodataset.org/zips/val2017.zip
unzip ./val2017.zip
wget http://images.cocodataset.org/annotations/annotations_trainval2017.zip
unzip ./annotations_trainval2017.zip
# train data 2017 をダウンロードするなら以下のコマンドを実行する
#wget http://images.cocodataset.org/zips/train2017.zip

COCO dataset では80種類のデータセットが公開されています。 実際に COCO Explorer で画像の検索もできます。

person bicycle car motorcycle airplane bus train truck boat traffic light fire hydrant stop
sign parking meter bench bird cat dog horse sheep cow elephant bear zebra giraffe backpack
umbrella handbag tie suitcase frisbee skis snowboard sports ball kite baseball bat baseball
glove skateboard surfboard tennis racket bottle wine glass cup fork knife spoon bowl banana
apple sandwich orange broccoli carrot hot dog pizza donut cake chair couch potted plant bed
dining table toilet tv laptop mouse remote keyboard cell phone microwave oven toaster sink
refrigerator book clock vase scissors teddy bear hair drier toothbrush

この中からクラスを選択して class.txt を作ります。 今回は自転車と車とバイクを選択します。

classes.txt
text
bicycle
car
motorcycle

YOLOに対応したアノテーションを取得する

PythonAPI に移動してJupyter notebookを起動します。使用するプログラムは PythonAPI に置いてください。

cd PythonAPI
jupyter notebook

必要なモジュールのインポートをします。インポートエラーは各々対応してください。

ln [1]:
python
from pycocotools.coco import COCO
import matplotlib.pyplot as plt
import numpy as np
import skimage.io as io
import pylab
import os
import shutil

pylab.rcParams['figure.figsize'] = (8.0, 10.0)

画像とアノテーションが書かれたファイルを読み込むための準備です。 アノテーションを置いたディレクトリを指定します。

ln [2]:
python
dataDir='..'
dataType='val2017'
annFile='{}/annotations/instances_{}.json'.format(dataDir,dataType)

COCO APIの初期化をします。

ln [3]:
python
coco=COCO(annFile)

ここでそれぞれの画像に対するアノテーションを取得します。 YOLOで使うバウンディングボックスの座標情報は、COCO datasetで提供されているのと異なるためYOLO用に変換しています。 このセルを実行し終えると、datasetというディレクトリがcocoディレクトリの下に生成され、そこにアノテーションを記したテキストファイルが生成されます。 テキストファイル名は拡張子を除き、画像ファイリと同じです。 また、test.list というファイルも生成され、validationとして使う画像がリストされています。

実行後
./coco
└── dataset
     ├── 000000005001.txt
     ├── 000000007386.txt
     ├── 000000008211.txt
     ├── ...
     └── test.list
ln [4]:
python
class_txt = '../classes.txt'
save_dir = '../dataset/'

if not os.path.isdir(save_dir):
    os.makedirs(save_dir)

dataset_dir = os.path.abspath('..') + '/dataset/'

with open(class_txt, 'r') as f:
    classes = f.readlines()

error_files = []

for i in range(0, len(classes)):
#for i in range(0, 1):
    class_name = classes[i].split('\n')[0]
    catIds = coco.getCatIds(catNms=[class_name]);
    imgIds = coco.getImgIds(catIds=catIds );
    print("Number of data of" + ' ' + class_name + ': ' + str(len(imgIds)))

    for j in range(0, len(imgIds)):
        img = coco.loadImgs(imgIds[j])[0]
        #print(img['file_name'])
        annIds = coco.getAnnIds(imgIds=img['id'], catIds=catIds, iscrowd=None)
        anns = coco.loadAnns(annIds)
        try:
            I = io.imread(img['coco_url'])
        except KeyboardInterrupt:
            sys.exit
        except:
            error_files.append(img['file_name'])
            continue

        for k in range(0, len(anns)):
            x = (anns[k]['bbox'][0] + (anns[k]['bbox'][2]/2)) / I.shape[1]
            y = (anns[k]['bbox'][1] + (anns[k]['bbox'][3]/2)) / I.shape[0]
            w =  anns[k]['bbox'][2] / I.shape[1]
            h =   anns[k]['bbox'][3] / I.shape[0]
            with open(save_dir + img['file_name'].split('.')[0] + '.txt', 'a') as f:
                f.write(str(i) + ' ' + str(x) + ' ' + str(y) \
                                       + ' ' + str(w) + ' ' + str(h) + '\n')

        with open('../dataset/test.list', 'a') as f:
                f.write(dataset_dir + img['file_name'] + '\n')

if len(error_files) != 0:
    print("Error occures when files read")
    print("File: " + error_files)

print('All complete.')

最後に使う画像を dataset ディレクトリに移動させます。

ln [5]:
python
# Move applicable data to dataset dir
from_dir = '../val2017/'
to_dir = save_dir
for i in range(0, len(classes)):
#for i in range(0, 1):
    class_name = classes[i].split('\n')[0]
    catIds = coco.getCatIds(catNms=[class_name]);
    imgIds = coco.getImgIds(catIds=catIds );
    for j in range(0, len(imgIds)):
        img = coco.loadImgs(imgIds[j])[0]
        if os.path.exists(from_dir + img['file_name']):
            #shutil.copy(from_dir + img['file_name'], to_dir)
            shutil.move(from_dir + img['file_name'], to_dir)

License

COCO dataset は Creative Commons Attribution 4.0 License で公開されています。

  1. Terms of Use - COCO (Common Objects in Context)
  2. クリエイティブ・コモンズ (Creative Commons) - 表示 4.0 国際 - CC BY 4.0

この記事のアイキャッチ画像で利用しているアイコンは COCO Consortium のものです。



 公開日時: 2019-06-07
 タグ: deep-learning  python 
ikath icon image
 ikath

名前は ikath と言います。情報系の大学生です。

 Twitter
サイト内検索

Google カスタム検索を利用してサイト内の記事をキーワードで検索できます。

サイト内検索

Google カスタム検索を利用してサイト内の記事をキーワードで検索できます。