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 インスタンスを構成します。 そのため、ジェスチャー認識サンプルアプリ用のファイルのみを残します。
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/gesture_recognizer/android
    

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

主要コンポーネント

次のファイルには、この手の動きに不可欠なコードが含まれています サンプル アプリケーション:

セットアップ

このセクションでは、開発環境をセットアップする主な手順と ジェスチャー認識ツールを使用するコード プロジェクトが存在します。一般的な情報については、 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 ジェスチャー認識タスクには、MediaPipe ジェスチャー認識ツール できます。ジェスチャー認識ツールで利用可能なトレーニング済みモデルについて詳しくは、 タスクの概要のモデル セクションをご覧ください。

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

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

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

baseOptionBuilder.setModelAssetPath(MP_RECOGNIZER_TASK)

タスクを作成する

MediaPipe ジェスチャー認識タスクは、createFromOptions() 関数を使用して以下を設定します。 できます。createFromOptions() 関数は、次の値を受け入れます。 構成オプションを確認します。構成オプションについて詳しくは 構成オプションをご覧ください。

ジェスチャー認識ツールは、静止画像、動画ファイル、 ライブ動画ストリーム。対応する実行モードを指定する必要があります。 入力データ型を指定します。対応するタブを選択してください タスクの作成方法と推論の実行方法を確認できます。

画像

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

val optionsBuilder =
    GestureRecognizer.GestureRecognizerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setRunningMode(RunningMode.IMAGE)

val options = optionsBuilder.build()
gestureRecognizer =
    GestureRecognizer.createFromOptions(context, options)
    

動画

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

val optionsBuilder =
    GestureRecognizer.GestureRecognizerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()
gestureRecognizer =
    GestureRecognizer.createFromOptions(context, options)
    

ライブ配信

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

val optionsBuilder =
    GestureRecognizer.GestureRecognizerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.LIVE_STREAM)

val options = optionsBuilder.build()
gestureRecognizer =
    GestureRecognizer.createFromOptions(context, options)
    

ジェスチャー認識ツールのコード実装例では、 処理モードを選択できますこのアプローチでは、タスク作成コードが複雑になり、 ユースケースに適さない場合がありますこのコードは setupGestureRecognizer() 関数を次の GestureRecognizerHelper.kt 表示されます。

構成オプション

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

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

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

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

LIVE_STREAM: 入力のライブ配信のモード カメラからのデータなどです。このモードでは、resultListener は 結果を受け取るリスナーを設定するために呼び出されます。 使用できます。
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
numHands 次の手で検出できる手の最大数は、 GestureRecognizer 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
cannedGesturesClassifierOptions あらかじめ用意されたジェスチャー分類器の動作を設定するためのオプション。返信定型文は["None", "Closed_Fist", "Open_Palm", "Pointing_Up", "Thumb_Down", "Thumb_Up", "Victory", "ILoveYou"]
です
  • Display Name locale: TFLite Model Metadata で指定された表示名に使用する言語 / 地域(存在する場合)。
  • 最大結果数: 返される上位スコアの分類結果の最大数。<0 の場合、利用可能な結果がすべて返されます。
  • スコアしきい値: 下回った結果が拒否されるスコア。0 に設定すると、利用可能な結果がすべて返されます。
  • カテゴリの許可リスト: カテゴリ名の許可リスト。空でない場合、このセットにカテゴリがない分類結果は除外されます。拒否リストとは相互に排他的。
  • カテゴリの拒否リスト: カテゴリ名の拒否リスト。空でない場合、このセット内にカテゴリがある分類結果は除外されます。許可リストとは相互に排他的。
    • 表示名の言語 / 地域: any string
    • 最大結果数: any integer
    • スコアしきい値: 0.0-1.0
    • カテゴリの許可リスト: vector of strings
    • カテゴリの拒否リスト: vector of strings
    • 表示名の言語 / 地域: "en"
    • 最大結果数: -1
    • スコアしきい値: 0
    • カテゴリの許可リスト: 空
    • カテゴリの拒否リスト: 空
    customGesturesClassifierOptions カスタム ジェスチャー分類器の動作を設定するオプション。
  • Display Name locale: TFLite Model Metadata で指定された表示名に使用する言語 / 地域(存在する場合)。
  • 最大結果数: 返される上位スコアの分類結果の最大数。<0 の場合、利用可能な結果がすべて返されます。
  • スコアしきい値: 下回った結果が拒否されるスコア。0 に設定すると、利用可能な結果がすべて返されます。
  • カテゴリの許可リスト: カテゴリ名の許可リスト。空でない場合、このセットにカテゴリがない分類結果は除外されます。拒否リストとは相互に排他的。
  • カテゴリの拒否リスト: カテゴリ名の拒否リスト。空でない場合、このセット内にカテゴリがある分類結果は除外されます。許可リストとは相互に排他的。
    • 表示名の言語 / 地域: any string
    • 最大結果数: any integer
    • スコアしきい値: 0.0-1.0
    • カテゴリの許可リスト: vector of strings
    • カテゴリの拒否リスト: vector of strings
    • 表示名の言語 / 地域: "en"
    • 最大結果数: -1
    • スコアしきい値: 0
    • カテゴリの許可リスト: 空
    • カテゴリの拒否リスト: 空
    resultListener 分類結果を受け取るように結果リスナーを設定します。 ライブ ストリーム モードの場合は非同期で行われます。 実行モードが LIVE_STREAM に設定されている場合にのみ使用できます ResultListener なし なし
    errorListener オプションのエラーリスナーを設定します。 ErrorListener なし なし

    データの準備

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

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

    画像

    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()
        

    「ジェスチャー認識ツール」のサンプルコードをご覧ください。データの準備は GestureRecognizerHelper.kt 表示されます。

    タスクを実行する

    ジェスチャー認識機能は、recognizerecognizeForVideorecognizeAsync を使用します。 推論をトリガーできますジェスチャー認識の場合 入力データの前処理、画像内の手の検出、手の検出 ランドマークからの手の動きの認識などです

    次のコードは、タスクモデルを使用して処理を実行する方法を示しています。 これらのサンプルには、画像、動画ファイル、 ストリーミング動画にも対応しています

    画像

    val result = gestureRecognizer?.recognize(mpImage)
        

    動画

    val timestampMs = i * inferenceIntervalMs
    
    gestureRecognizer?.recognizeForVideo(mpImage, timestampMs)
        ?.let { recognizerResult ->
            resultList.add(recognizerResult)
        }
        

    ライブ配信

    val mpImage = BitmapImageBuilder(rotatedBitmap).build()
    val frameTime = SystemClock.uptimeMillis()
    
    gestureRecognizer?.recognizeAsync(mpImage, frameTime)
        

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

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

    ジェスチャー認識機能のサンプルコード、recognizerecognizeForVideorecognizeAsync 関数は、 GestureRecognizerHelper.kt 表示されます。

    結果の処理と表示

    ジェスチャー認識ツールは、操作ごとに 認識されます。結果のオブジェクトには、画像座標の手のランドマークが含まれます。 世界座標、利き手(左手と右手)、手の手のランドマーク 検出された手のジェスチャー カテゴリです。

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

    結果の GestureRecognizerResult には 4 つのコンポーネントが含まれます。各要素は配列で、各要素には 1 つの検出された手の検出結果が含まれます。

    • 利き手

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

    • ジェスチャー

      検出された手で認識されたジェスチャーのカテゴリ。

    • ランドマーク

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

    • 世界の名所

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

    GestureRecognizerResult:
      Handedness:
        Categories #0:
          index        : 0
          score        : 0.98396
          categoryName : Left
      Gestures:
        Categories #0:
          score        : 0.76893
          categoryName : Thumb_Up
      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)
    

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

    GestureRecognizerResultsAdapter GestureRecognizerResultsAdapter.kt 結果を処理できます。