この記事は?
物体検出に用いられるアノテーションを作成する labelImg の mac OS での使い方を解説した記事です。特に、アノテーション対象のオブジェクトの位置とクラスが事前にざっくりわかっていてそれを補正したいという場合の使い方を解説しています。
labelImg とは?
labelImg では以下のようなことができます。
- 物体検出のためのアノテーション (bbox, class) を無料で作成できる
- 商用利用可能 (MIT LICENSE)
- 事前に作成した (擬似) アノテーションを読み込んで GUI 上で補正できる
特に、3 が他のアノテーションツールにはない強みで、適当に事前学習したモデルでそれっぽい仮の bbox を作成できるとアノテーション作業がかなり楽になります。例えば、人物インスタンスにアノテーションをつけたい時には COCO や CrowdHuman などで学習したモデルの confidence を思いっきり下げてとりあえずの bbox を作成するとゼロベースで bbox の矩形を描くよりずっと高速にアノテーションができます。
準備
環境構築
まずはリポジトリをクローンします。
git clone git@github.com:tzutalin/labelImg.git
cd labelImg
20220616時点での mac での推奨は pipenv を使うやり方です1。python3 や pipenv が既にインストールされてる場合は対応する箇所は適宜スキップして良いです。
brew install python3
pip3 install pipenv
pipenv run pip install pyqt5==5.15.2 lxml
pipenv run make qt5py3
バグの修正
20220616現在の labelImg の master ブランチにはバグがありそのまま使うとエラーを吐かれて GUI が停止します。そこでバグに当たる箇所である libs/labelDialog.py
の74行目を以下のように修正します。QPoint
の引数の型を float から int に変換するだけです。
(before fix): offset += QPoint(btn.size().width()/4, btn.size().height()/2)
(after fix): offset += QPoint(int(btn.size().width()/4), int(btn.size().height()/2))
使い方
ラベルの設定
bbox のアノテーションを始める前にクラスラベルを定義する必要があります。GUI で作成した bbox にここで定義したラベルの中から選んでクラスを付与することになるためです。
クラスラベルは data/predefined_classes.txt
の中で定義します。data/predefined_classes.txt
は1行に1つのクラスラベルが記された構成になっています。例えば、ヒト、トカゲ、カエルにアノテーションをつけたい場合は以下のようにファイルを構成します。data/predefined_classes.txt
の中身は日本語で書いても英語で書いても大丈夫です。
ヒト
トカゲ
カエル
(optional) 擬似ラベルを作成してアノテーションを補助する場合
擬似ラベルを作成する場合、以下のようなフォルダ構成を作成します。
data
┣ 00000001.jpg
┣ 00000001.txt
┣ 00000002.jpg
┣ 00000002.txt
...
┗ classes.txt
ここで、*.jpg
はアノテーションをつける画像2、*.txt
は同じ名称の画像に対応する擬似アノテーション、classes.txt
は擬似アノテーションに利用されたクラスラベルを定義したファイルです。
擬似ラベルの作成
擬似ラベルを作成できる場合には作成したほうが確実にアノテーションコストを削減できます。小規模であってもアノテーションをつけるオブジェクトのクラスを含むデータセットがあれば、そこで finetune したモデルを使って擬似ラベルを付与することをお勧めします。
擬似ラベルは以下のようなテキストファイルとして作成する必要があります。いわゆる YOLO 型のアノテーションと言われているやつで、class center-x center-y width height
でオブジェクトを表現します。ここで class
は int 型、 center-x
center-y
width
height
は全て画像のサイズで正規化された float で値のレンジは [0, 1]
です。例えば、画像中央に bbox の中心があり、幅と高さがそれぞれ画像の幅と高さの1/10、クラスが0であるオブジェクトは以下のように表現されます。
0 0.5 0.5 0.1 0.1
同一画像の中に複数のオブジェクトがあるときは同様に改行してオブジェクトを定義します。1行当たり1インスタンスになるようにしてください。
0 0.5 0.5 0.1 0.1
1 0.25 0.75 0.2 0.3
2 0.75 0.25 0.1 0.2
また、擬似ラベルのファイル名は suffix を除いて画像の名称と一致する必要があります。つまり、00000001.jpg
という画像に擬似ラベルをつけるときは 00000001.txt
という名称で擬似ラベルを作成する必要があります。
classes.txt
の作成
擬似ラベルを作成した場合、擬似ラベルで定義したクラス (int) に対応する str 型のクラスを定義したファイルを用意する必要があります。ファイルの構成は data/predefined_classes.txt
と同様です。擬似ラベルを作成する際に利用したモデルのラベルをそのまま使えば良いと思います。
GUI の起動とアノテーション
labelImg.py
を動かすと GUI を起動できます。
pipenv run python3 labelImg.py
GUI さえ起動すればアノテーション作業自体は割と直感的にできます。日本語にも対応しているので特に迷うことはないと思います。
tips
- アノテーションフォーマットは YOLO (たぶんデフォルト) を選択する
-
表示
→自動で保存する
を選択するとアノテーションを保存する際に出てくる確認のポップアップを排除できるのでアノテーション速度が改善します- このオプションをつけない場合
command + s
で保存できます
- このオプションをつけない場合
-
a
で前の画像、d
で次の画像に移動します。自動で保存する
オプションをつけている場合は移動した瞬間にアノテーションが保存されます -
w
で新しい矩形を作成します -
command + +
で拡大、command + -
で縮小- 個人的に使い勝手はあんまり良くないです
- 擬似ラベルを作成するときは class-agnostic な NMS をかけて矩形の数を絞ると楽になる気がします
- pytorch (torchvision) の場合は
batched_nms
の代わりにnms
を使う感じです。
- pytorch (torchvision) の場合は
- 動画のアノテーションを行う場合は
command + v
で直線のフレームのアノテーションをコピーできるのでインスタンス数が変わらないときはアノテーションを楽できる時があります