Python 用手のランドマーク検出ガイド

MediaPipe Hand Landmarker タスクを使用すると、画像内の手のランドマークを検出できます。ここでは、Python でハンド ランドマーカーを使用する方法について説明します。これらの手順で説明するコードサンプルは GitHub で入手できます。

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

サンプルコード

Hand Landmarker のサンプルコードには、このタスクの Python での完全な実装が含まれています。このコードは、このタスクをテストし、独自の手のランドマーク検出機能の構築を開始するのに役立ちます。ウェブブラウザのみを使用して、ハンド ランドマークのサンプルコードを表示、実行、編集できます。

Raspberry Pi 用に Hand LandMarker を実装する場合は、Raspberry Pi のサンプルアプリをご覧ください。

セットアップ

このセクションでは、Hand Landmarker を使用するように開発環境とコード プロジェクトを設定する主な手順について説明します。プラットフォーム バージョンの要件など、MediaPipe タスクを使用する開発環境の設定に関する一般的な情報については、Python の設定ガイドをご覧ください。

パッケージ

MediaPipe Hand Landmarker タスクには、mediapipe PyPI パッケージが必要です。これらの依存関係は、次のコマンドを使用してインストールしてインポートできます。

$ python -m pip install mediapipe

インポート

次のクラスをインポートして、Hand Landmarker タスク関数にアクセスします。

import mediapipe as mp
from mediapipe.tasks import python
from mediapipe.tasks.python import vision

モデル

MediaPipe Hand Landmarker タスクには、このタスクに対応したトレーニング済みモデルが必要です。Hand Landmarker で使用可能なトレーニング済みモデルの詳細については、タスクの概要のモデルのセクションをご覧ください。

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

model_path = '/absolute/path/to/gesture_recognizer.task'

BaseOptions オブジェクトの model_asset_path パラメータを使用して、使用するモデルのパスを指定します。コード例については、次のセクションをご覧ください。

タスクを作成する

MediaPipe Hand Landmarker タスクは、create_from_options 関数を使用してタスクを設定します。create_from_options 関数は、処理する構成オプションの値を受け入れます。構成オプションの詳細については、構成オプションをご覧ください。

次のコードは、このタスクをビルドして構成する方法を示しています。

これらのサンプルは、画像、動画ファイル、ライブ配信のタスクの作成方法の違いも示しています。

画像

import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
HandLandmarker = mp.tasks.vision.HandLandmarker
HandLandmarkerOptions = mp.tasks.vision.HandLandmarkerOptions
VisionRunningMode = mp.tasks.vision.RunningMode

# Create a hand landmarker instance with the image mode:
options = HandLandmarkerOptions(
    base_options=BaseOptions(model_asset_path='/path/to/model.task'),
    running_mode=VisionRunningMode.IMAGE)
with HandLandmarker.create_from_options(options) as landmarker:
  # The landmarker is initialized. Use it here.
  # ...
    

動画

import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
HandLandmarker = mp.tasks.vision.HandLandmarker
HandLandmarkerOptions = mp.tasks.vision.HandLandmarkerOptions
VisionRunningMode = mp.tasks.vision.RunningMode

# Create a hand landmarker instance with the video mode:
options = HandLandmarkerOptions(
    base_options=BaseOptions(model_asset_path='/path/to/model.task'),
    running_mode=VisionRunningMode.VIDEO)
with HandLandmarker.create_from_options(options) as landmarker:
  # The landmarker is initialized. Use it here.
  # ...
    

ライブ配信

import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
HandLandmarker = mp.tasks.vision.HandLandmarker
HandLandmarkerOptions = mp.tasks.vision.HandLandmarkerOptions
HandLandmarkerResult = mp.tasks.vision.HandLandmarkerResult
VisionRunningMode = mp.tasks.vision.RunningMode

# Create a hand landmarker instance with the live stream mode:
def print_result(result: HandLandmarkerResult, output_image: mp.Image, timestamp_ms: int):
    print('hand landmarker result: {}'.format(result))

options = HandLandmarkerOptions(
    base_options=BaseOptions(model_asset_path='/path/to/model.task'),
    running_mode=VisionRunningMode.LIVE_STREAM,
    result_callback=print_result)
with HandLandmarker.create_from_options(options) as landmarker:
  # The landmarker is initialized. Use it here.
  # ...
    

画像で使用するハンド ランドマークの作成例については、コードサンプルをご覧ください。

設定オプション

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

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

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

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

LIVE_STREAM: カメラなどからの入力データのライブ配信モード。このモードでは、resultListener を呼び出して、結果を非同期で受信するリスナーを設定する必要があります。
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
num_hands 手のランドマーク検出機能で検出される手の最大数。 Any integer > 0 1
min_hand_detection_confidence 手の検出が成功と見なされるために必要な、手のひら検出モデルの信頼度の最小スコア。 0.0 - 1.0 0.5
min_hand_presence_confidence 手ランドマーク検出モデルの手の存在スコアの最小信頼度スコア。動画モードとライブ配信モードでは、ハンド ランドマーク モデルの手の存在の信頼スコアがこのしきい値を下回ると、ハンド ランドマークは手のひら検出モデルをトリガーします。それ以外の場合は、軽量の手トラッキング アルゴリズムが、その後のランドマーク検出のために手の位置を決定します。 0.0 - 1.0 0.5
min_tracking_confidence ハンド トラッキングが成功とみなされるための最小信頼スコア。これは、現在のフレームと最後のフレームの手の境界ボックスの IoU しきい値です。手の地面マーカーの動画モードとストリーム モードでは、トラッキングが失敗した場合、手の地面マーカーが手の検出をトリガーします。それ以外の場合、手検出はスキップされます。 0.0 - 1.0 0.5
result_callback ハンド ランドマークがライブ配信モードのときに検出結果を非同期で受信するように結果リスナーを設定します。実行モードが LIVE_STREAM に設定されている場合にのみ適用されます。 なし なし

データの準備

入力を画像ファイルまたは NumPy 配列として準備し、mediapipe.Image オブジェクトに変換します。入力が動画ファイルまたはウェブカメラからのライブ配信の場合は、OpenCV などの外部ライブラリを使用して、入力フレームを numpy 配列として読み込むことができます。

画像

import mediapipe as mp

# Load the input image from an image file.
mp_image = mp.Image.create_from_file('/path/to/image')

# Load the input image from a numpy array.
mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=numpy_image)
    

動画

import mediapipe as mp

# Use OpenCV’s VideoCapture to load the input video.

# Load the frame rate of the video using OpenCV’s CV_CAP_PROP_FPS
# You’ll need it to calculate the timestamp for each frame.

# Loop through each frame in the video using VideoCapture#read()

# Convert the frame received from OpenCV to a MediaPipe’s Image object.
mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=numpy_frame_from_opencv)
    

ライブ配信

import mediapipe as mp

# Use OpenCV’s VideoCapture to start capturing from the webcam.

# Create a loop to read the latest frame from the camera using VideoCapture#read()

# Convert the frame received from OpenCV to a MediaPipe’s Image object.
mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=numpy_frame_from_opencv)
    

タスクを実行する

Hand Landmarker は、detect、detect_for_video、detect_async 関数を使用して推論をトリガーします。手のランドマーク検出の場合、これは入力データの前処理、画像内の手の検出、手のランドマークの検出を伴います。

次のコードは、タスクモデルを使用して処理を実行する方法を示しています。

画像

# Perform hand landmarks detection on the provided single image.
# The hand landmarker must be created with the image mode.
hand_landmarker_result = landmarker.detect(mp_image)
    

動画

# Perform hand landmarks detection on the provided single image.
# The hand landmarker must be created with the video mode.
hand_landmarker_result = landmarker.detect_for_video(mp_image, frame_timestamp_ms)
    

ライブ配信

# Send live image data to perform hand landmarks detection.
# The results are accessible via the `result_callback` provided in
# the `HandLandmarkerOptions` object.
# The hand landmarker must be created with the live stream mode.
landmarker.detect_async(mp_image, frame_timestamp_ms)
    

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

  • 動画モードまたはライブ配信モードで実行する場合は、ハンド ランドマーク タスクに入力フレームのタイムスタンプも指定する必要があります。
  • 画像モデルまたは動画モデルで実行する場合、Hand Landmarker タスクは、入力画像またはフレームの処理が完了するまで現在のスレッドをブロックします。
  • ライブ ストリーム モードで実行している場合、ハンド ランドマーク タスクは現在のスレッドをブロックせず、すぐに戻ります。入力フレームの処理が完了するたびに、検出結果とともに結果リスナーが呼び出されます。Hand Landmarker タスクが別のフレームの処理でビジー状態になっているときに検出関数が呼び出されると、タスクは新しい入力フレームを無視します。

画像に手のマーカーを描画する詳細な例については、コード例をご覧ください。

結果を処理して表示する

Hand Landmarker は、検出実行ごとに Hand Landmarker 結果オブジェクトを生成します。結果のオブジェクトには、画像座標の手のランドマーク、世界座標の手のランドマーク、検出された手の利き手(左手と右手)が含まれます。

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

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

  • 利き手

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

  • ランドマーク

    手には 21 個のランドマークがあり、それぞれ xyz の座標で構成されています。x 座標と y 座標は、それぞれ画像の幅と高さで [0.0, 1.0] に正規化されます。z 座標はランドマークの深さを表します。手首の深さが原点になります。値が小さいほど、ランドマークはカメラに近くなります。z の振幅は、x とほぼ同じスケールを使用します。

  • 世界の名所

    21 個の手のランドマークもワールド座標で表されます。各ランドマークは xyz で構成され、手形の幾何学的中心を原点として、メートル単位の現実世界の 3D 座標を表します。

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)

次の画像は、タスク出力の可視化を示しています。

Hand Landmarker のサンプルコードは、タスクから返された結果を表示する方法を示しています。詳細については、コードサンプルをご覧ください。