MediaPipeの使い方
1. MediaPipe
「MediaPipe」は、マルチモーダル(ビデオ、オーディオ、時系列データなど)を利用したMLパイプラインを構築するためのフレームワークです。これを利用することで、MLパイプラインを、「前処理」「推論」「後処理」「描画」などのノードを組み合わせたグラフとして構築できます。
2. MediaPipeのMLソリューション
MediaPipeのMLソリューションには、次のようなものがあります。
・ハンドトラッキング
・顔検出
・髪のセグメンテーション
・物体検出
3. macOSへのインストール
(1) HomebrewとXcodeをインストール
「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)グラフ実行の前に、グラフ出力を取得するために「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
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
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
10. MediaPipe Model
MediaPipeのモデルはここで提供されている。