Javascriptで顔を追跡してみる

こんにちは。えんどうです。

新参者ですが、ブログ連投していきます。

第9回社内勉強会でお話したJavascript用の顔追跡ライブラリclmtrackrについて書いていきたいと思います!

687474703a2f2f617564756e6f2e6769746875622e636f6d2f636c6d747261636b722f6d656469612f636c6d747261636b725f30332e6a7067

clmtrackrのアルゴリズムはC++ライブラリのFaceTrackerと同じものを採用しています。
これにについて詳しく知りたい方は、わかりやすく説明してくださっている方がいるので、そちらを参考にしてください!

参考
FaceTrackerの論文を読んでみた:”Deformable Model Fitting by Regularized Landmark Mean-Shift”

では、clmtrackrの具体的な使い方に入っていきたいと思います!

clmtrackrの中で使われる主なクラスは以下の二つです。

  • clm.tracker…顔の追跡をするクラス
  • faceDeformer…画像と頂点を渡してマスクの表示、変形をしてくれるクラス

 ということで、まずはclm.trackerで顔の追跡をしたいと思います!

顔の検出

まずはclm.trackerをインスタンス化します。
次にinit()で初期化をしますが、ここで渡すpModelは/models/model_pca_20_svm.jsで定義されています。
また、ctrack.start()の引数は顔検出をしたいvideoのエレメントです。

var ctrack = new clm.tracker();
ctrack.init(pModel);
var vid = document.getElementById('videoel');
vid.play();
ctrack.start(vid);

あとはgetCurrentPosition()で頂点を取得するだけ!

var positions = ctrack.getCurrentPosition();

もし取得した頂点を描画したかったらこんな感じです。
ちなみにctrack.draw()の引数は描画したいcanvasのエレメントです!

var overlay = document.getElementById('overlay');
drawGridLoop();
function drawGridLoop() {
	overlayCC.clearRect(0, 0, 500, 375);
	if (positions) {
		ctrack.draw(overlay);
	}
	requestAnimFrame(drawGridLoop);
}

こんな感じで表示できます。
この時の、頂点と画像を保存しておくと、画像からマスクを生成して変形することもできます!

face1

続いて、マスクの変形と表示についてです!

マスクの変形、表示

こちらもまずはfaceDeformerの初期化からです。
fd.init()の第一引数は、マスクの描画用canvasのエレメントです。

var fd = new faceDeformer();
var webgl = document.getElementById('webgl');
fd.init(webgl);

fd.load()の第一引数は、マスク用のテクスチャが描画されているcanvasのエレメントです。
第二引数は、テクスチャから切り取る顔の頂点です。
第三引数は、ロード時ののモデルです。

var texture = document.getElementById("maskname");
fd.load(texture, maskPos, pModel);

これでfaceDeformerの設定は終わったので、あとはビデオから検出した顔に合わせて描画するだけです。
それと、fd.draw()の引数は表示したい頂点を渡します。

drawMaskLoop();
function drawMaskLoop() {
	var positions = ctrack.getCurrentPosition();
	overlayCC.clearRect(0, 0, 400, 300);
	if (positions) {
		fd.draw(positions);
	}
	requestAnimFrame(drawMaskLoop);
}

face2

自分の顔なんであまり変わりませんが、、、

これだけで、顔検出できるなんて便利ですね。
上手くまとめられなかったので、ご意見いただけたら訂正します。

それでは。