1. Qiita
  2. 投稿
  3. RaspberryPi

Raspberry Pi 深層学習でリアルタイム顔認識(Keras・Open CV)

  • 7
    いいね
  • 0
    コメント

愛用のRaspberryPiが「赤りんご」と「青りんご」を見分けることができたので、同じ方法で「顔も見分けられるんじゃないだろうか?」と思い試してみました。

こんな感じ

2017-01-14 14_01_46.gif

まずは「サミュエル・L・ジャクソン(のフィギュア)」から。確率90%以上で本人と推測させてみました。

2017-01-14 14_02_58.gif

続いて「ジョン・トラボルタ(のフィギュア)」。同じく確率90%以上で本人と判定させています。

顔の切り出しはOpenCVで行いました。

環境

DSC_0070.JPG

あとは前々回と同じです。

学習の流れ

学習方法はリンゴを見分けさせた方法と同じです。

  1. Web上から画像をダウンロードし、OpenCVで顔を切り出す。
  2. 切り出した画像をNumPy配列にし、訓練データとテストデータに分ける
  3. 畳み込みニューラルネットワークで学習する
  4. OpenCVで切り出した顔の画像をNumPy配列にし推測データとして使用する

顔の切り出しにはOpenCVのカスケード分類器を利用しました。

1. Web上から画像をダウンロードし、OpenCVで顔を切り出す。

リンゴのスクレイピングでも利用させて頂きました、TomoProgの技術書さんのクローリングコードを利用しました。(ありがとうございます)

TomoProg/HatenaBlog/python/web_crawler.py - GitHub

OpenCVで顔を切り出すのは、長生村本郷Engineers'Blogさんのこちらのコード
をそのまま利用しました。(ありがとうございます)

kenzo0107/collect_face_samples.py - Gist

こちらはファイルを指定すれば自動で顔を切り出せるのですが、更に嬉しいことに反転画像や回転画像も自動的に出力することが出来ます。

Kerasのメソッドで画像の水増しをすることも出来るようなのですが、今回はこちらをそのまま利用させて頂きました。

travolta 2017-01-14 14-43-34.png

200枚ほどの顔画像をゲットしました。

最初「サミュエル・L・ジャクソン」「ジョン・トラボルタ」と私の3人で学習し、3人の分類は上手くいきましたが、サンプルが少なすぎて、顔画像であればなんでも99%と認識してしまいました。

madsen 2017-01-14 14-44-06.png

そこで学習用のラベルを増やしてみることにしました。「ブラック・スプロイテーションの女王」こと「パム・グリア」さんと、タランティーノの「レザボア・ドッグス」でミスターブロンドを演じた「マイケル・マドセン」の画像も合わせて抽出してみました。

私の認識精度を上げるために、昔似ていると言われたことのある俳優の三上博史さんの画像を一緒に抽出しました。

2. 切り出した画像をNumPy配列にし、訓練データとテストデータに分ける

リンゴと比べると顔の構造はちょっと複雑になるので、画像の大きさをどうしようか迷ったのですが、今回は32×32ピクセルのまま試してみました。

face_makedata.py - Gist

ラベルは「サミュエル・L・ジャクソン」「ジョン・トラボルタ」「私」「パム・グリア」「マイケル・マドセン」「三上博史」の6名で分けました。

3. 畳み込みニューラルネットワークで学習する

学習方法はラベルが増えたことを除きリンゴと一緒です。

face_keras.py - Gist

figure_1.png

figure_2.png

nb_epoc=30で学習させてみました。10エポック位で終了した方が良いのかもしれませんが、今回はこれで。

4. OpenCVで切り出した顔の画像をNumPy配列にし推測データとして使用する

リンゴの画像をデータ化する際は、キーボードsキー押下で写真を撮ったのですが、今回は認識したものをリアルタイムで表示させてみました。

iMacで実行した際は0.2秒間隔で画像認識させても比較的スムーズに表示されたのですが、RaspPiだと少し厳しいです。0.4秒間隔で画像認証をさせていますが結構遅延が起きてしまいます。

face_checker_cv_notalk.py - Gist

OpenCVはcv2.putText()というメソッドを使うと文字も画像に書き込めるようです。顔認識の正方形の上にKerasPredict()で推測したラベル名と推測の割合を画像に表示させて完成です。

まとめ

私の画像で試すとこんなレスポンスが返ってきます。

$ 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番目のラベルが「三上博史」さんです。

似てねえ。