CVATでバウンディングボックスをアノテーションしてみる

2021.07.16

データアナリティクス事業本部の鈴木です。

教師あり学習で画像の物体認識を行う際には、一般的には以下の情報が必要になります。

  • 画像
  • アノテーションデータ(どこになんの物体が写っているかなど)

公開されているデータセットでは、アノテーションデータがすでに準備されていることも多いですが、新しい問題に取り組む際には、基本的には自分でアノテーションを付ける必要があります。

今回は画像にアノテーションデータとしてバウンディングボックスを付けるために、Computer Vision Annotation Tool (以降、CVAT)を調べたのでご紹介します。

CVATとは

インテルで開発されている、コンピュータビジョンアルゴリズム用のラベリングツールです。

MITライセンスで配布されており、ソースコードはGitHubで公開されています。

ウェブベースのツールで、Dockerでサーバーを起動し、Google Chromeからアクセスして利用できます。

GitHubレポジトリは以下です。

openvinotoolkit/cvat: Powerful and efficient Computer Vision Annotation Tool (CVAT)

使ってみる

ダウンロード・起動

公式のインストールガイドにしたがってインストールしました。

前提としてDockerおよびGoogle Chromeがインストールされている必要があります。

今回は自分のPC上でコンテナを起動し、自分のPCのブラウザでアクセスしました。

Installation Guide | CVAT

私はMac OSを使っているのでMac OS Mojaveの箇所を参考に進めました。

まず、GitHubレポジトリをCloneしました。

git clone https://github.com/opencv/cvat

レポジトリのルートに移動し、docker-composeでCVATを起動しました。このとき、初回は大きめのコンテナイメージをいくつかダウンロードするので、ご注意ください。

# レポジトリのルートに移動
cd cvat

# サーバーの起動
docker-compose up

別のコンソールを立ち上げ、下記コマンドでスーパーユーザーを作成しました。ユーザー名・パスワード、メールアドレスを聞かれるので、入力しました。

docker exec -it cvat bash -ic 'python3 ~/manage.py createsuperuser'

スーパーユーザーが作成できたら、Google Chromeを起動し、localhost:8080にアクセスしました。

ログインページが表示されます。先ほど作成したユーザーでログインしました。

CVATログイン画面

ログインできるとホーム画面に移ります。

CVTAホーム画面

作業を行うためには、プロジェクトとタスクを作成する必要があります。

今回アノテーションしたい画像

今回はスマホに眠っていた、いつぞやに美味しくいただいたコリンキーと銀杏の写真にアノテーションをつけることにしました。

コリンキー

Ginkgo

コリンキーはかぼちゃの一種なのでsquash、銀杏はginkgoでラベル付します。

ちなみに、コリンキーの英語名を調べたところ、"Colinky Squash"と出てきたのでラベルもsquashとしました。あれ、pumpkinじゃないの?と思ったのですが、諸説あるようですが、皮がオレンジ色の種類がpumpkinで、ほかはsquashと呼ぶことが多いようです。知らなかった。

プロジェクトの作成

アノテーションをするため、プロジェクトとタスクを作成します。

まず、プロジェクトを作成します。ホーム画面でCreate new projectを押します。

Create a new project画面が表示されるので、NameLabelsを入力します。 CVATプロジェクトの作成

LabelsAdd Labelをクリックすると以下のようになるので、とりあえずLabel nameを入力してDoneを押します。

Label作成

設定が入力できたら、Submitボタンを押します。

プロジェクト作成

これで、プロジェクトが作成できました。

タスクの作成

続いて、各プロジェクトのCreate new taskを押して、タスクを作成します。

Create a new task画面で、Nameを入力し、Projectを選択します。アノテーションを付けたい画像をSelect filesにドラッグ&ドロップします。

タスク作成

また、よく見るとLabelsが"Project labels will be used"になっており、先ほどプロジェクトで作成したラベルがアノテーションに使えるラベルであることが分かります。

問題なければSubmitを押します。

アノテーションの実施

タスクの作成ができたので、アノテーションデータを作成します。

タスクからJobのリンクをクリックします。

jobのリンクをクリックする

このように、作業用のUIが表示されます。今回はバウンディングボックスを作成したいので、その操作に絞って説明します。

作業UI

サイドバーからDraw new rectangleを選びます。このときに、LabelとDrawing methodを選べます。コリンキーなので、Labelはsquash、Drawing methodはとりあえずBy 2 Points(長方形の対頂点を選ぶ)にしておきます。

DrawNewRectangle

対頂点を選んでバウンディングボックスを作成します。

アノテーション完了

画像が複数ある場合は、上部のバーから画像を変更できます。

画像の変更

銀杏にもアノテーションを付けてみます。後からアノテーションデータの出力を見たいので、殻がない銀杏はsquashにしておきました。

銀杏のアノテーション

作業が終わったらSaveを押しておきます。

結果の出力

アノテーション結果を出力します。

Menu > Export as a datasetで出力したい形式を選択します。 アノテーションデータを出力

見て分かる通り、多岐にわたる形式をサポートしています。今回はPASCAL VOC1.1形式をクリックします。

程なく、zipがダウンロードされます。

zipを解凍すると、以下の構成のデータセットが得られます。特にAnnotationsディレクトリに入っているxmlファイルがアノテーションデータです。元の画像はJPEGImagesに入っていました。

.
├── Annotations
│   ├── ColinkySquash.xml
│   └── Ginkgo.xml
├── ImageSets
│   ├── Action
│   │   └── default.txt
│   ├── Layout
│   │   └── default.txt
│   ├── Main
│   │   ├── background_default.txt
│   │   ├── default.txt
│   │   ├── ginlgo_default.txt
│   │   └── squash_default.txt
│   └── Segmentation
│       └── default.txt
├── JPEGImages
│   ├── ColinkySquash.jpg
│   └── Ginkgo.JPG
└── labelmap.txt

xmlの中身も確認してみます。

Ginkgo.xml

<annotation>
  <folder></folder>
  <filename>Ginkgo.JPG</filename>
  <source>
    <database>Unknown</database>
    <annotation>Unknown</annotation>
    <image>Unknown</image>
  </source>
  <size>
    <width>1088</width>
    <height>816</height>
    <depth></depth>
  </size>
  <segmented>0</segmented>
  <object>
    <name>squash</name>
    <occluded>0</occluded>
    <bndbox>
      <xmin>513.44</xmin>
      <ymin>341.66</ymin>
      <xmax>679.1</xmax>
      <ymax>469.73</ymax>
    </bndbox>
  </object>
  <object>
    <name>ginlgo</name>
    <occluded>0</occluded>
    <bndbox>
      <xmin>722.58</xmin>
      <ymin>250.01</ymin>
      <xmax>869.44</xmax>
      <ymax>427.43</ymax>
    </bndbox>
  </object>
  <object>
    <name>ginlgo</name>
    <occluded>0</occluded>
    <bndbox>
      <xmin>640.33</xmin>
      <ymin>387.48</ymin>
      <xmax>827.15</xmax>
      <ymax>588.4</ymax>
    </bndbox>
  </object>
  <object>
    <name>ginlgo</name>
    <occluded>0</occluded>
    <bndbox>
      <xmin>585.11</xmin>
      <ymin>205.37</ymin>
      <xmax>750.77</xmax>
      <ymax>360.46</ymax>
    </bndbox>
  </object>
  <object>
    <name>ginlgo</name>
    <occluded>0</occluded>
    <bndbox>
      <xmin>263.17</xmin>
      <ymin>215.94</ymin>
      <xmax>418.26</xmax>
      <ymax>395.71</ymax>
    </bndbox>
  </object>
  <object>
    <name>ginlgo</name>
    <occluded>0</occluded>
    <bndbox>
      <xmin>433.54</xmin>
      <ymin>157.19</ymin>
      <xmax>594.51</xmax>
      <ymax>295.84</ymax>
    </bndbox>
  </object>
</annotation>

期待した値が入っていることが確認できました。

感想

今回は一人で使う前提で、最低限の使い方の紹介をしました。

実際にアノテーションのプロジェクトを実施するときは、アノテーションの仕方の取り決めやタスク割り振りなど、ツールに期待することがたくさんあると思います。

より詳細にCVATを知っていくことで、そのような用途にも余裕で応えてくれる実力を感じます。

GitHubではScreencastsから、各種使い方の動画を見ることも可能です。併せてご参照ください。