手のランドマーク検出ガイド(Android)

MediaPipe の手のランドマーカー タスクを使用すると、画像内の手のランドマークを検出できます。 Android アプリでハンド ランドマーカーを使用する手順は以下のとおりです。「 この手順で説明するコードサンプルは、 GitHub

機能、モデル、構成オプションの詳細については、 概要をご覧ください。

サンプルコード

MediaPipe Tasks のサンプルコードは、ハンド ランドマーカーの単純な実装です。 アプリこの例では、物理的な Android デバイスのカメラを使用して、 手のランドマークを継続的に検出します。また、画像と動画を使用して、 静的に手のランドマークを検出できます。

独自の Android アプリの出発点としてアプリを使用することも、アプリ自体に言及することもできます。 変更する際の注意点があります。ハンド マーカーのサンプルコードは、 GitHub

コードをダウンロードする

次の手順では、サンプルのローカルコピーを作成する方法を示します。 git コマンドライン ツールを使用してコードを実行します。

<ph type="x-smartling-placeholder">

サンプルコードをダウンロードするには:

  1. 次のコマンドを使用して Git リポジトリのクローンを作成します。
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. 必要に応じて、スパース チェックアウトを使用するように Git インスタンスを構成します。 そのため、Hand Landmarker サンプルアプリのファイルのみが含まれることになります。
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/hand_landmarker/android
    

サンプルコードのローカル バージョンを作成したら、プロジェクトをインポートできます。 アプリを実行します。手順については、次をご覧ください: Android 向けセットアップ ガイド

主要コンポーネント

次のファイルには、この手のランドマークの重要なコードが含まれています アプリケーションです。

  • HandLandmarkerHelper.kt - ハンド ランドマーク検出機能を初期化し、モデルとデリゲートを処理する 選択します。
  • MainActivity.kt - HandLandmarkerHelper の呼び出しなど、アプリを実装します。

セットアップ

このセクションでは、開発環境をセットアップする主な手順と ハンド ランドマーカーを使用するというコード プロジェクトがありました。一般的な情報については、 MediaPipe タスクを使用するための開発環境の設定 プラットフォーム バージョンの要件については、 Android の設定ガイド

<ph type="x-smartling-placeholder">

依存関係

ハンド ランドマーク タスクでは、com.google.mediapipe:tasks-vision を使用します。 ライブラリです。Android アプリの build.gradle ファイルに次の依存関係を追加します。

dependencies {
    implementation 'com.google.mediapipe:tasks-vision:latest.release'
}

モデル

MediaPipe のハンドランドマーカー タスクには、以下と互換性のあるトレーニング済みモデルバンドルが必要です できます。ハンド ランドマーク ツールで利用可能なトレーニング済みモデルについて詳しくは、 タスクの概要のモデル セクションをご覧ください。

モデルを選択してダウンロードし、プロジェクト ディレクトリに保存します。

<dev-project-root>/src/main/assets

ModelAssetPath パラメータ内でモデルのパスを指定します。 サンプルコード、 モデルは HandLandmarkerHelper.kt で定義されています。 ファイル:

baseOptionBuilder.setModelAssetPath(MP_HAND_LANDMARKER_TASK)

タスクを作成する

MediaPipe のハンド ランドマーカー タスクでは、createFromOptions() 関数を使用して タスクを実行します。createFromOptions() 関数は構成の値を受け入れます。 。構成オプションの詳細については、このモジュールの 構成オプション

ハンド マーカーは、静止画像、動画ファイル、 おすすめします。モデルに対応する実行モードを 入力データ型を使用します。レポートタイプに対応するタブを 入力データ型を見て、タスクの作成方法と推論の実行方法を確認します。

画像

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_HAND_LANDMARKER_TASK)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder =
    HandLandmarker.HandLandmarkerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setNumHands(maxNumHands)
        .setRunningMode(RunningMode.IMAGE)

val options = optionsBuilder.build()

handLandmarker =
    HandLandmarker.createFromOptions(context, options)
    

動画

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_HAND_LANDMARKER_TASK)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder =
    HandLandmarker.HandLandmarkerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setNumHands(maxNumHands)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()

handLandmarker =
    HandLandmarker.createFromOptions(context, options)
    

ライブ配信

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_HAND_LANDMARKER_TASK)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder =
    HandLandmarker.HandLandmarkerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setNumHands(maxNumHands)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()

handLandmarker =
    HandLandmarker.createFromOptions(context, options)
    

ハンド マーカー コードのサンプル コードを実装すると、 処理モードを選択できますこのアプローチでは、タスク作成コードが複雑になり、 ユースケースに適さない場合がありますこのコードは setupHandLandmarker() 関数を次の HandLandmarkerHelper.kt 表示されます。

構成オプション

このタスクには、Android アプリ用に次の構成オプションがあります。

オプション名 説明 値の範囲 デフォルト値
runningMode タスクの実行モードを設定します。3 つの モード:

IMAGE: 単一画像入力のモード。

VIDEO: 動画のデコードされたフレームのモード。

LIVE_STREAM: 入力のライブ配信のモード カメラからのデータなどです。このモードでは、resultListener は 結果を受け取るリスナーを設定するために呼び出されます。 使用できます。
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
numHands 手のランドマーク検出機能で検出される手の最大数。 Any integer > 0 1
minHandDetectionConfidence ハンド検出の最小信頼スコアは、 成功したと考えられています。 0.0 - 1.0 0.5
minHandPresenceConfidence 手のプレゼンス スコアの最小信頼スコア モデルです。動画モードとライブ配信モードでは 手のランドマーク モデルの手の存在の信頼スコアが次の場合 手のひら検出モデルがトリガーされます。それ以外の場合: 軽量のハンド トラッキング アルゴリズムによって、 その後のランドマーク検出に使用します。 0.0 - 1.0 0.5
minTrackingConfidence ハンド トラッキングの最小信頼スコア 成功です。グラフ内の手間の境界ボックスの IoU しきい値です。 現在のフレームと最後のフレームが表示されます。動画モードとストリーム モードでは、 手の地面マーカー(追跡がうまくいかなかった場合、手の地面マーカーが手を動かします) できます。それ以外の場合は、手の検出をスキップします。 0.0 - 1.0 0.5
resultListener 検出結果を受信する結果リスナーを設定する ライブ ストリーム モードのときに非同期で送信されます。 実行モードが LIVE_STREAM に設定されている場合にのみ適用されます なし なし
errorListener オプションのエラーリスナーを設定します。 なし なし

データの準備

Handmark は、画像、動画ファイル、ライブ ストリーム動画に対応しています。タスク サイズ変更、回転、値を含むデータ入力の前処理を処理 説明します。

次のコードは、処理のためにデータを引き渡す方法を示しています。論文 サンプルには、画像、動画ファイル、ライブ ストリーミング データ、 動画ストリーム。

画像

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(image).build()
    

動画

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

val argb8888Frame =
    if (frame.config == Bitmap.Config.ARGB_8888) frame
    else frame.copy(Bitmap.Config.ARGB_8888, false)

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(argb8888Frame).build()
    

ライブ配信

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(rotatedBitmap).build()
    

土地マーカーのハンド サンプルコード。データの準備は、 HandLandmarkerHelper.kt 表示されます。

タスクを実行する

扱うデータのタイプに応じて、 そのデータ型に固有の HandLandmarker.detect...() メソッドを使用します。使用 個々の画像の場合は detect()、 動画ファイル内のフレームの場合は detectForVideo() 動画ストリームの場合は detectAsync()。Cloud Storage バケットに 検出を別のスレッドで実行して、この問題を回避してください。 ユーザー インターフェース スレッドをブロックします。

次のコードサンプルは、ハンド ランドマーカーを実行する簡単な例を示しています。 さまざまなデータモードで

画像

val result = handLandmarker?.detect(mpImage)
    

動画

val timestampMs = i * inferenceIntervalMs

handLandmarker?.detectForVideo(mpImage, timestampMs)
    ?.let { detectionResult ->
        resultList.add(detectionResult)
    }
    

ライブ配信

val mpImage = BitmapImageBuilder(rotatedBitmap).build()
val frameTime = SystemClock.uptimeMillis()

handLandmarker?.detectAsync(mpImage, frameTime)
    

次の点にご留意ください。

  • 動画モードまたはライブ配信モードで実行する場合は、 ハンド ランドマーク タスクに入力フレームのタイムスタンプを提供します。
  • 画像モードまたは動画モードで実行すると、手のランドマーク タスクが 入力画像の処理が完了するまで、現在のスレッドをブロックします。 クリックします。ユーザー インターフェースがブロックされないように、 使用します。
  • ライブ ストリーム モードで実行している場合、手のランドマーク タスクがブロックされない すぐに戻ります。このメソッドは、 完了するたびに、その検出結果が 表示されます。ハンド ランドマーク タスクの実行時に検出関数が呼び出された場合 別のフレームの処理でビジー状態の場合、タスクは新しい入力フレームを無視します。

ハンド ランドマーク マーカーのサンプルコード、detectdetectForVideodetectAsync 関数は、 HandLandmarkerHelper.kt 表示されます。

結果の処理と表示

ハンド ランドマーカーは、検出ごとにハンド ランドマーク結果オブジェクトを生成します あります。結果のオブジェクトには、画像座標の手のランドマーク、手のひら 検出された対象物の世界座標と利き手(左手/右手)のランドマーク できます。

このタスクからの出力データの例を次に示します。

HandLandmarkerResult の出力には 3 つのコンポーネントが含まれます。各コンポーネントは配列で、各要素には検出された 1 つの手について以下の結果が含まれます。

  • 利き手

    利き手は、検出された手が左手か右手かを表します。

  • ランドマーク

    21 個のハンド ランドマークがあり、それぞれ xyz 座標で構成されています。「 x 座標と y 座標は、画像の幅と [0.0, 1.0] に正規化されます。 あります。z 座標はランドマークの深さを表します。 手首の奥行きが原点になります。値が小さいほど、 カメラに映し出されますz の大きさは、 x

  • 世界の名所

    21 の針のランドマークも世界座標で示されています。各ランドマーク は xyz で構成されており、次の現実世界の 3D 座標を表します。 m を、手の幾何学的中心を原点とします。

HandLandmarkerResult:
  Handedness:
    Categories #0:
      index        : 0
      score        : 0.98396
      categoryName : Left
  Landmarks:
    Landmark #0:
      x            : 0.638852
      y            : 0.671197
      z            : -3.41E-7
    Landmark #1:
      x            : 0.634599
      y            : 0.536441
      z            : -0.06984
    ... (21 landmarks for a hand)
  WorldLandmarks:
    Landmark #0:
      x            : 0.067485
      y            : 0.031084
      z            : 0.055223
    Landmark #1:
      x            : 0.063209
      y            : -0.00382
      z            : 0.020920
    ... (21 world landmarks for a hand)

次の図は、タスク出力を可視化したものです。

ハンド マーカーのサンプル コードでは、 結果については、 OverlayView クラスをご覧ください。