MediaPipeのHand Tracking からのデータ取得

MediaPipe の Hand Tracking データを外部に保存する必要があった。

「【MediaPipe】Multi Hand Trackingから検出データを抽出した」を基にさせてもらい、Windows でデータを取得できるようにした。

上記Webが扱っているMediaPipe のバージョンとこれを執筆時点のMediaPipe のバージョンが異なるため、執筆時点のMediaPipe のバージョンに合わせる修正をした。下記のビルドに利用したファイルを https://github.com/kunsen-an/mediapipe に置いた。

環境

試したソフトウェアなどのバージョンは以下の通りである。

  • Windows 11 Pro 22000.556
  • MediaPipe v0.8.9 (14 Dec 2021)

ビルドのための、bazel や Visual C++、Pythonは、Windows 10にMediaPipe をインストール (WSL不使用) で設定したものを利用している。これらは最新バージョンとは異なる。

Hand Tracking のグラフの変更

データのファイルへの保存は、PassThroughCalculatorを用いた「【MediaPipe】Multi Hand Trackingから検出データを抽出した」を基にしている。

ただし、「【MediaPipe】Multi Hand Trackingから検出データを抽出した」は、MediaPipe v0.7.4 を基にしており、v0.8.9では Hand Tracking のグラフが変更されているのでそのまま動作させることができなかった。

MediaPipe v0.8.9 の Hand Tracking のグラフ mediapipe/graphs/hand_tracking/hand_tracking_desktop_live.pbtxt を Mediapipe Visualizer で可視化すると次の通りであった。

このHandLandMarkTrackingCpu と HandRenderer の間に、PathThroughCalculator を追加した(mediapipe/graphs/hand_tracking/hand_tracking_desktop_live_out.pbtxt)。Mediapipe Visualizer で可視化したものは次の通りである。

mediapipe/graphs/hand_tracking/hand_tracking_desktop_live_out.pbtxt は以下の通り。

demo_run_graph_main.cc の変更

グラフを実行して、PassThroughCalculator のデータを保存するために、mediapipe/examples/desktop/demo_run_graph_main.cc を変更し、mediapipe/examples/desktop/demo_run_graph_main_out.cc とした。

以前のMediaPipe v0.7.4 ではフレームごとにランドマークや手の矩形、手の平、手の平の矩形などが出力されていたようであるが、MediaPipe v0.8.9では、実際に検出されたときにしかデータ出力されない。このため、すべてのデータが揃うのを待っていては適切なタイミングでデータを保存できない。

やむを得ないので、PassThroughCalculator にPoller を追加し、そのキューが空でなければ(poller_?????.QueueSize() > 0)、データがあるとし、すべてのデータが揃った際にファイルに(save_dataがtrueの場合に)データを出力することにした。すべてのデータが揃わなくてもデータを保存した方がよい場合には、ファイルへ出力する(save_dataの)条件を変更する必要がある。

データが揃わない場合(save_dataが falseの場合)には、processTypeList でキューの処理は行うが、ファイルへのデータ出力は行わない。この処理のタイミングがフローによって異なるため、キューの処理よりも入力ビデオの処理が速い場合には、データ出力のタイミングがずれる可能性がある。現時点では、処理をするCPUの性能が十分に高ければ、そのようなことはないと考えている。念のために、キューの長さが1より大きくなったら処理が間に合っていないとして、警告(LOG(WARNING))を出力するようにしている。

mediapipe/examples/desktop/demo_run_graph_main_out.cc は以下の通りである。

ビルド

ビルドするターゲットを mediapipe/examples/desktop/hand_tracking:hand_tracking_cpu_out にし、基になる グラフをmediapipe/graphs/hand_tracking/hand_tracking_desktop_live_out.pbtxt に、C++プログラムを mediapipe/examples/desktop/demo_run_graph_main_out.cc にし、PathThroughCalculator を利用するため、bazel のBUILDファイルを変更した。

mediapipe/examples/desktop/BUILD

name =  demo_run_graph_main_out の cc_library を追加し、依存しているものに以下を追加した。

"//mediapipe/framework/formats:detection_cc_proto",
"//mediapipe/framework/formats:landmark_cc_proto",
"//mediapipe/framework/formats:rect_cc_proto"

mediapipe/examples/desktop/hand_tracking/BUILD

name =  hand_tracking_cpu_out の cc_library を追加し、依存しているものはhand_tracking_cpuを基にして以下とした。

"//mediapipe/examples/desktop:demo_run_graph_main_out", "//mediapipe/graphs/hand_tracking:desktop_tflite_calculators"

mediapipe/graphs/hand_tracking/BUILD

name = "desktop_tflite_calculators" の cc_library の依存しているものに "//mediapipe/calculators/core:pass_through_calculator" を追加した。

環境設定

利用したツールなどは以下の設定を行ってコマンドプロンプト内でビルドした。

以下では、この設定の下での例を示す。

bazel build の実行

D:\mediapipe_repo\mediapipe で以下のbazel build を実行し、hand_tracking_cpu_out.exe をビルドした。

bazel-bin\mediapipe\examples\desktop\hand_tracking\hand_tracking_cpu_out.exe に実行ファイルが構築された。

hand_tracking_cpu_out.exeの実行

ビルドした hand_tracking_cpu_out.exe を以下のコマンドで実行した。

以下の例では、set GLOG_logtostderr=1 を実行しておき、ログを標準エラー出力に表示している。この環境変数の設定を行わないと、画面には出力されない。

実行時のプレビューウィンドウ

実行時のログの情報出力

ログの出力レベルを変更するには環境変数を設定する。set GLOG_minloglevel=1 を実行するすることで、INFOレベルのメッセージは出力せず、WARNING以上を出力する。値に2、 3 を指定することで、それぞれERROR以上、FATAL になる。

データ出力

hand_tracking_cpu_out.cc の中の std::string output_dirpath = std::string("./result"); で出力を指定している。この例では、カレントディレクトリをD:\mediapipe_repo\mediapipe として実行しているので、 D:\mediapipe_repo\mediapipe\result にデータが出力される。

出力された .bin ファイルは人が可読形式になっていないので、必要に応じて変換を行う必要がある。