顔にモザイクをかけてFace Detection APIを試してみました

UI開発者 古川

Google Chrome 70よりOrigin Trialsとされた、Shape Detection API内で定義されているFace Detection APIを試してみました。

Face Detection APIは画像内から人間の顔を検出できるAPIです。Shape Detection APIの中で定義されているAPIの一種であり、Shape Detection APIには他にもバーコードを検出するBarcode Detection APIが定義されています。

Face Detection APIにおける顔認識の仕組み

現状Face Detection APIをGoogle Chrome 70で試すには、chrome://flagsから「Experimental Web Platform features」をEnabledに設定するか、特定のオリジンに対する期限付きトークンを取得する必要があります。(取得方法やOrigin Trialsの詳細はOrigin Trials Guide for Web Developersを参照ください)

Face Detection APIの使い方は非常にシンプルで、以下のソースの実行で画像内の顔認識ができます。

<img src="./face.jpg" id="image" alt="">
const decector = () => {
  const image = document.getElementById('image');

  const faceDetector = new window.FaceDetector({
    fastMode: true,
    maxDetectedFaces: 1
  });

  faceDetector.detect(image).then((faces) => {
    faces.forEach((face) => {
      console.log(face);
    });
  }).catch(error => {
    console.error("Error " + error);
  });
};

window.addEventListener('load', () => {
  decector();
});

オプション指定は以下です。

  • fastMode:顔認識について速度重視か精度重視か(速度重視であればtrue
  • maxDetectedFaces:検出される顔の最大数

FaceDetectordetectメソッドを保持しています。detectorメソッドの引数にimageBitmapSourceを渡すと顔の検出結果を検出の個数分配列で返却します。

配列のひとつひとつは以下のようなオブジェクトになっています。(以下のキャプチャは仕様書に掲載されているデモのものです)

boundingBoxには検出した顔の位置や範囲の情報が格納されます。landmarksには目、鼻、口の位置が格納されるのですが、現段階ではまだ仕様通りに動作しないようです。landmarksはブラウザ側で取得できない場合は空の配列として返却されます。

今回私が試したところlandmarksだけでなくmaxDetectedFacesを設定しても最大人数が適用されず、仕様通りに動作しませんでした。

Webカメラの映像から顔にモザイクをかけてみた

この機能を利用して顔にモザイクをかけるデモを作成してみました。

仕組みとしては、

  1. getUserMediaでWebカメラの映像を取得
  2. 以下をフレームレート毎に繰り返す
    1. Webカメラの映像をcanvasに転写
    2. canvasの画像からFace Detection APIで顔を検出
    3. 検出された顔の範囲のピクセルをgetImageDataで取得し、canvasでモザイクのように描画

となります。

デモを用いて実際に私の顔にモザイクをかけてみました!

顔全体を映さないと正しく認識しないようで、横を向いたり顔の一部を隠すとモザイクが取れてしまうので注意が必要です。

まとめ

landmarksが検出できるようになれば顔のパーツのみを検出できるので、たとえば眼鏡やつけ髭を付けるなど色々応用ができそうです。シンプルなソースコードとWebブラウザのみでリアルタイムに顔認識ができるようになるのはとても便利ですね。モダンブラウザに正式実装される日が楽しみです。