OpenCVでリアルタイム顔認識してFaceAPIで年齢とか取得する
10月27、28日に大学で学園祭がありました。
私が所属するサークルでは毎年何かしら作って展示するのが伝統となりつつあります。
1年生のときはHSPで簡単な連打ゲームと、画面が白くなった瞬間にボタンを押して反応速度を競うようなゲームの二つを作りました。
どちらもとても単純なゲームではありますが、予想以上に人気で多くの人に遊んでもらうことができました。
2年生のときはかつてjavaの講義で作った「2048」というゲームをHSPでリメイクしました。1年の頃に作ったゲームと比べるとはるかに難易度が上がりましたが、このときも結構多くの方に遊んで頂けました。
ランキングを見てみると70人分ぐらいのスコアが残っていました。数字だけ見ると少ないように見えなくもないですが、1人あたりの平均プレイ時間が5分ぐらいであることを考えるとわりと繁盛していたほうなのではないでしょうか。
そして3年の学園祭。
今年もゲームを作ろうとも考えましたが、学園祭が近づいてきても全く作る気が起きませんでした。
そこで以前から手を付けていたFacaAPIを使って何か作ろうと考えました。それで思いついたのがこのブログのタイトルのものです。
さて、前置きはこれぐらいにしてどのように実装したのか紹介します。
用意したもの
- RasberryPi 3 modelB
- Webカメラ(BSWHD06MBK)
- キーボード
- マウス
実装
学園祭で使った説明資料です。
手順は以下の通り。
①OpenCVでリアルタイム顔認識して、顔を認識したら顔に赤枠を描画
②赤枠が表示されている間にエンターキーを押させる
③画像をバイナリでFaceAPIに送信
④結果をJSONで取得
⑤JSONをもとに年齢や性別を描画
⑥画像を表示
OpenCVでリアルタイム顔認識
この部分はてきとうにggって上らへんに出てきたものをほぼそのまま実装しました。
ラズパイにUSBでwebカメラを接続するとうまく動くのですが、ノートPCの内臓カメラを使おうとするとうまく動きません。仮想環境だと内臓カメラをうまく認識できないのでしょうか。ノートPCにUSBのwebカメラを接続しても動かなかったような気がします。
メインはFaceAPIなので、正直OpenCVで顔認識する必要は無いのですが、APIの無駄打ちを少なくするために使っています。
OpenCVでの顔認識は一切お金がかかりませんし、OpenCVで認識できていればFaceAPIではほぼ間違いなく認識できるので。
FaceAPIで顔認識した結果を取得
上述の理由でお客さんには赤枠が表示されている間にエンターキーを押してもらうようにします。
エンターキーを押すと、押した瞬間のカメラの画像を保存してFaceAPIにバイナリで送り付けます。このときにFaceAPIで取得する情報を指定します。今回は性別、年齢、笑顔度を取得しました。(途中、ハゲ度を取得するようにしたりして仲間内で盛り上がっていたりしてました。)
そして、返ってきたJSONから頑張って顔の座標を抜き出し、その座標をもとに年齢や性別を描画する場所を決めます。ちなみに一度に認識できる顔の数は実質無制限です。
また、視覚的に分かりやすくするためにif文で文字の色を男性の場合は青色、女性の場合は赤色で描画するようにしています。
最後に画像を保存して表示すれば完成です。
色々描画するとこんな感じ。
この写真を撮ったときの私は20歳なので、まぁ許容範囲内といったところでしょうか。少しだけニコッとしたつもりでしたがFaceAPI的には真顔だったようです。少し悔しい。
でも、目とかグラサンで隠れてるのにこの精度ってすごくないですか?
以下ソースコードです。
学園祭の2日間を通して合計で300人近い方に楽しんで頂くことができました。
大学のwifiでAzureにアクセスしようとしたところ、どうやらファイアウォールで弾かれているようで自分のスマホでテザリングする羽目になりました。約700MB。
感想
過去に自分で作ったものを組み合わせただけなので主要な部分は2、3時間で作り終わりました。たぶん今までで一番手抜きです。
学園祭中はちょくちょくお客さんの反応を伺ったりしていたのですが、精度がどうも微妙な感じなようでした。親子で撮って母と娘がどちらも19歳なんてことがわりとあるようで、「ハッ、この程度か」みたいな反応をしている方が少なくないような気がしました。
事前の検証では大体±5歳ぐらい収まっていたので結構自信があったのですが、やはり本番環境になるとそううまくはいかないようです。
もっとも、こういった顔認識なんていうのは顔の角度や明るさなどで結構変わってくるので精度が悪くなるのは当然といえば当然なのですが。展示してたのも外ですし。
まぁ、半分以上の方はそんなに大きくは外していなかったようなので良しとします。
今年の学園祭は後輩の1年生達にとても感謝しています。
後輩達にはこれといった説明なんて全然していなかったのに、たまたま興味を持って話かけていただいた一般の方に私が説明していたことを要約して、私が居ない間に解説してくれてました。
途中ラズパイへの電力供給が不安定になって再起動するなんてことがあったのですが、私が気付かない間に自分達でプログラムを起動し直してくれてました。
どのファイルを実行すればいいかとか全く教えて無かったのにすごいです。たぶんそこらへんにいる私と同じ学科の3年生なんかよりよっぽど力があります。
本当にありがとう。助かりました。
そういえばFaceAPIで顔認証システムを作るなんて言っていた時期がありました。アレ、私が導入したい環境では実装が難しいことが判明してしまい、モチベーションが上がらなくて完全に後回し状態です。今後やるかどうかも正直微妙です。
なんというか、撮影場所がどうやっても逆光になってしまうので顔が真っ黒になって認識できないんですよね。カメラ側に人感センサー付きのライトを設置するとかで解決できはするんですけど、如何せん私の財布は厳しい状況にあるので...
というわけで、学園祭でFaceAPIを使って顔認識した話でした。