GoogleのMediaPipe良いですね。コア部分はTensorFlowLiteでできていて、Pre/Postプロセス部分をUnityで書き直すことで移植できました。まだ勉強中ですがメモ。
↓ こんな感じでUnity上で動作してます。
Face Tracking and Blaze Face
FaceMesh from RGB webcam runs around 50fps on my Mac. #madewithunity #tensorflowlite pic.twitter.com/qZgEC29MmD
— Koki Ibukuro (@asus4) September 3, 2020
Blaze Pose
Fixed issues related with webcam rotation. Applied a velocity filter from mediapipe. pic.twitter.com/VQ03wrpQuI
— Koki Ibukuro (@asus4) 2020年8月27日
Hand Tracking
Fixed bugs and improved accuracy. pic.twitter.com/D513tLFVpA
— Koki Ibukuro (@asus4) 2020年8月25日
全体
MediaPipeのBlaze Face, Balze Pose, Hand Trackingは細かい違いはあれど、かなり似ていて。大きく分けて2つTensorFlow Liteのモデルが動いています。
- SSD Detection: オブジェクトの矩形エリアを推定します。
- Landmark Detection: オブジェクトの画像からランドマーク(骨格など)を推定します。
MediaPipeはWebで処理を見ることができます。以下はBlaze Faceの例です。Max/MSPのノードのような感じで全体を俯瞰できるので、まずここから概要を掴みました。 https://viz.mediapipe.dev/demo/face_detection
その他のモデルもこちらから見れます。
それぞれのTFLiteについて見ていきます。
1. SSD Detection
SSD(Single Shot Detetor)でオブジェクトの矩形エリアを返します。
Pre Process
とくに難しいことはなく、入力画像のサイズにトリムしてfloatの配列に変換するだけです。
がPC上のWebカメラでやるときは簡単ですが、スマートフォンではWebcamTextureは回転とフリップしてるんですよね…。とても面倒くさいです。私の場合は入力画像とWebカメラの回転の正規化を一度にするシェーダーを用意しました。
Post Process
とりあえず重なる部分も含めて多めに返して、CPU側でNon Max Suppressionというアルゴリズムを使って精度を上げています。Courseraの動画で概要を理解しました。最近他のライブラリにも追加されてるの見ました。
通常のSSDモデルは推定された矩形エリアを返すだけですが。これはキーポイントと呼ばれる特徴点も返します。これは次のプロセスで使います。
2. Landmark Detection
Pre Process
カメラ画像から対象のオブジェクト部分をトリムします。トリムするときに、キーポイントの情報をもとに回転を直します。これは頭良いなーと。回転を直してからLandmarkを検出するモデルに画像を入力することで精度が上がるとのこと。当初バグで、間違った回転をした画像をLandmark Detectionのモデルに入力したのですが、精度が全然違いました。
緑色が矩形エリアとキーポイント。赤が回転とクロップする範囲。右上のちっこい手が実際のLandmark Detectionへの入力画像です。手が横向きになっても入力画像は上向きなのがわかると思います。
Post Process
FaceMeshとHand Landmarkは出力されたランドマークをそのまま表示しています。BlazePoseはすこし値が暴れるのかRelative Velocity Filterというものを使っています。移動が少ないときは強めのローパスフィルタ。移動が多いときはフィルタを弱めるというもののようです。
返されるランドマークは、入力画像に対しての値です。それを、2段階の画像入力で使ったMatrix4x4の逆行列をかけて、Unityの座標に戻しています。この変換も結構ややこしかったです。
まとめ
MediaPipeの処理はかなり似ていて、一度作るとHandTracking, BlazePose, BlazeFaceも大体同じプログラムが適用できました。機械学習の勉強のために初めてTensorFlow LiteのUnity移植ですが、共通する処理が結構出てきて。自分のためになっている気がします。
参考
TensorFlow Lite界隈は日本人が多く活躍していますね。@PINTO03091さん、@terrykyさんのTwitter, GitHubをよく参考にさせていただいております。