徘徊 会いに行こう 叱られる時間になる前に
(ニガミ17才/町の変態)
こういう歌詞を書ける、幼心をいつまでも持ち続けているかのようなセンスに痺れるし憧れます。
さて、前回までにPythonとOpenCVを使った顔認識のサンプル的なものを書きました。
が、いかんせん Python
が必要だったりとか python xxx
とかうたなきゃならなかったりでサクッと遊べる感じではありません。
できればこういったものはブラウザ上でサクッと試してみたいものです。
そこで調べてみると、jsでも顔認識が出来るぞ!!という情報がオドロくほどあるではないですか。知らんかった。
そんなわけで試しにサンプルを作ってみました。
※ といっても、jsでイチから顔認識を実装するのではなくライブラリを利用します
※ ついでに利用したライブラリの比較表も載せています
PCだとWebカメラ必須ですが、スマホでも見れます。
利用したライブラリ
ググると目立っていたのが以下2つのライブラリでしたので、これらを利用します。
- auduno/clmtrackr: Javascript library for precise tracking of facial features via Constrained Local Models
- tehnokv/picojs: A face detection library in 200 lines of JavaScript
OpenCV.js も検討したのですがビルドがめんどくさいのとファイルサイズが巨大すぎた(6MB)ので断念しました。
※ また機会があればチャレンジしてみます
それと、justadudewhohacks/face-api.js: JavaScript API for face detection and face recognition in the browser with tensorflow.js もあるみたいですね。これも次の機会に。
作ったサンプル
作ったサンプルは以下になります。
いずれのサンプルも、
- 顔認識
- 認識された顔部分を別canvasで表示
- スマホ対応
iOS11.4/Safari
で動作確認済み
- フロント、リアカメラの切り替え
- スマホのみ
- PC(WEBカメラ)でやるとエラー
- グレースケール変換
- デバッグ機能
- 顔認識部分のマージン調整
といった機能を持っています。
getUserMedia API をサポートしているブラウザであれば動くと思います。
Can I use… Support tables for HTML5, CSS3, etc
注意点
ただし、
- 電池の消耗ハンパない
- スマホで見る場合、熱をかなり持つ
- 冬に使うとカイロ代わりになるかも
といった注意が必要です。
clmtrackr.jsを利用したもの
ソース
shimabox/face_recognition_with_clmtrackr: Sample of face recognition with clmtrackr.js
デモ
Face recognition with clmtrackr.js
特徴
- 精度が結構いい
- 顔をある程度傾けても大丈夫っぽい
- ファイルサイズがかなりデカい
- minでも約1.9MB
- 一人のみしか認識しない
- 複数人写っていた場合、いちばん認識結果がよいものが選ばれているっぽい
pico.jsを利用したもの
ソース
shimabox/face_recognition_with_pico: Sample of face recognition with pico.js
デモ
特徴
- 精度が悪いといえば悪い
- 顔を少し傾けただけでOUT
- ファイルサイズが小さい
- minで約2.2KB
- 若干カクつく
- 複数人の認識可能
比較表
上記にあるとおり、特徴が一長一短だったので気になった部分をまとめてみました。
clmtrackr.js | pico.js | 備考 | |
---|---|---|---|
精度 | ○ | △ | pico.jsは少し顔を傾けただけで認識されない |
認識人数 | △ | ○ | clmtrackr.jsは一人のみ/pico.jsは複数人可能 |
ファイルサイズ | × (1.9MB) | ◎ (2.2KB) | 一度の読み込みと割り切れればそこまで懸念することではないかも |
FPS※ | ○ | × | どっちがカクつくかといえばpico.js |
※ FPSは自分の書き方も影響していると思うのでなんともいえないですけども
ファイルサイズが結構気になるところではありますが、顔を認識する精度を考えると個人的にはclmtrackrがベターかと思います。
ファイルサイズが大きいのもモデルを一緒に含んでいるっぽいので、そこは致し方ないかなと。
pico.jsも、対象があまり動かないのであれば十分実用的かと思います。
マージンのとり方(clmtrackr.js)
clmtrackr.jsにおいて顔認識された部分に対して、マージンをとるのに苦戦したのでどう対応したのかを書いておきます。
以下は、顔の長さを5等分した高さのマージンを上部に2つ、下部に1つ取る例になります。
1. 顔の矩形部分を取得する
clmtrackrは顔の特徴点(目,鼻,口,輪郭など)を座標で返してくれます。
※ README にも載っていますが、こんな感じです
これを利用して顔の矩形部分(座標)を特定します。
矩形部分の座標取得にあたっては、
【画像処理】HTML5+JavaScriptでリアルタイムに顔認識して顔を隠してみた – 備忘録
の記事を参考にさせていただきました。
この部分の ソースはこんな感じ です。
2. 顔の長さを分割する
顔の長さを適当に分割(ここでは5等分)し、その一つの枠の高さをマージンの基準となる値(scaleと呼ぶ)とします。
3. 上部にマージンをとる
- で得たscale2つ分のマージンを上部に取ります。
ctx.drawImage()
のsyの値をマイナスするイメージです。上に2つ分ずらす感じ。
見て分かるとおり、上に2つずれているので下部に1つ分マージンを取りたい場合は、下部に3つ分のマージンが必要になることがわかります。
4. 下部にマージンをとる
- のとおり、3つ分のマージンを下部に取ります。
ctx.drawImage()
のshの値をプラスするイメージです。下に3つ分ずらす感じ。
横のマージンも同じロジックです。
デバッグ機能をオンにすれば動きがわかりやすいと思います。
おわりに
jsで顔認識できるということを知って時代はかなり進んでいるなと感動しました。
(自分が取り残されていた感があるけど)
サンプルもゴロゴロ転がっているし、これできるかもと思ったものは、やる気があれば程度はどうであれ大体作れるのでは?という気がしてしまいます。
今回のサンプルも利用の仕方によっては幅が広がる(※)だろうし、なんというかもはや夢見る少年になれます。
(※ 顔部分の抜き出しには成功しているのだから顔部分が描画されるタイミングを監視しておけば、サーバーにPOST → 保存/解析 とか)
凡人でも巨人たちが作ってくれたものを組み合わせれば、夢が見れる。
というわけで、jsで顔認識するサンプルを作った話は以上となります。
サンプルを作るにあたって参考にさせていただいた記事
- MediaTrackConstraints.facingMode – Web APIs | MDN
- Capabilities, constraints, and settings – Web APIs | MDN
- HTML5 Canvas Grayscale Image Colors Tutorial
- 【画像処理】HTML5+JavaScriptでリアルタイムに顔認識して顔を隠してみた – 備忘録
- querySelectorAllしてmapしたいとき[…すると短い – hitode909の日記
- レンジ入力欄(スライダー)の現在値を表示する方法
- html の input type=”range” を css でカッコつけてみた
clmtrackr.js を使ってこんなものも書いてみました
clmtrackr.jsで顔認識してへのへのもへじを描画する | Shimabox Blog
clmtrackr.jsで返ってきた顔座標に対して “へのへのもへじ” を描画しただけのものになります。