matplotlibだけでアノテーターを作る

はじめに

たまに,特定のタスクのために変なアノテーターを作りたいときがある. 慣れているので,pythonでやりたい. これまでこういうときは,opencvを使って作っていたが,最近,matplotlibを使っても同じようなことができると知ったので,調べて使ってみる.

公式ドキュメントをeventを受け取る関数を作って,それを fig.canvas.mpl_connect という関数で登録することでマウスやキーボードのイベントを取得できるらしい. 以下ではよくある感じのアノテーターを作って,どんな感じでできるかを確認する.

画像にラベルをつける

  • ←→が押されたら前の画像,次の画像を表示する.
  • キーが押されたら,押されたキーを記録して次の画像へ移動
  • qが押されたら結果をpickleに保存して終了

矩形選択

  • ←→が押されたら前の画像,次の画像を表示する.
  • ドラッグで領域選択して座標を取得
  • 選択中は四角を表示する
  • cを押したら前回の結果をキャンセルする
  • qが押されたら結果をpickleに保存して終了
  • keyのイベント,マウス押し込み,マウスドラッグ,マウスリリースのそれぞれのイベントを検出する関数を作って登録する.
  • 想像よりだいぶ長くなってしまってイマイチ

f:id:ksknw:20200810231441p:plain

特定の物体が写ってる画像を選択

  • クリックされたら,クリックされた画像のインデックスを保存して,別の画像を表示する.
  • 人間性を証明するためにたまにやらされるやつ
  • マウスイベントではevent.inaxesとして,axisのオブジェクトが返ってくる.subplotの番号がほしいときは,self.plot_axes.index(event.inaxes)とかやると番号を取得できる.

まとめ

  • matplotlibを使ってアノテーターを作ってみた.
  • いくつかやってみた感じ,opencvを覚えてるなら,opencvで作るのと対して手間は変わらないかなという印象(subplot使えるぶんだけ有用かも).
  • plt.drawを使うと若干ラグが生じるときがあって,plt.pause()で適当に短い時間を指定したほうが軽快だった.
  • ここに書いたようなものだったら何でもできそうだけど,matplotlibの機能を使ったアノテーター(scatterの点の位置をドラッグして補正するとか)するときは便利かもしれない.公式ドキュメントにはbarプロットのバーをドラッグして動かすデモが載っている.

参考

Event handling and picking — Matplotlib 3.1.2 documentation