愛用のRaspberryPiが「赤りんご」と「青りんご」を見分けることができたので、同じ方法で「顔も見分けられるんじゃないだろうか?」と思い試してみました。
こんな感じ
まずは「サミュエル・L・ジャクソン(のフィギュア)」から。確率90%以上で本人と判定させてみました。
続いて「ジョン・トラボルタ(のフィギュア)」。同じく確率90%以上で本人と判定させています。
顔の切り出しはOpenCVで行いました。
環境
- パルプ・フィクション/ サミュエル・L・ジャクソン ジュールス・ウィンフィールド 13インチ トーキングフィギュア
- パルプ・フィクション/ ジョン・トラボルタ ビンセント・ベガ 13インチ トーキングフィギュア
あとは前々回と同じです。
学習の流れ
学習方法はリンゴを見分けさせた方法と同じです。
- Web上から画像をダウンロードし、OpenCVで顔を切り出す。
- 切り出した画像を
NumPy
配列にし、訓練データとテストデータに分ける - 畳み込みニューラルネットワークで学習する
- OpenCVで切り出した顔の画像を
NumPy
配列にし推測データとして使用する
顔の切り出しにはOpenCVのカスケード分類器を利用しました。
1. Web上から画像をダウンロードし、OpenCVで顔を切り出す。
リンゴのスクレイピングでも利用させて頂きました、TomoProgの技術書さんのクローリングコードを利用しました。(ありがとうございます)
TomoProg/HatenaBlog/python/web_crawler.py - GitHub
OpenCVで顔を切り出すのは、長生村本郷Engineers'Blogさんのこちらのコードをそのまま利用しました。(ありがとうございます)
kenzo0107/collect_face_samples.py - Gist
こちらはファイルを指定すれば自動で顔を切り出せるのですが、更に嬉しいことに反転画像や回転画像も自動的に出力することが出来ます。
Keras
のメソッドで画像の水増しをすることも出来るようなのですが、今回はこちらをそのまま利用させて頂きました。
200枚ほどの顔画像をゲットしました。
最初「サミュエル・L・ジャクソン」「ジョン・トラボルタ」と私の3人で学習し、3人の分類は上手くいきましたが、サンプルが少なすぎて、顔画像であればなんでも99%と認識してしまいました。
そこで学習用のラベルを増やしてみることにしました。「ブラック・スプロイテーションの女王」こと「パム・グリア」さんと、タランティーノの「レザボア・ドッグス」でミスターブロンドを演じた「マイケル・マドセン」の画像も合わせて抽出してみました。
私の認識精度を上げるために、昔似ていると言われたことのある俳優の三上博史さんの画像を一緒に抽出しました。
2. 切り出した画像をNumPy
配列にし、訓練データとテストデータに分ける
リンゴと比べると顔の構造はちょっと複雑になるので、画像の大きさをどうしようか迷ったのですが、今回は32×32ピクセルのまま試してみました。
ラベルは「サミュエル・L・ジャクソン」「ジョン・トラボルタ」「私」「パム・グリア」「マイケル・マドセン」「三上博史」の6名で分けました。
3. 畳み込みニューラルネットワークで学習する
学習方法はラベルが増えたことを除きリンゴと一緒です。
nb_epoc=30
で学習させてみました。10エポック位で終了した方が良いのかもしれませんが、今回はこれで。
4. OpenCVで切り出した顔の画像をNumPy
配列にし推測データとして使用する
リンゴの画像をデータ化する際は、キーボードsキー押下で写真を撮ったのですが、今回は認識したものをリアルタイムで表示させてみました。
iMacで実行した際は0.2秒間隔で画像認識させても比較的スムーズに表示されたのですが、RaspPiだと少し厳しいです。0.4秒間隔で画像認証をさせていますが結構遅延が起きてしまいます。
face_checker_cv_notalk.py - Gist
OpenCVはcv2.putText()
というメソッドを使うと文字も画像に書き込めるようです。顔認識の正方形の上にKeras
のPredict()
で推測したラベル名と推測の割合を画像に表示させて完成です。
まとめ
私の画像で試すとこんなレスポンスが返ってきます。
$ python3 face_checker_cv_notalk2.py
Using TensorFlow backend.
[[ 7.23991604e-08 1.06343272e-07 9.99999404e-01 1.25359421e-07
1.08549557e-07 1.90402147e-07]]
PonDad
3番目が私のラベル、6番目のラベルが「三上博史」さんです。
似てねえ。