Python 適用的手勢辨識指南

MediaPipe 手勢辨識器工作可讓你即時辨識手勢,以及 可提供系統辨識的手部手勢結果和偵測到的手部地標 。下列操作說明說明如何使用手勢辨識器 Python 應用程式

如要查看這項工作的實際運作情形,請前往網頁版 示範 進一步瞭解 請參閱總覽

程式碼範例

手勢辨識器的範例程式碼提供了這項功能的完整實作 執行相關作業這個程式碼可協助您測試這項工作 就是開始打造自己的手勢辨識工具您可以查看、執行 編輯手勢辨識工具範例 程式碼 只要使用網路瀏覽器即可。

如果您要為 Raspberry Pi 實作手勢辨識工具,請參閱 Raspberry Pi 範例 app

設定

本節說明設定開發環境的重要步驟,以及 專門使用手勢辨識工具的程式碼專案如需 設定開發環境以使用 MediaPipe 工作,包括: 平台版本需求,請參閱這份指南 Python

套件

MediaPipe 手勢辨識工具工作需要 mediapipe PyPI 套件。您可以安裝 透過下列指令匯入這些依附元件:

$ python -m pip install mediapipe
敬上

匯入

匯入下列類別,即可存取手勢辨識工具工作函式:

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

型號

MediaPipe 手勢辨識工具工作需要一個與 執行這項工作如要進一步瞭解手勢辨識器可用的已訓練模型,請參閱: 請參閱工作總覽的「模型」一節

選取並下載模型,然後儲存在本機目錄中:

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

在 Model Name 參數中指定模型的路徑,如下所示:

base_options = BaseOptions(model_asset_path=model_path)

建立工作

MediaPipe 手勢辨識工具工作會使用 create_from_options 函式來設定 工作。create_from_options 函式接受設定值 來處理這些動作如要進一步瞭解設定選項,請參閱 設定選項

下列程式碼示範如何建構及設定這項工作。

這些樣本還會顯示圖片的工作建構方式的不同版本, 影片檔案和直播影片串流

圖片

import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
GestureRecognizer = mp.tasks.vision.GestureRecognizer
GestureRecognizerOptions = mp.tasks.vision.GestureRecognizerOptions
VisionRunningMode = mp.tasks.vision.RunningMode

# Create a gesture recognizer instance with the image mode:
options = GestureRecognizerOptions(
    base_options=BaseOptions(model_asset_path='/path/to/model.task'),
    running_mode=VisionRunningMode.IMAGE)
with GestureRecognizer.create_from_options(options) as recognizer:
  # The detector is initialized. Use it here.
  # ...
    

影片

import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
GestureRecognizer = mp.tasks.vision.GestureRecognizer
GestureRecognizerOptions = mp.tasks.vision.GestureRecognizerOptions
VisionRunningMode = mp.tasks.vision.RunningMode

# Create a gesture recognizer instance with the video mode:
options = GestureRecognizerOptions(
    base_options=BaseOptions(model_asset_path='/path/to/model.task'),
    running_mode=VisionRunningMode.VIDEO)
with GestureRecognizer.create_from_options(options) as recognizer:
  # The detector is initialized. Use it here.
  # ...
    

直播

import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
GestureRecognizer = mp.tasks.vision.GestureRecognizer
GestureRecognizerOptions = mp.tasks.vision.GestureRecognizerOptions
GestureRecognizerResult = mp.tasks.vision.GestureRecognizerResult
VisionRunningMode = mp.tasks.vision.RunningMode

# Create a gesture recognizer instance with the live stream mode:
def print_result(result: GestureRecognizerResult, output_image: mp.Image, timestamp_ms: int):
    print('gesture recognition result: {}'.format(result))

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

設定選項

這項工作有下列 Python 應用程式設定選項:

選項名稱 說明 值範圍 預設值
running_mode 設定任務的執行模式。在架構中 模式:

圖片:單一圖片輸入模式。

VIDEO:影片已解碼的影格模式。

LIVE_STREAM:輸入串流模式 擷取的資訊等。在此模式下, resultListener 設定接聽程式來接收結果 以非同步方式載入物件
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
num_hands 可偵測的手部數量上限 GestureRecognizer 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
canned_gestures_classifier_options 罐頭手勢分類器行為的設定選項。罐頭手勢為:["None", "Closed_Fist", "Open_Palm", "Pointing_Up", "Thumb_Down", "Thumb_Up", "Victory", "ILoveYou"]
  • 顯示名稱語言代碼:透過 TFLite 模型中繼資料指定的顯示名稱 (如有) 使用的語言代碼。
  • 結果數量上限:要傳回的分類結果分數上限。如果0,系統會傳回所有可用的結果。
  • 分數門檻:低於這個分數的結果會遭到拒絕。如果設為 0,會傳回所有可用的結果。
  • 類別許可清單:類別名稱的許可清單。如果非空白,系統會篩除不屬於這個集合的類別結果。與拒絕清單互斥。
  • 類別拒絕清單:類別名稱的拒絕清單。如果設為非空白,系統就會篩除這個組合中的類別結果。允許與許可清單互斥,
    • 顯示名稱語言代碼:any string
    • 結果數量上限:any integer
    • 分數門檻:0.0-1.0
    • 類別許可清單:vector of strings
    • 類別拒絕清單:vector of strings
    • 顯示名稱語言代碼:"en"
    • 結果數量上限:-1
    • 分數門檻:0
    • 類別許可清單:空白
    • 類別拒絕清單:空白
    custom_gestures_classifier_options 自訂手勢分類器行為的設定選項。
  • 顯示名稱語言代碼:透過 TFLite 模型中繼資料指定的顯示名稱 (如有) 使用的語言代碼。
  • 結果數量上限:要傳回的分類結果分數上限。如果0,系統會傳回所有可用的結果。
  • 分數門檻:低於這個分數的結果會遭到拒絕。如果設為 0,會傳回所有可用的結果。
  • 類別許可清單:類別名稱的許可清單。如果非空白,系統會篩除不屬於這個集合的類別結果。與拒絕清單互斥。
  • 類別拒絕清單:類別名稱的拒絕清單。如果設為非空白,系統就會篩除這個組合中的類別結果。允許與許可清單互斥,
    • 顯示名稱語言代碼:any string
    • 結果數量上限:any integer
    • 分數門檻:0.0-1.0
    • 類別許可清單:vector of strings
    • 類別拒絕清單:vector of strings
    • 顯示名稱語言代碼:"en"
    • 結果數量上限:-1
    • 分數門檻:0
    • 類別許可清單:空白
    • 類別拒絕清單:空白
    result_callback 設定用來接收分類結果的結果監聽器 以非同步方式觸發手勢辨識功能 只有在執行模式設為「LIVE_STREAM」時才能使用 ResultListener 不適用 不適用

    準備資料

    備妥圖片檔案或 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)
        

    執行工作

    手勢辨識器會使用辨識、Recognize_for_video 和 Recognize_async 函式,用於觸發推論。以手勢辨識來說 預先處理輸入資料, 偵測圖像中的手, 偵測手部 地標和辨識地標的手勢。

    下列程式碼示範如何使用工作模型執行處理程序。

    圖片

    # Perform gesture recognition on the provided single image.
    # The gesture recognizer must be created with the image mode.
    gesture_recognition_result = recognizer.recognize(mp_image)
        

    影片

    # Perform gesture recognition on the provided single image.
    # The gesture recognizer must be created with the video mode.
    gesture_recognition_result = recognizer.recognize_for_video(mp_image, frame_timestamp_ms)
        

    直播

    # Send live image data to perform gesture recognition.
    # The results are accessible via the `result_callback` provided in
    # the `GestureRecognizerOptions` object.
    # The gesture recognizer must be created with the live stream mode.
    recognizer.recognize_async(mp_image, frame_timestamp_ms)
        

    注意事項:

    • 以錄影模式或直播模式執行時,你也必須 提供手勢辨識工具工作,做為輸入影格的時間戳記。
    • 以圖片或影片模型執行時,手勢辨識工具工作會 封鎖目前的執行緒,直到處理完成輸入圖片, 相框。
    • 在直播模式下執行時,手勢辨識工具工作不會封鎖 但會立即傳回這會叫用結果 每次處理完成後,系統會傳回辨識結果 輸入影格如果在手勢辨識器時呼叫辨識函式 工作正忙於處理另一個影格,工作將忽略新的輸入 相框。

    如需對圖片執行手勢辨識工具的完整範例,請參閱程式碼 示例

    處理及顯示結果

    手勢辨識器會為 辨識工作順利進行結果物件包含圖片座標中的手部地標, 世界座標中的手部地標、慣用手(左/右手),以及手部 所偵測到的手語。

    以下範例顯示這項工作的輸出資料範例:

    產生的 GestureRecognizerResult 包含四個元件,而每個元件都是陣列,其中每個元素都包含偵測到單隻手的偵測結果。

    • 慣用手設計

      慣用手代表偵測到的手是左手還是右手。

    • 手勢

      偵測到的手部已辨識出的手勢類別。

    • 地標

      共有 21 個手部地標,每個地標都由 xyz 座標組成。 xy 座標會依照圖片寬度和 z 座標代表地標深度, 手腕的深度就是起點值越小, 地標就是相機鏡頭z 的規模大致與下列指標相同: x

    • 世界著名地標

      世界座標也會顯示 21 個手部地標。每個地標 由 xyz 組成,代表實際的 3D 座標 公尺,將感應器放在手部的幾何中心。

    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)
    

    下圖顯示工作輸出內容的示意圖:

    手勢辨識器程式碼範例示範如何顯示辨識結果 查看工作傳回的結果,請參閱 示例