はじめに
DDRの最高クリアがLv.17になりました。エアバスです。
突然ですが皆さんはアイドルマスターミリオンライブに登場する二人のアイドル、所恵美さんと高坂海美さんをご存知でしょうか?
ここではお二人の詳しい紹介は省略させていただきますが、ミリマス初心者あるあるの一つとして「所恵美と高坂海美、見分けつかないがち問題」があります。
参考リンク:
ミリオン歴5年目ぼく「いいかミリシタ新規P共!これが所恵美!これが高坂海美!最初は区別が付かんだろう!俺もそうだった!だがミリオンに触れてれば自然と区別が付くようになるからな!」
— 本幕🍦 (@motomaku) July 31, 2017
ミリシタ新ガシャ予告バナー見たぼく「次の水着ガシャはうみみかー」
ミリPなんてそれでいいんだよ… pic.twitter.com/7uf4YQRiy4
【ミリシタ】『所恵美』と『高坂海美』が初心者Pの難関!? : ミリシタまとめ雑談
かくいう私もミリオンをしっかり追っていないこともあり、かつてはお二人を混同してしまうことがありました。このペインをどうにかして解決できないものか…。
そんなときに目にしたのがこちらの記事でした。
TensorFlow を使ってブラックホールとポンデリングを見分ける (追記あり) - Qiita
こちらの記事ではTensorflowという”エンドツーエンドのオープンソース機械学習プラットフォーム” (公式サイトより) を使い、機械学習によりブラックホールとポンデリングの画像を判別しています。 (色々調べてみると過学習に陥ってるっぽいけど)
ブラックホールとポンデリングを見分けられるなら、海美と恵美[1]も見分けられるはず!ということで、今回は深層学習[2]を利用して、恵美と海美の顔を判別できる画像識別器を作ってみました。
学習データを集める
深層学習で画像認識器を作る上でまず必要なのが多くの学習データを集める事です。
まずはミリシタ・グリマスのカード画像を収集しましたが、海美・恵美のそれぞれで50枚弱しか存在しないため学習を行うには明らかに数が足りません。
アニメがあれば動画のフレームを画像化すればいいけどミリのアニメはまだだしな…
そこで私が思いついたのがPixivに投稿されたイラストを学習データに利用する方法です。有志によるPixivの非公式API「pixivpy」を利用し、タグ検索の結果から最低ブックマーク数を指定して投稿をDLしていくコードを書きました。
これでどうにかなりそうだ!と思っていたところにこんなアドバイスをもらいました。
TwitterにMV無限に転がってません?
— ひたらぎ★22.57 (@23k_h) September 4, 2019
確かに……
という訳でミリシタのゲーム内MVを学習データとして使いました。
具体的にはYouTubeにアップロードされている恵美と海美それぞれのソロバージョンのMVをダウンロードし、各フレームを画像化しました。(権利者、アップロード者各位に御礼申し上げます。)
顔を切り出す
今回は衣装や背景などの影響を無くすため、アイドルの顔だけをトリミングした画像を扱います。しかし大量の画像を手動でトリミングするのは非現実的です。
そこでOpenCVという画像処理用のオープンソースライブラリの物体認識機能と、@ultraistter 氏によるアニメ顔認識用の特徴量ファイル lbpcascade_animeface.xmlを使ってアイドルの顔の検出とトリミングを自動化しようと思います。
まずはOpenCVの環境構築をしたのですがこれがめちゃくちゃめんどくさい!
CUDA対応のOpenCVコンパイルするのめんどくさくて泣いてる
— aiгЬus (@airbus_P) September 4, 2019
公式のパッケージを使うのであればらくちんなのですが、今回CUDAを使うため自前でコンパイルしようとしたところ失敗が続き、最終的にPython版のOpenCVからはCUDAを使う事ができない事が判明し諦めてCPUで処理しました。
(流石にこのためだけにC++を学習する気にはなれませんでした)
てかPythonからCUDA使ってOpenCV走らせるバインディングは無いらしい
— aiгЬus (@airbus_P) September 6, 2019
うーん
環境構築が終わったのであとは書くだけです。コーディングは殆ど初心者なのでQiitaやその他ブログを回遊して得たスニペットからキメラを錬成します。
今回は標準入力で読み込むディレクトリを受け取ったり、処理時間計測したりしていますがその必要性はあんまり無さそうです。
1年次の必修科目だった情報(文科生用カリキュラム)の記憶を頼りに書いたコードでしたが、どうにか動きました。
さっきは拾ったコード使ってたんだけど、単一の画像から顔一つしか認識できないっぽかったのでコード書きなおした pic.twitter.com/OL4HcFOjeX
— aiгЬus (@airbus_P) September 6, 2019
注)この時素材にしていた動画に複数アングルからの映像をまとめたものがあり、一つの画像に複数の顔が写っている場合があった。
手作業で誤認識データを選別
大量の顔をトリミングした画像が手に入った訳ですが、上のツイートの画像のように顔と誤認識されているものが一定数存在するため、これらをデータセットから取り除く必要があります。
これも自動化したいところですが、さすがに無理そうだったので手作業で除外していきました。
主に除外対象となったのは
- 顔では無いものを顔と認識しているもの(特に背景に丸いものが浮かんでいると誤認されがち)
- 顔を切り取っているが、極端なアップなど顔全体を認識できていないもの
- イラストの背景にいる他のアイドルや人影
- 人間(私)から見て海美と恵美の判別がつかないもの(極端に明度の低いものなど)
です。
終わりに
こうして選別をした結果、二人合わせて約1万件の顔の画像データが集まりました。次回からはいよいよこれらを使って学習に入っていきます。自発的にプログラミングをするのは初めてでしたが、ライブラリも先行記事も大量にあって楽しくラクチンにできた感があります。
実は一通りの実験(?)は終わっているので全て一気に記事にしてもよかったのですが、なかなか記事を書くのが遅いため細かくステップごとに分けて投稿していく予定です。
追記: 学習結果も記事にしました
参照先
- OpenCVによるアニメ顔検出ならlbpcascade_animeface.xml - デー
- OpenCVでアニメの顔検出 - Qiita
- OpenCV 4.1 (最新版) をソースコードからビルドして,インストール(NVIDIA CUDA, cuDNN 対応で高速化可)(Windows 上)
脚注
[1] 突然呼び捨てになっていますが敬意は失っていません。
[2] ディープラーニングって何?って場合にはこの記事読むとなんとなく分かるかも…? ディープラーニングと機械学習の違い (Vol.5)