みどりのあくま

勉強したことをアウトプットしていきます。

顔画像周りのデータを扱うアプリをelectron-vueで作ってみた

この前けものフレンズ解析機を作った際にdlibやtensorflowを利用したのですが、その時顔の位置に関した情報を扱うことが多かったです。
dlibだと顔の位置判別の学習に、tensorflowは学習データを作成する際に顔画像を切り出すのに使いました。

orange634.hatenablog.com

なので、後々のデータセットを準備する作業のことを考えて、そういった顔の位置の情報を上手く扱えるようなアプリがあると便利だろうなーと思い今回作成しました。

概要

f:id:orange634:20170908131738p:plain

起動した画面はこんな感じです。
「Load」ボタンから画像が入ってるフォルダを選択して、フォルダ内部画像データを取得します。
再帰的にファイルを取得しないのでフォルダ直下の画像のみ読み込まれます。

f:id:orange634:20170908131850p:plain

実際にロードしたらこんな感じになります。

f:id:orange634:20170908131943g:plain

各画像の上に四角の描画、ドラッグ、リサイズ、削除が行うことができ、複数の四角を描画することも可能です。

描画が完了したら「SAVE」ボタンを押して保存します。
保存しないでページを変えると描画したデータが消えてしまいます。

f:id:orange634:20170908132245p:plain

「Publish」ボタンを押すと、上の画像のように画面に書かれた正方形の位置(x, y)と大きさ(rectLength)のデータをdata.jsonとして選択したフォルダ内部に出力します。
また、ロードした際にディレクトリにdata.jsonがあった場合はそのデータを元に画像に正方形を描画します。 なので、何回でも調整可能ということです。
また、dlibで検出した顔の位置の情報をdata.jsonと同じ形式にすれば、そのデータも利用可能です。 (ただし画像に合わせて倍率を修正する必要があります)

f:id:orange634:20170908132228p:plain

mustacheというテンプレートエンジンを利用してtemplate.xmlからdata.xmlを出力できるようにしました。
出力される位置とうの情報は実際に画像に合わせて倍率をかけて四捨五入しています。

ただ、今回あくまで機械学習がメインであまり時間をかけるのは適切でないと判断して以下の部分で妥協しています。

  • 画像の横幅は1000px固定(実際の大きさに戻す時に倍率の計算が楽)
  • 縦長の画像は途切れて実質使えない(アニメの画像のみ使う想定なのでこれで横長画像しか使わない想定なので)
  • リサイズするのに右下一箇所でしか出来ない
  • vuexが上手く扱えず厳格モードではない

技術

今回アプリ作成に置いて、electron-vueを利用しました。
仕事で一度使ったことがあり、なんとなくですが知見があるからです。

vueではなくreactを使おうかと考えましたが、あくまで機械学習がメインでアプリ制作は手っ取り早く(それでも1ヶ月かかりましたが…)作ってしまいたかったので、経験のあるvueを採用しました。

四角の描画

顔を囲む四角はsvgを利用して記述しています。
svgを扱うのにライブラリは一切利用していません。
本当はsvg.jsを使いたかったのですが、vueと相性が悪いようで正しく動かなかったの(どうやらDOMを直接いじるのがvueだと上手く動かない)で諦めました。
正直正方形を記述するだけなので簡単だと思っていましたが、そんなことはなく苦労しました。

fabricを利用してのcanvasでの描画も考えたが、リサイズした時に大きさによっては四角にジャギが入るので、謎のこだわりでリサイズしても綺麗なsvgにしました。
正直canvasでよかったように思います…

またsvgはvueでhtmlのタグを扱うように扱えるので、vueの単一コンポーネントも使えます。

四角の描画部分はmouseup、mousedown、mousemove等と今は何を選択しているかで描画、ドラッグ、リサイズ等を行なっています。
正直コードは実験しながら行なっていたので、あまりよくありません。

ファイルの取得と画像の描画

nodeのfs(FileSystem)を利用しています。
画像はsvgのimageタグで表示させました。
file://<url>を使えるようんするためにelectronのwebPreferenceswebSecurityfalseにしています。
canvasで読み込んで表示させる方法も考えましたが、個人利用の範囲ならこの設定でも問題ないかなと思い、楽しています。

画像の切り出し方法

こちらはpythonのコードを利用する想定です。
nodeで画像を切り取ることは可能ですが、pythonのコードがすでにあるのでそちらを使ったほうが早いと思い切り出す機能はつけていません。
時間に余裕があればつけたいと思っています。
なので「画像を切り出しソフト」はあまり正しくないのですが、いいネーミングがないので暫定でこの名前にしています。

問題

正しくビルドされない

現在なぜかビルドが正しく出来ないでいます。原因は不明です。 ビルドは正しく終わるのですが起動してみると真っ白のままです。
mainWindow.openDevTools()を追記して、ビルドされたもののデバッグツールを確認すると、axiosというモジュールが見つかんないとエラーがでます。
これは素のelectron-vue(つまりvue init simulatedgreg/electron-vue applicationのテンプレートのままのこと)でも上手く行かないようです。
webpack等のフロントのビルドに関してはテンプレートを信じて使っており、あまり詳しくないので一旦諦めました。
原因がわかれば追記します。

Vuexの厳格モードでのデータの扱い

Vuexを利用してgetterで受け取ったarrayを変更すると(今回の場合は正方形の情報)Vuexの厳格モードだとエラーが発生します。
jsは普段あまりつかわないのでうまい解決策がわからず、今回は厳格モードオフで作成しました。
後ほどVuexのベストプラクティスを調べてここら辺に理解を深めたいと思っています。

感想

だらだらっと箇条書きで感想を書いていきます。

svgは初めて利用しましたがvue扱うのに全く問題はありませんでした。
ずっと昔から簡易イラレ版みたいなの欲しいけど、インクスケープ操作感が悪く使いづらかたので、時間がある時にsvgを利用して作れないかな考えています。(時間ないけど)

electron-veuは昔使った時よりさらにドキュメントやツール周りがさらに強化されているなーという印象でした。
vue周りの発展の速度がすごい早いので驚きです。

Vuexを利用する想定がある場合は早めに利用したほうがいいです。
中盤くらいまでVuexを使わないで作っており、いざVuexを使うことを考えると書き直しが発生して、余計に作業が増えてしまいました…

mustacheはシンプルが故に簡単な演算は無理みたいなので、作業的に必要になったら他のテンプレートエンジンの利用も考えてみます。 でも今はこれで問題ないです。

これできっと機械学習のデータセットを作るのが多少楽になるはず…!

追記

python製のラベリングをサポートするツールがありました… これ使った方がいいですね… github.com