Przewodnik dotyczący wykrywania punktów orientacyjnych dłoni w Pythonie

Zadanie MediaPipe Hand Landmarker umożliwia wykrywanie punktów orientacyjnych dłoni na obrazie. Z tych instrukcji dowiesz się, jak korzystać z Hand Landmarker w Pythonie. Przykładowy kod opisany w tych instrukcjach jest dostępny na GitHub.

Więcej informacji o możliwościach, modelach i opcjach konfiguracji związanych z tym zadaniem znajdziesz w sekcji Omówienie.

Przykładowy kod

Przykładowy kod dla Hand Landmarker zawiera kompletną implementację tego zadania w Pythonie. Ten kod pomoże Ci przetestować to zadanie i rozpocząć tworzenie własnego wykrywacza punktów orientacyjnych dłoni. Przykładowy kod Hand Landmarker możesz wyświetlać, uruchamiać i edytować za pomocą przeglądarki.

Jeśli wdrażasz punkt orientacyjny Raspberry Pi, zapoznaj się z przykładową aplikacją Raspberry Pi.

Konfiguracja

W tej sekcji opisaliśmy kluczowe kroki konfigurowania środowiska programistycznego i projektów kodu w celu używania narzędzia Hand Landmarker. Ogólne informacje o konfigurowaniu środowiska programistycznego na potrzeby korzystania z zadań MediaPipe, w tym wymagania dotyczące wersji platformy, znajdziesz w przewodniku po konfigurowaniu Pythona.

Pakiety

Zadanie MediaPipe Hand Landmarker wymaga pakietu mediapipe PyPI. Te zależności możesz zainstalować i importować za pomocą:

$ python -m pip install mediapipe

Importy

Aby uzyskać dostęp do funkcji zadania Hand Landmarker, zaimportuj te klasy:

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

Model

Zadanie MediaPipe Hand Pointer wymaga wytrenowanego modelu, który jest zgodny z tym zadaniem. Więcej informacji o dostępnych wytrenowanych modelach usługi Hand Landmarker znajdziesz w sekcji Modele w omówieniu zadania.

Wybierz i pobierz model, a następnie zapisz go w katalogu lokalnym:

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

Aby określić ścieżkę do modelu, użyj parametru BaseOptions obiektu model_asset_path. Przykład kodu znajdziesz w następnej sekcji.

Tworzenie zadania

Do konfigurowania zadania MediaPipe Hand Landmarker służy funkcja create_from_options. Funkcja create_from_options przyjmuje wartości opcji konfiguracji do obsługi. Więcej informacji o opcjach konfiguracji znajdziesz w artykule Opcje konfiguracji.

Poniższy kod pokazuje, jak skompilować i skonfigurować to zadanie.

Przykłady te pokazują też różne sposoby tworzenia zadań dotyczących obrazów, plików wideo i transmisji na żywo.

Obraz

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.
  # ...
    

Wideo

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.
  # ...
    

Transmisja na żywo

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.
  # ...
    

Pełny przykład tworzenia narzędzia Hand Landmarker do użycia z obrazem znajdziesz w przykładzie kodu.

Opcje konfiguracji

W tym zadaniu dostępne są te opcje konfiguracji aplikacji Python:

Nazwa opcji Opis Zakres wartości Wartość domyślna
running_mode Ustawia tryb działania zadania. Dostępne są 3 tryby:

IMAGE: tryb używany do przesyłania pojedynczego obrazu.

FILM: tryb dekodowanych klatek filmu.

LIVE_STREAM: tryb transmisji na żywo danych wejściowych, takich jak dane z kamery. W tym trybie należy wywołać metodę resultListener, aby skonfigurować odbiornik, który będzie asynchronicznie odbierał wyniki.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
num_hands Maksymalna liczba rąk wykrytych przez wykrywacz punktów orientacyjnych „Dłoń”. Any integer > 0 1
min_hand_detection_confidence Minimalny wynik ufności wykrywania dłoni, który jest uznawany za udany w przypadku modelu wykrywania dłoni. 0.0 - 1.0 0.5
min_hand_presence_confidence Minimalny wskaźnik ufności dla wyniku obecności dłoni w modelu wykrywania punktów orientacyjnych dłoni. W trybie wideo i w trybie transmisji na żywo, jeśli wskaźnik ufności obecności ręki z modelu punktów orientacyjnych ręki jest poniżej tego progu, narzędzie Hand Landmarker uruchamia model wykrywania dłoni. W przeciwnym razie lekki algorytm śledzenia dłoni określa położenie dłoni na potrzeby wykrywania kolejnych punktów orientacyjnych. 0.0 - 1.0 0.5
min_tracking_confidence Minimalny wskaźnik ufności, dla którego śledzenie dłoni można uznać za skuteczne. To próg współczynnika podobieństwa ramki ograniczającej między dłońmi w bieżącej i ostatniej ramie. W trybie wideo i trybie strumieniowania w Hand Landmarker, jeśli śledzenie się nie powiedzie, Hand Landmarker uruchamia wykrywanie dłoni. W przeciwnym razie pomija wykrywanie rąk. 0.0 - 1.0 0.5
result_callback Konfiguruje detektor wyników tak, aby asynchronicznie otrzymywał wyniki wykrywania, gdy punkt orientacyjny dłoni jest w trybie transmisji na żywo. Ma zastosowanie tylko wtedy, gdy tryb działania jest ustawiony na LIVE_STREAM Nie dotyczy Nie dotyczy

Przygotuj dane

Przygotuj dane wejściowe jako plik obrazu lub tablicę numpy, a następnie przekształć je w obiekt mediapipe.Image. Jeśli dane wejściowe to plik wideo lub transmisja na żywo z kamery internetowej, możesz użyć biblioteki zewnętrznej, takiej jak OpenCV, aby załadować ramki wejściowe jako tablice numpy.

Obraz

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)
    

Wideo

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)
    

Transmisja na żywo

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)
    

Uruchamianie zadania

Funkcja Hand Landmarker używa funkcji detect, detect_for_video i detect_async do wywoływania wniosków. W przypadku wykrywania punktów orientacyjnych dłoni obejmuje to wstępną obróbkę danych wejściowych, wykrywanie dłoni na obrazie oraz wykrywanie punktów orientacyjnych dłoni.

Poniższy kod pokazuje, jak wykonać przetwarzanie za pomocą modelu zadania.

Obraz

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

Wideo

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

Transmisja na żywo

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

Pamiętaj:

  • W trybie wideo lub transmisji na żywo musisz też przekazać zadaniu Hand Landmarker sygnaturę czasową ramki wejściowej.
  • W przypadku działania na obrazie lub w modelu wideo zadanie „Ręczny punkt orientacyjny” zablokuje bieżący wątek, dopóki nie zakończy przetwarzania obrazu wejściowego lub klatki.
  • W trybie transmisji na żywo zadanie Hand Landmarker nie blokuje bieżącego wątku, ale zwraca się natychmiast. Za każdym razem, gdy skończy przetwarzać ramkę wejściową, wywoła swojego słuchacza z wynikiem wykrywania. Jeśli funkcja wykrywania zostanie wywołana, gdy zadanie Hand Landmarker jest zajęte przetwarzaniem innego kadru, zadanie zignoruje nowy klatka wejściowa.

Pełny przykład użycia modułu Hand Landmarker na obrazie znajdziesz w przykładowym kodzie.

Obsługa i wyświetlanie wyników

W przypadku każdego uruchomienia wykrywania wygeneruje obiekt wyników wykrywania dłoni. Obiekt wyniku zawiera punkty odniesienia dłoni w współrzędnych obrazu, punkty odniesienia dłoni w współrzędnych globalnych oraz rękę(lewą lub prawą) wykrytej dłoni.

Poniżej znajdziesz przykładowe dane wyjściowe tego zadania:

Dane wyjściowe HandLandmarkerResult zawierają 3 komponenty. Każdy komponent to tablica, w której każdy element zawiera następujące wyniki dla 1 wykrytej ręki:

  • Ręka dominująca

    Ręka określa, czy wykryta ręka jest lewą czy prawą.

  • Punkty orientacyjne

    Jest 21 punktów orientacyjnych dłoni, z których każdy składa się ze współrzędnych x, y i z. współrzędne xy są normalizowane do zakresu [0,0, 1,0] odpowiednio według szerokości i wysokości obrazu. Współrzędna z reprezentuje głębokość punktu orientacyjnego, przy czym źródłem jest głębia na nadgarstku. Im mniejsza wartość, tym obiektyw jest bliżej zabytku. Wielkość z używa mniej więcej tej samej skali co x.

  • Punkty orientacyjne na świecie

    21 punktów orientacyjnych dłoni jest też przedstawionych w współrzędnych światowych. Każdy punkt orientacyjny składa się z punktów x, y i z, które reprezentują rzeczywiste współrzędne 3D w metrach, a początk w środku geometrycznym dłoni.

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)

Na ilustracji poniżej widać wizualizację wyniku zadania:

Przykładowy kod punktu orientacyjnego Handel pokazuje, jak wyświetlić wyniki zwrócone z zadania. Szczegóły znajdziesz w przykładowym kodzie.