TensorFlow.jsを土台として作成されたml5.jsライブラリを利用すると、APIを通じてブラウザ上で機械学習のアルゴリズムとモデルを使うことができます。今回は顔のパーツを認識してその部分に別の画像を表示させます。顔を隠したいときに使えるかもしれません。

静止画と動画から顔のパーツを検出する

最初に静止画の顔検出をしてみることにします。

以下のコードはサーバー上でないとうまく動きません。

HTML部分

まずHTML部分を示します。

画像の読み込み

JavaScript部分を示します。

getFaceImageAsync関数は画像ファイルのパスを引数とし、image要素を返します。

faceAPIの呼び出し

faceAPIDetect関数はgetFaceImageAsync関数が返した要素を引数として、faceAPIを呼び出します。そしてその結果を返します。また処理に時間がかかるので「処理中」とかどこまで処理が完了したのかを表示させます。

検出結果の表示

faceAPIDetect関数が返したオブジェクトから各パーツの座標を抜き出すには以下のようにします。

getMeanOfX関数、getMeanOfY関数は座標の配列からX座標とY座標の平均値をそれぞれ取得します。

ページが読み込まれたらこれらの関数を用いて目と鼻と口がある座標を取得してそれらの中心に画像を表示させます。

動画から顔のパーツを検出する

動画としてカメラを使います。カメラの使用を許可するとカメラで撮影されたあなたの顔が表示されます。目がある部分には「目」と書かれた画像が表示されます。急に顔を動かすと画像も少しおくれてついていきます。

今回はml5.jsが提供している機能の中でも、体の部位の座標を取得してくれる poseNet を使います。カメラをつかった処理はp5.jsを使います。そのためml5以外に上の2行が必要です。

p5.jsのカメラをつかった描画

p5.jsでカメラをつかった描画は以下のようにおこないます。

setup関数とdraw関数は自動的に実行されます。最初にcreateCanvas関数でcanvasを生成し、loadImage関数で画像ファイルを読み込み、カメラで撮影されたものが描画できるようにしておきます。あとはdraw関数によって指定された位置に描画処理がおこなわれます。

loadImage関数はサーバー上でないとエラーが発生します。

HTML部分

カメラで撮影された画像から目を検出する処理を示します。

JavaScript部分

定数とグローバル変数を示します。両目のX座標とY座標を格納する変数には-100(見えない場所)を格納しておきます。

初期化の処理でml5.poseNet関数を呼び出し、引数に対象のVideo Element とロード後の処理を記述しています。poseNet.on(‘pose’, gotPoses);とすることで新しいポーズが検出されるたびにgotPoses関数が実行されます。

gotPoses関数では目が検出された場合はグローバル変数にその座標の値を格納しています。そうでない場合は-100を格納して「目」と書かれた画像が描画されない(実際には見えない位置に描画)ようにしています。

描画の処理ではカメラで撮影された画像と目が検出された座標に「目」と書かれた画像を表示させます。