ディープラーニングを使ってドラゴンボールZのスカウターっぽいのを作ってみた(Python, Chainer, dlib, PyQt)

ディープラーニングを使用して、ドラゴンボールZの「スカウター(っぽいもの)」を作ってみたので紹介します。

今回作成を試みたのは、ドラゴンボールZで相手の戦闘力を測定する装置「スカウター」です。

ですが、かなり頑張っても、「戦闘力を測定する方法」が実現できなかったです。

そこで戦闘力を測定する機能はあきらめて、画像を読み込み、キャラをディープラーニングで識別することにしました。

キャラを特定した後に、顔の横に名前と戦闘力を出力する、擬似的なスカウターです。

名づけて「ディープラーニング・スカウター」(試作機1号)です。

本当はスマートグラスに実装までしたかったですが、大変すぎるので、デスクトップ・アプリケーションを作成しました。

作成したアプリケーションの機能や使用の様子、作成方法のガイドを以下の動画にまとめました。

3分ほどの動画となっており、音が出ます。

まずはこちらをごらんください。

動画

ディープラーニング・スカウターの作り方

ディープラーニング・スカウターは次の5つの手順で作成しました。

①画像データを収集

②ドラゴンボール専用の顔認識プログラムを作成

③ディープラーニングでキャラの顔の特徴量を学習

④デスクトップ・アプリケーションのデザインを作成

⑤GUIを制御するプログラムをコーディング

①画像データを収集

今回はYoutubeに公開されている公式チャネルの動画からスクリーンキャプチャしました。

【公式】ドラゴンボール改 第1話「闘いの幕開け! 帰ってきたぞ孫悟空」

※Youtube見れなくなってたのでGYAOの無料版

【公式】ドラゴンボール改 第1話「闘いの幕開け! 帰ってきたぞ孫悟空」

この話は、サイヤ人編の第一話でラディッツ(悟空の兄)が地球にやってくるという内容です。

今回は「悟空」、「クリリン」、「ラディッツ」の3人を識別することにし、この3キャラの画像をスクリーンショットで保存しまくりました。

Ubuntusのデフォルトのスクリーンショットは確認画面が面倒なので、Shutterなどのスクリーンショットをインストールして使う方が良いです。

Shutterの使う場合はキーボードショートカットに割り当てておくと便利です。

Shutter解説参考サイト

とはいえ、1話だけなので、各キャラにつき学習画像が23枚、テスト画像を5枚用意するのがやっとでした(あきらかに少ない・・・)。

テスト画像は、学習画像と極力似ていないものを、主観的に選びました。

②ドラゴンボール専用の顔認識プログラムを作成

Pythonのdlibライブラリを使用して、ドラゴンボールの顔を識別するプログラムを作成します。

デジカメの顔検出と同じです。

ですが人の顔検出プログラムそのままでは、ドラゴンボールの顔は判別できなかったので別途作成しました。

このあたりは以下の記事を参考にしました。

[参考:dlibでマンガの顔認識をやってみた]

まずdlibを導入します(なんか変な感じですが、Interface2017.8.の記事の手順です)。

apt-get upgradeと、最後のdlibのインストールには時間がかかります。

dlibで進まなくなったと思っても、当分ほっといてください。

さらに、dlibの学習用のGUIを導入します。

DBpro→DBFaceTest→trainingというフォルダを作成し、学習用の画像を10枚ずつほど合計30枚ほど用意します(キャラは全部使用して同一の顔検出を作成する)。

trainingフォルダの階層で以下を実行します。

すると画像が出てくるので、Shiftキーを押しながら、顔を囲います。

全ファイル分、顔を囲ってFile-Saveします。

すると、training.xmlの中身が生成されます。

同様にtest分も作成します。

DBpro→DBFaceTest→testで

生成された二つのxmlファイルと全画像をDBpro→DBFaceTest→detectorCreateフォルダに入れ、training_object_detector.pyを実行します。

※コードは全て別記事にまとめました。

以上の操作で、検出用SVM設定ファイルである、detector.svmが生成されます。

このファイルを使うことで、ある程度ドラゴンボールの顔を検出できます。

※今回は学習に使う枚数が少なかったので、70%ちょっとの精度です・・・

新たにface_detector.pyを作成し、detector.svm、それからチェックしたい画像を入れたフォルダを用意します。

そして、

と実行すると、画像の切り出し具合がチェックできます。

テスト画像でもうまく切り出せています。

また、学習にいっさい使っていないフリーザの顔もきちんと検出できています。

③ディープラーニングでキャラの顔の特徴量を学習させる

次にディープラーニングのライブラリであるChainerを使用して、顔画像の識別器を作成します。

顔画像が入力されたら、[悟空、クリリン、ラディッツ]のどれなのかを識別させます。

このあたりはInterface 2017.8号の記事と添付プログラムを参考にしました。

今回は、コンボリューションしてMaxプーリングする操作を3回してから1層のニューラルネットワークで識別するCNN(Convolution Neural Network)を組んで使用しました。

ニューラルネットワーク1層なので、ディープラーニングなのか・・・って気はします。

ですが、コンボリューションする層も学習する必要があるので、conv3層とneuron1層なので、ディープラーニングと言えます。

ただ、そこまでディープではないですが・・・

学習データがあまりに少ないので、今回はこれでいきます。

まずは学習データから顔を切り出した画像を生成します。

DBproにCroppingFace_anime.pyと、さきほど生成したdetecor.svmを置き、

gazou_DB→Gokuh

gazou_DB→Klilyn

gazou_DB→Raditz

の3つのフォルダにそれぞれ、ディープラーニングに使用する学習データの画像を配置します。

また顔を切り出した出力先としてcroppedDBFaceフォルダを作成しておきます。
そして、

を実行すると、切り出された顔ファイルが生成されます。

続いて、CNNで学習します。

まず、chainerをインストールし、python train_face.pyを作成して、deeplearningで学習します。

50回くらい学習させると良い感じに収束したので、この結果を使用します。

ニューラルネットワークの構造を可視化したいときには、以下のコマンドで画像ファイルができます。

できあがったCNNで識別する際には、eval_face.pyを作成し、ターミナルで次のような感じで実行します。

※学習したモデルがFaceEmotionなのは、参考にしたプログラムから変え忘れていました。

すると、以下のような出力がされ、うまく判別されています。

ですが、CUIのターミナルの結果だけでは面白くないので、続いてGUIを作成してデスクトップ・アプリケーションにします。

(Webアプリにしたかったですが、そこまでの気力はなかったです・・・)

④デスクトップ・アプリケーションのデザインを作成

PythonでGUIをつくるにはTkInterやPyQt、wxPythonがありますが、今回はPyQtを使用しました。

「QtDesigner」を同時に使用すると簡単に開発ができます。

以下のサイトを参考にしました。

[参考:PyQt(PySide)で画像処理その1(GUIの作成)]

まずPyQtとGUI開発ツールQtDesignerをインストールします。

そして、画面を作成します。

今回は、テキスト出力用のQLineEDIT、ボタン2つ(ファイル選択、スカウター)、画像を出力するQGraphicViewからなるシンプルな画面です。

できた画面ファイルをPythonファイルに変換します。

最後にGUIのコンポーネント(各ボタンやView)に対応するプログラムをコーディングします。

⑤GUIを制御するプログラムをコーディング

全体を制御するmain.pyと、ディープラーニングを実行するscouter.pyを用意します。

※動画では3つだったのですが、面倒なので2つにしました。

少しでもスカウターっぽくするために、ボタンのpressedアクションで全体的に薄く緑を表示させ、ボタンreleasedアクションでディープラーニングを実行し、識別と描画をしています。

※コンポーネントのアクションからメインに返ると画像描画が反映されるので

以上で、完成です。

上記、コマンドでGUIアプリケーションが立ち上がります。

Fileボタンをクリックして画像を選択し、スカウターのボタンを押すと顔を検出し、ディープラーニングでキャラを特定して、顔の下に名前と戦闘力を表示してくれます。

まとめ

雑な点や、コードが汚くて残念な感じはありますが、「ディープラーニング・スカウター」の試作機としては十分に働いてくれました。

テスト結果は次の通りです。

・悟空(5枚中3枚で顔検出OK、3枚すべて識別OK)

・クリリン(5枚中2枚で顔検出OK、2枚すべて識別OK)

・ラディッツ(5枚中3枚で顔検出OK、3枚すべて識別OK)

学習に使える画像が少なすぎて、顔検出がうまくいっていないです。

識別はうまくいっていますが、1話のなかだと同じような顔が多くて微妙なところです。

このあたりの問題は、学習データを増やし、ディープラーニングも、もっとでかい回路を使えば解決できます。

今後の発展としては、

①新入社員の顔写真を学習

②スマートグラスに搭載

③リアルタイムに判別し、新入社員の名前と戦闘力が表示される

そんなスカウター(ARスマートグラス)を作成したいと考えています。

いつやるか分かりませんが・・・

(サルの固体識別で似たようなことやろうとしてる阪大の研究もあるし・・・)

今回のディープラーニング・スカウターを作るうえで大変だったのは次の4点です。

①ドラクエXIをやりたい誘惑

②Youtubeやドラゴンボールばっか見てて、嫁に自主勉強中だと理解されない

③ラディッツのつづり調べてたら、ラディッツの小ネタが楽しくて、ドラゴンボールの豆知識ばかり増えて、手が止まる

④バーダック(悟空の父親)の声も野沢雅子さんが演じていて、野沢さんが親子三代全部(バーダック、悟空、悟飯、悟天)の声優をしていることに驚く。

親子三代ってドラクエ5かよ!って思いながらやっぱり、ドラクエXIをやりたい誘惑・・・

以上、長い記事にお読みいただき、ありがとうございました。

コードは別記事にまとめて置いています。

汚いので参考程度に、使用してください。