見出し画像

MediaPipeの使い方

1. MediaPipe

MediaPipe」は、マルチモーダル(ビデオ、オーディオ、時系列データなど)を利用したMLパイプラインを構築するためのフレームワークです。これを利用することで、MLパイプラインを、「前処理」「推論」「後処理」「描画」などのノードを組み合わせたグラフとして構築できます。

2. MediaPipeのMLソリューション

MediaPipeのMLソリューションには、次のようなものがあります。

・ハンドトラッキング
・顔検出
・髪のセグメンテーション
・物体検出

画像1

3. macOSへのインストール

(1) HomebrewXcodeをインストール
「Xcode」は一度起動して、コマンドラインツールもインストールします。

(2) MediaPipeリポジトリをクローン
「MediaPipe」リポジトリをクローンします。

$ git clone https://github.com/google/mediapipe.git
$ cd mediapipe

(3) Bazelをインストール(0.24.1以降)
Bazel入門」を参照。

(4) OpenCVとFFmpegをインストール
「FFmpeg」は「OpenCV」を介してインストールされます。

$ brew install opencv@3

(5) デスクトップ版のHelloWorldを実行
デスクトップ版のHelloWorldを実行には、以下のコマンドを入力します。
「GLOG_logtostderr=1」でglog(Google Logging Library)の出力を有効化しています。デスクトップではGPUは現在サポートされていないので、オプション「MEDIAPIPE_DISABLE_GPU=1」が必要になります。

$ export GLOG_logtostderr=1
$ bazel run --define MEDIAPIPE_DISABLE_GPU=1 \
   mediapipe/examples/desktop/hello_world:hello_world

初回はビルドも行われるので時間がかかります。
成功すると、以下のように「Hello World!」が10回出力されます。

# Should print:
# Hello World!
# Hello World!
# Hello World!
# Hello World!
# Hello World!
# Hello World!
# Hello World!
# Hello World!
# Hello World!
# Hello World!

4. Ubuntuへのインストール

(1) MediaPipeリポジトリをクローン
「MediaPipe」リポジトリをクローンします。

$ git clone https://github.com/google/mediapipe.git
$ cd mediapipe

(2) Bazelをインストール(0.24.1以降)
Bazel入門」を参照。

(3) OpenCVとFFmpegをインストール
「FFmpeg」は「libopencv-video-dev」を介してインストールされます。

$ sudo apt-get install libopencv-core-dev libopencv-highgui-dev \
   libopencv-imgproc-dev libopencv-video-dev

(4) GPUアクセラレーションの利用

# EGLドライバーをサポートするGPUが必要
# mesa GPUライブラリをデスクトップに使用できる(またはNvidia/AMDと同等)
sudo apt-get install mesa-common-dev libegl1-mesa-dev libgles2-mesa-dev

(5) デスクトップ版のHelloWorldを実行
デスクトップ版のHelloWorldを実行には、以下のコマンドを入力します。
GPU版でビルドするには、 「--define MEDIAPIPE_DISABLE_GPU=1」を「--copt -DMESA_EGL_NO_X11_HEADERS」に入れ替えてください。

$ export GLOG_logtostderr=1
$ bazel run --define MEDIAPIPE_DISABLE_GPU=1 \
   mediapipe/examples/desktop/hello_world:hello_world
# Should print:
# Hello World!
# Hello World!
# Hello World!
# Hello World!
# Hello World!
# Hello World!
# Hello World!
# Hello World!
# Hello World!
# Hello World!

5. HelloWorldの詳細

(1)「HelloWorld」では、PrintHelloWorld()で、「MediaPipe」グラフを定義して実行してます。

::mediapipe::Status PrintHelloWorld() {
  //2つのPassThroughCalculatorsを連結する単純なグラフを設定
  CalculatorGraphConfig config = ParseTextProtoOrDie<CalculatorGraphConfig>(R"(
    input_stream: "in"
    output_stream: "out"
    node {
      calculator: "PassThroughCalculator"
      input_stream: "in"
      output_stream: "out1"
    }
    node {
      calculator: "PassThroughCalculator"
      input_stream: "out1"
      output_stream: "out"
    }
  )");

以下の「MediaPipe」グラフを「Visualizer」のサイトに貼り付けることにより、グラフを視覚化できます。「Visualizer」のヘルプについては、こちらを参照してください。

input_stream: "in"
    output_stream: "out"
    node {
      calculator: "PassThroughCalculator"
      input_stream: "in"
      output_stream: "out1"
    }
    node {
      calculator: "PassThroughCalculator"
      input_stream: "out1"
      output_stream: "out"
    }

このグラフは、1つのグラフ入力ストリーム(in)と1つのグラフ出力ストリーム(out)、および直列に接続された2つの「PassThroughCalculator」で構成されます。

画像2

(2)グラフ実行の前に、グラフ出力を取得するために「OutputStreamPoller」を出力ストリームに接続します。その後、StartRun()でグラフの実行が開始されます。

CalculatorGraph graph;
RETURN_IF_ERROR(graph.Initialize(config));
ASSIGN_OR_RETURN(OutputStreamPoller poller,
                graph.AddOutputStreamPoller("out"));
RETURN_IF_ERROR(graph.StartRun({}));

(3)MakePacket()を使用して10個の「パケット」を作成し、入力ストリームを介してグラフに追加し、最後に入力ストリームを閉じて、グラフ実行を終了します。

for (int i = 0; i < 10; ++i) {
  RETURN_IF_ERROR(graph.AddPacketToInputStream("in", MakePacket<std::string>("Hello World!").At(Timestamp(i))));
}
RETURN_IF_ERROR(graph.CloseInputStream("in"));

(4)「OutputStreamPoller」を介して、出力ストリームから10個すべての「パケット」を取得し、各パケットから文字列コンテンツを取得して、ログに出力します。

mediapipe::Packet packet;
while (poller.Next(&packet)) {
  LOG(INFO) << packet.Get<string>();
}

ソースコード全体は次の通りです。

【hello_world.cc】

#include "mediapipe/framework/calculator_graph.h"
#include "mediapipe/framework/port/logging.h"
#include "mediapipe/framework/port/parse_text_proto.h"
#include "mediapipe/framework/port/status.h"

namespace mediapipe {

::mediapipe::Status PrintHelloWorld() {
  // 2つのPassThroughCalculatorsを連結する単純なグラフを設定
  CalculatorGraphConfig config = ParseTextProtoOrDie<CalculatorGraphConfig>(R"(
    input_stream: "in"
    output_stream: "out"
    node {
      calculator: "PassThroughCalculator"
      input_stream: "in"
      output_stream: "out1"
    }
    node {
      calculator: "PassThroughCalculator"
      input_stream: "out1"
      output_stream: "out"
    }
  )");

  CalculatorGraph graph;
  MP_RETURN_IF_ERROR(graph.Initialize(config));
  ASSIGN_OR_RETURN(OutputStreamPoller poller,
                   graph.AddOutputStreamPoller("out"));
  MP_RETURN_IF_ERROR(graph.StartRun({}));

  // "Hello World!"を含む10個の入力パケットを提供
  for (int i = 0; i < 10; ++i) {
    MP_RETURN_IF_ERROR(graph.AddPacketToInputStream(
        "in", MakePacket<std::string>("Hello World!").At(Timestamp(i))));
  }
  // 入力ストリームinを閉じる
  MP_RETURN_IF_ERROR(graph.CloseInputStream("in"));
  mediapipe::Packet packet;

  // 出力パケットを取得
  while (poller.Next(&packet)) {
    LOG(INFO) << packet.Get<std::string>();
  }
  return graph.WaitUntilDone();
}
}  // namespace mediapipe

int main(int argc, char** argv) {
  google::InitGoogleLogging(argv[0]);
  CHECK(mediapipe::PrintHelloWorld().ok());
  return 0;
}

6. ハンドトラッキングのデモの実行

CPU版のハンドトラッキングのデモの実行のコマンドは次の通りです。

# ビルド
$ bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 \
   mediapipe/examples/desktop/hand_tracking:hand_tracking_cpu

# 実行
$ export GLOG_logtostderr=1
$ bazel-bin/mediapipe/examples/desktop/hand_tracking/hand_tracking_cpu \
    --calculator_graph_config_file=mediapipe/graphs/hand_tracking/hand_tracking_desktop_live.pbtxt

画像3

7. 顔検出のデモの実行

CPU版の顔検出のデモの実行のコマンドは次の通りです。

# ビルド
$ bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 \
   mediapipe/examples/desktop/face_detection:face_detection_cpu

# 実行
$ export GLOG_logtostderr=1
$ bazel-bin/mediapipe/examples/desktop/face_detection/face_detection_cpu \
   --calculator_graph_config_file=mediapipe/graphs/face_detection/face_detection

画像4

8. 髪セグメンテーションのデモの実行

GPU版の髪セグメンテーションのデモの実行のコマンドは次の通りです。
このデモは現在Linuxでのみ実行できます。

# ビルド
$ bazel build -c opt --copt -DMESA_EGL_NO_X11_HEADERS \
   mediapipe/examples/desktop/hair_segmentation:hair_segmentation_gpu

# 実行
$ export GLOG_logtostderr=1
$ bazel-bin/mediapipe/examples/desktop/hair_segmentation/hair_segmentation_gpu \
    --calculator_graph_config_file=mediapipe/graphs/hair_segmentation/hair_segmentation_mobile_gpu.pbtxt

9. 物体検出のデモの実行

CPU版の物体検出のデモの実行のコマンドは次の通りです。

# ビルド
$ bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 \
   mediapipe/examples/desktop/object_detection:object_detection_cpu

# 実行
$ export GLOG_logtostderr=1
$ bazel-bin/mediapipe/examples/desktop/object_detection/object_detection_cpu \
    --calculator_graph_config_file=mediapipe/graphs/object_detection/object_detection_desktop_live.pbtxt
Graph

画像5

10. MediaPipe Model

MediaPipeのモデルはここで提供されている。

いいなと思ったら応援しよう!