この記事は The TensorFlow Blog の記事 "Face and hand tracking in the browser with MediaPipe and TensorFlow.js" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
投稿者: Google ソフトウェア エンジニア、Ann Yuan、Andrey Vakunov

本日は、2 つの新しいパッケージ facemeshhandpose のリリースについてお知らせします。それぞれ、顔の重要なランドマークと、手をトラッキングするパッケージです。このリリースは、Google Research の MediaPipe チーム、TensorFlow.js チームとの共同作業です。

facemesh パッケージ
handpose パッケージ

実際にブラウザでデモを試す

facemesh パッケージは、イメージ内の顔の境界線とランドマークを検出します。handpose パッケージは、手に対して同じことを行います。これらのパッケージは小さく高速で、完全にブラウザの中だけで実行されます。データがユーザーの端末の外に出ることはないので、ユーザーのプライバシーを保護できます。こちらのリンクから、すぐに試すことができます。
これらのパッケージは、MediaPipe の一部としても利用できます。MediaPipe は、マルチモーダル認識パイプラインを構築するためのライブラリです。
リアルタイムで顔や手をトラッキングすることで、新しいタイプのインタラクションが実現することを願っています。たとえば、顔のパーツの位置は表情を分類する上での基本情報になります。また、手のトラッキングはジェスチャー認識の第一段階です。このような機能を持つアプリケーションが、どのようにウェブのインタラクションやアクセシビリティの限界を広げるのかを見るのが楽しみです。

詳しい仕組み: facemesh


facemesh パッケージは、イメージや動画ストリームから顔面のジオメトリを 3D で大まかに推論します。入力として必要なのは 1 つのカメラだけで、深度センサーは不要です。このジオメトリによって、唇や顔の輪郭などの細かい部分も含め、顔の中の目、鼻、唇などのパーツを特定します。この情報は、表情の分類といった下流のタスクで使うことができます(ただし、個人の識別には利用できません)。さまざまなデータセットに対してモデルがどのように実行されるかの詳細は、モデルカードをご覧ください。このパッケージは、MediaPipe 経由でも利用できます。

パフォーマンスの特徴

facemesh は最大 3 MB の重みのみを含む軽量パッケージで、各種モバイル端末でリアルタイム推論を行うのに最適です。テストする際には、TensorFlow.js では数種類のバックエンドから選択できる機能を提供している点にご注意ください。たとえば、WebGL や、低スペックの GPU を搭載した端末に適した XNNPACK と WebAssembly(WASM)を使うことができます。下の表は、数種類の端末と TensorFlow.js バックエンドごとにパッケージのパフォーマンスを示しています。数種類の端末と TensorFlow.js バックエンドごとにパッケージのパフォーマンスを示す表

インストール

facemesh パッケージは、2 つの方法でインストールできます。
  1. NPM を使う場合:
    import * as facemesh from '@tensorflow-models/facemesh;
  2. script タグを使う場合:
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-core"></script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-converter"></script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/facemesh"></script>

使用方法

パッケージをインストールしたら、モデルの重みを読み込み、イメージを渡すだけで、顔のランドマークの検知を始めることができます。
// Load the MediaPipe facemesh model assets.
const model = await facemesh.load();
 
// Pass in a video stream to the model to obtain 
// an array of detected faces from the MediaPipe graph.
const video = document.querySelector("video");
const faces = await model.estimateFaces(video);
 
// Each face object contains a `scaledMesh` property,
// which is an array of 468 landmarks.
faces.forEach(face => console.log(face.scaledMesh));
estimateFaces の入力には、動画、静的イメージ、さらには node.js パイプラインで使用する ImageData インターフェースを指定できます。facemesh は、入力された顔(複数可能)の予測オブジェクトを含む配列を返します。この配列には、それぞれの顔の情報が含まれます(例: 信頼度、その顔の 468 個のランドマークの位置)。次に予測オブジェクトのサンプルを示します。
{
    faceInViewConfidence: 1,
    boundingBox: {
        topLeft: [232.28, 145.26], // [x, y]
        bottomRight: [449.75, 308.36],
    },
    mesh: [
        [92.07, 119.49, -17.54], // [x, y, z]
        [91.97, 102.52, -30.54],
        ...
    ],
    scaledMesh: [
        [322.32, 297.58, -17.54],
        [322.18, 263.95, -30.54]
    ],
    annotations: {
        silhouette: [
            [326.19, 124.72, -3.82],
            [351.06, 126.30, -3.00],
            ...
        ],
        ...
    }
}
API の詳細については、README をご覧ください。

詳しい仕組み: handpose

handpose パッケージは、入力されたイメージまたは動画ストリームから手を検知し、それぞれの手の特徴の位置を示す 21 個の 3 次元ランドマークを返します。このランドマークには、それぞれの指の関節や手のひらの位置も含まれます。このモデルは、2019 年 8 月に MediaPipe と通してリリースしました。モデルの詳しいアーキテクチャについては、リリースに合わせて公開されたブログ投稿をご覧ください。さまざまなデータセットに対して handpose がどのように実行されるかの詳細は、モデルカードをご覧ください。このパッケージは、MediaPipe 経由でも利用できます。

パフォーマンスの特徴

handpose は最大 12 MB の重みを含む比較的軽量なパッケージで、リアルタイム推論に適しています。下の表は、数種類の端末ごとにパッケージのパフォーマンスを示しています。数種類の端末でのパッケージのパフォーマンスを示した表

インストール

handpose パッケージは、2 つの方法でインストールできます。
  1. NPM を使う場合:
    import * as handtrack from '@tensorflow-models/handpose;
  2. script タグを使う場合:
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-core"></script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-converter"></script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/handpose"></script>

使用方法

パッケージをインストールしたら、モデルの重みを読み込み、イメージを渡すだけで、手のランドマークのトラッキングを始めることができます。
// Load the MediaPipe handpose model assets.
const model = await handpose.load();
 
// Pass in a video stream to the model to obtain 
// a prediction from the MediaPipe graph.
const video = document.querySelector("video");
const hands = await model.estimateHands(video);
 
// Each hand object contains a `landmarks` property,
// which is an array of 21 3-D landmarks.
hands.forEach(hand => console.log(hand.landmarks));
facemesh と同じく、estimateHands には動画、静的イメージ、ImageData インターフェースを入力できます。すると、入力された手の詳細を表すオブジェクトの配列が返されます。次に予測オブジェクトのサンプルを示します。
{
    handInViewConfidence: 1,
    boundingBox: {
        topLeft: [162.91, -17.42], // [x, y]
        bottomRight: [548.56, 368.23],
    },
    landmarks: [
        [472.52, 298.59, 0.00], // [x, y, z]
        [412.80, 315.64, -6.18],
        ...
    ],
    annotations: {
        indexFinger: [
            [412.80, 315.64, -6.18],
            [350.02, 298.38, -7.14],
            ...
        ],
        ...
    }
}
API の詳細については、README をご覧ください。

今後に向けて

facemesh と handpose は今後も改善を続ける予定です。近いうちに、複数の手をトラッキングする機能もサポートしたいと考えています。さらに、特にモバイル端末において、常にモデルの高速化に取り組んでいます。ここ数か月間の開発で、facemesh と handpose のパフォーマンスは大幅に向上しました。この傾向は今後も続くと確信しています。MediaPipe チームはさらに効率を上げたモデル アーキテクチャの開発に取り組んでおり、TensorFlow.js チームは推論を高速化する方法(演算の統合など)を常に調査しています。推論が高速になれば、リアルタイム パイプラインのモデルを大きくして、精度を上げることができます。

次のステップ

謝辞

パッケージのオリジナル実装を快く共有してくださった MediaPipe チームに感謝いたします。MediaPipe は、基盤となるモデルの開発とトレーニング、すべてを統合する後処理グラフの設計を行いました。

Reviewed by Khanh LeViet - Developer Relations Team