クソアプリ2 Advent Calendar 2019の18日目の記事です。
誰でもマジシャンになれるDeepMagicを開発しました。
Qiitaアドベントカレンダー用のクソアプリ「Deep Magic」が完成しました。手で囲った物体を消すことができます。 pic.twitter.com/mrX2d8Azi6
— shinmura0 | 2/15発表者募集中 (@shinmura0) December 8, 2019
#概要
上記の動画でも紹介しているように、指で囲った物体を消すことができます。
ただし、モニター越しで物体を消しているため、種も仕掛けもありまくる
しょうもないマジックです。コンセントとモニターが必要なため、忘年会にも
持っていけませんし、活躍する場が皆無です。
活躍する場が無い...まさしくクソアプリです。
#構成
本アプリは、異なるディープラーニングモデルを3種類使っています。
以下の3ステップで構成されています。
- 1ステップ:handtrackingで手を検出
- 2ステップ:MobileNet V2で手の形を分類
- 3ステップ:Partial Convolutionsで物体を消す
##1ステップ目
handtrackingは以前にも紹介していますが、普通のPC(GPUなし)でも高速に
手の検出ができる優れものです。Githubからクローンしてくるだけで、簡単に使えます。
(動画はGithubより)
jetson Nanoで動かすとマルチスレッドで11FPS、シングルスレッドで8FPSの速度が
出ます。(TensorRTにすると、もっと速くなるはずです。)
Qiitaのアドベントカレンダーに向け、クソアプリを開発中...。まずは、handtrackingをJetson Nanoで動かしてみました。
— shinmura0 | 2/15発表者募集中 (@shinmura0) November 9, 2019
生のTesorFlowでもほぼ10FPSで動くので感動!TensorRTになるともっと速くなるのかな?https://t.co/SQIQPbBvPL pic.twitter.com/LoGGR9lyD0
ただし、こちらでも書いたように色々モデルがあり、精度が劇的に変わるため
注意が必要です。
産業用用途では、こちらにあるような使い方もできます。
##2ステップ目
MobileNet V2では、handtrackingで検出してきた手の画像を渡し、手の形を
分類しています。
Qiita用 pic.twitter.com/8bsOO16VJH
— shinmura0 | 2/15発表者募集中 (@shinmura0) December 10, 2019
2ステップ目では、以下のように手の形を3種類に分類するタスクを行っています。
「ポインター」を認識すると、赤い枠が出てきて物体を消失させる範囲を決めることができます。
「グー」を認識すると、3ステップ目に移行します。「その他」では、特に何もしません。
(本当は、handtacking内で折角SSDが使われているので、手の形の違いで
データを用意して学習させれば、MobileNet V2は不要になります。
それによって、シンプルかつ高速に処理することができますが、
アノテーションに時間がかかるため、今回は諦めました。)
###学習の条件など
- 画像のサイズ:96×96
- 最適化手法:SGD
- エポック:400
- 転移学習を使っています。
用意した画像の枚数は以下のとおりです。
枚数 | |
---|---|
ポインター | 112 |
グー | 51 |
その他 | 175 |
学習させる際は、PCACAを使って500枚に増幅しています。
ちなみに、精度はvalidation、testのデータで共に70%くらい。
MobileNet V2を使って速度を優先させているため、いくらか精度を犠牲にしています。
ただし、予測確率に閾値を設けることで自信がない予測値は全て「その他」に
分類しました。これにより精度が80%ほどになりました。
##3ステップ目
Partial Convolutions(PCs)は、マスクした部分を綺麗に復元することが可能です。
PCsには事前に屋内の画像を与え、ランダムにマスクされた画像を復元させる学習を
しておきます。これにより、PCsではマスクされた部分を自然な画像に復元できる
ようになります。
そして、実行の際には、「ポインター」の範囲(赤い枠)でマスクした画像を
PCsに入力し復元させます。その結果、復元させた画像では、赤い枠内が自然な
感じになり、あたかも、枠内にあった物体が消えたようになる仕組みです。
学習の要件は以下のとおりです。
- 学習用の画像はSUNRGB-D(屋内の画像10,000枚以上)を使用。
- エポックは30(1000イタレーション/1エポック)。Colabの学習で34時間かかった。
ちなみに、PCsを異常検知に使うと異常部分の可視化ができます。
#実行結果
##レベル1
消す範囲は、小さければ小さいほど自然な画像になって帰ってきます。
まずは、小さいマグネットを消します。
Qiita用 pic.twitter.com/2hEVut29Vo
— shinmura0 | 2/15発表者募集中 (@shinmura0) December 10, 2019
##レベル2
冒頭にお見せした動画です。レベル1に比べ、消す範囲が大きくなっていますが、
周りの背景が単純なので、割と良い結果が得られます。
Qiitaアドベントカレンダー用のクソアプリ「Deep Magic」が完成しました。手で囲った物体を消すことができます。 pic.twitter.com/mrX2d8Azi6
— shinmura0 | 2/15発表者募集中 (@shinmura0) December 8, 2019
##レベル3
最後は将棋の駒を消します。消す範囲は小さいですが、周りの背景が複雑なので
ちょっと自信がありませんでした。
Qiita用 pic.twitter.com/c0OPVrMOGc
— shinmura0 | 2/15発表者募集中 (@shinmura0) December 10, 2019
動画をよく見ると、将棋盤の線も一部再現されています。
何とか頑張っています。
#使い方
##ハード
- Jetson Nano
- USBカメラ
##ソフト
- Keras2.2.5
- OpenCV
- TensorFlow
##手順
基本的にGithubに上げたもので実行可能なのですが、Partial Convolutionsの
モデルは、容量が40MBもあるためアップすることができませんでした。
そのため、このモデルだけ欠落しています。
このモデルはメール(shinmura_0@yahoo.co.jp)をいただければ、送信できます。
(40MBでもアップできる方法があれば教えてください)
また、こちらを参考に自分で学習することも可能です。
アプリの使い方は以下のとおりです。
- こちらから実行ファイルをダウンロードしてください。
- main.pyを実行してください。
カメラ画像が表示されたら、以下のとおりに実行してください。
- 「S」ボタンを押すと、実行開始です。
- 右手の人差し指を立てて(爪を上に向けるのがポイントです)、消したい物体を囲ってください。
- その後、手のひらをカメラ側に見せた状態で「グー」にすると囲った物体を消すことができます。
- 消す範囲が小さければ小さいほど、精巧な復元画像を得ることができます。
- 消す範囲をリセットする場合は、「R」ボタンを押してください。その後、「S」ボタンを押し実行開始です。
#実行時間
2ステップ目までだと全体で6FPSくらい出ますが、3ステップ目に移行すると
1FPSくらいになります。各処理単体の実行時間は以下のとおりです。
内容 | 実行時間(msec) | |
---|---|---|
1ステップ目 | handtracking | 120 |
2ステップ目 | MobileNet V2 | 50 |
3ステップ目 | Partial Convolutions | 500 |
#クソアプリから抜け出すために
このアプリの欠点は、マジックのくせに電源とモニターが必要なことです。
スマートではありません。カッコよくありません。
でも、一番のネックはモニターが固定されていることなのです。
モニターを見ながら遊んでいると首が痛くなります。
これは、周りにあるものを消そうとして、気が付くと首が120度に曲がっている
ためです。(↓こんなイメージ。)
じゃあ、移動式モニターがあれば良いわけです。
移動式モニター、移動式モニター...
スマホでやれば良いじゃん!と思ったあなた、鋭いです。
スマホでも手の検出が高速にできます。
(動画はGithubより)
指の座標も得られるので、さらに高精度の判別ができると思います。
ただ、この後3ステップ目(Partial Convolutions)を動かすと、激遅になると思われるので
スマホ計画は頓挫。。。やっぱり、モニターは固定。クソアプリから抜け出せない。
結論:「クソアプリでもいいじゃない。」