Przewodnik po wykrywaniu punktów orientacyjnych ustawiania pozycji w Pythonie

Zadanie MediaPipe Pose Landmarker umożliwia wykrywanie punktów orientacyjnych ciała ludzkiego na obrazie lub filmie. Za pomocą tego zadania możesz identyfikować kluczowe części ciała, analizować postawę oraz kategoryzować ruchy. To zadanie korzysta z modeli systemów uczących się, które działają z pojedynczymi obrazami lub filmami. Zadanie wyprowadza punkty orientacyjne postawy ciała w współrzędnych obrazu i w trójwymiarowych współrzędnych świata.

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 usługi Pose Landmarker zawiera kompletną implementację tego zadania w Pythonie. Ten kod pomoże Ci przetestować to zadanie i rozpocząć tworzenie własnego punktowania pozycji. Możesz wyświetlać, uruchamiać i edytować przykładowy kod usługi Pose Landmarker, korzystając tylko z przeglądarki.

Jeśli wdrażasz narzędzie Pose Landmarker na Raspberry Pi, zapoznaj się z przykładową aplikacją na Raspberry Pi.

Konfiguracja

W tej sekcji opisaliśmy kluczowe kroki konfigurowania środowiska programistycznego i projektów kodu w celu używania narzędzia Pose 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 Pose Landmarker wymaga pakietu mediapipe z 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 dotyczącego wykrywania punktów orientacyjnych w postawie, zaimportuj te klasy:

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

Model

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

Wybierz i pobierz model, a potem zapisz go w katalogu lokalnym:

model_path = '/absolute/path/to/pose_landmarker.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 Pose Landmarker służy funkcja create_from_options. Funkcja create_from_options przyjmuje wartości dla opcji konfiguracji. Więcej informacji znajdziesz w opcjach 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
PoseLandmarker = mp.tasks.vision.PoseLandmarker
PoseLandmarkerOptions = mp.tasks.vision.PoseLandmarkerOptions
VisionRunningMode = mp.tasks.vision.RunningMode

options = PoseLandmarkerOptions(
    base_options=BaseOptions(model_asset_path=model_path),
    running_mode=VisionRunningMode.IMAGE)

with PoseLandmarker.create_from_options(options) as landmarker:
  # The landmarker is initialized. Use it here.
  # ...
    

Wideo

import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
PoseLandmarker = mp.tasks.vision.PoseLandmarker
PoseLandmarkerOptions = mp.tasks.vision.PoseLandmarkerOptions
VisionRunningMode = mp.tasks.vision.RunningMode

# Create a pose landmarker instance with the video mode:
options = PoseLandmarkerOptions(
    base_options=BaseOptions(model_asset_path=model_path),
    running_mode=VisionRunningMode.VIDEO)

with PoseLandmarker.create_from_options(options) as landmarker:
  # The landmarker is initialized. Use it here.
  # ...
    

Transmisja na żywo

import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
PoseLandmarker = mp.tasks.vision.PoseLandmarker
PoseLandmarkerOptions = mp.tasks.vision.PoseLandmarkerOptions
PoseLandmarkerResult = mp.tasks.vision.PoseLandmarkerResult
VisionRunningMode = mp.tasks.vision.RunningMode

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

options = PoseLandmarkerOptions(
    base_options=BaseOptions(model_asset_path=model_path),
    running_mode=VisionRunningMode.LIVE_STREAM,
    result_callback=print_result)

with PoseLandmarker.create_from_options(options) as landmarker:
  # The landmarker is initialized. Use it here.
  # ...
    

Pełny przykład tworzenia znacznika orientacyjnego pozy do użycia z obrazem znajdziesz w przykładzie kodu.

Opcje konfiguracji

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

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

OBRAZ: tryb dla pojedynczych obrazów wejściowych.

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_poses Maksymalna liczba poz, które może wykryć Landmarker poz. Integer > 0 1
min_pose_detection_confidence Minimalna wartość ufności wykrywania pozycji, która jest uznawana za prawidłową. Float [0.0,1.0] 0.5
min_pose_presence_confidence Minimalny wynik ufności obecności pozycji w wykrywaniu punktów orientacyjnych postawy. Float [0.0,1.0] 0.5
min_tracking_confidence Minimalny wynik ufności śledzenia pozycji ciała, aby uznać go za udany. Float [0.0,1.0] 0.5
output_segmentation_masks Określa, czy narzędzie Pose Landmarker wygeneruje maskę segmentacji dla wykrytej postawy. Boolean False
result_callback Ustawia odbiornik wyników tak, aby asynchronicznie otrzymywał wyniki wyszukiwania punktów orientacyjnych, gdy punkt orientacyjny w ramach funkcji Pose Landmarker jest w trybie transmisji na żywo. Można go używać tylko wtedy, gdy tryb działania ma wartość LIVE_STREAM. ResultListener N/A

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 Pose Landmarker używa funkcji detect, detect_for_videodetect_async do wywoływania wniosków. W przypadku oznaczania punktów orientacyjnych pozy obejmuje to wstępną obróbkę danych wejściowych i wykrywanie pozy na obrazie.

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

Obraz

# Perform pose landmarking on the provided single image.
# The pose landmarker must be created with the image mode.
pose_landmarker_result = landmarker.detect(mp_image)
    

Wideo

# Perform pose landmarking on the provided single image.
# The pose landmarker must be created with the video mode.
pose_landmarker_result = landmarker.detect_for_video(mp_image, frame_timestamp_ms)
    

Transmisja na żywo

# Send live image data to perform pose landmarking.
# The results are accessible via the `result_callback` provided in
# the `PoseLandmarkerOptions` object.
# The pose 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 podaj zadaniu wyznaczania punktów orientacyjnych w pozie sygnaturę czasową ramki wejściowej.
  • Gdy jest wykonywane w ramach modelu obrazu lub filmu, zadanie wykrywania punktów orientacyjnych pozy blokuje bieżący wątek, dopóki nie zakończy przetwarzania wejściowego obrazu lub klatki.
  • W trybie transmisji na żywo zadanie dotyczące wyznaczenia punktów orientacyjnych pozycji powraca natychmiast i nie blokuje bieżącego wątku. Za każdym razem, gdy skończy przetwarzać daną klatkę wejściową, wywoła komponent odbiorczy z wynikiem wykrywania. Jeśli funkcja wykrywania zostanie wywołana, gdy zadanie dotyczące punktowania pozycji jest zajęte przetwarzaniem innego kadru, zadanie zignoruje nowy klatka wejściowa.

Pełny przykład użycia narzędzia do wykrywania punktów orientacyjnych na potrzeby rozpoznawania pozy na obrazie znajdziesz w przykładzie kodu.

Obsługa i wyświetlanie wyników

Funkcja Pose Landmarker zwraca obiekt poseLandmarkerResult dla każdego przebiegu wykrywania. Obiekt wyniku zawiera współrzędne każdego punktu orientacyjnego pozy.

Poniżej znajdziesz przykład danych wyjściowych z tego zadania:

PoseLandmarkerResult:
  Landmarks:
    Landmark #0:
      x            : 0.638852
      y            : 0.671197
      z            : 0.129959
      visibility   : 0.9999997615814209
      presence     : 0.9999984502792358
    Landmark #1:
      x            : 0.634599
      y            : 0.536441
      z            : -0.06984
      visibility   : 0.999909
      presence     : 0.999958
    ... (33 landmarks per pose)
  WorldLandmarks:
    Landmark #0:
      x            : 0.067485
      y            : 0.031084
      z            : 0.055223
      visibility   : 0.9999997615814209
      presence     : 0.9999984502792358
    Landmark #1:
      x            : 0.063209
      y            : -0.00382
      z            : 0.020920
      visibility   : 0.999976
      presence     : 0.999998
    ... (33 world landmarks per pose)
  SegmentationMasks:
    ... (pictured below)

Dane wyjściowe zawierają zarówno znormalizowane współrzędne (Landmarks), jak i współrzędne globalne (WorldLandmarks) dla każdego punktu orientacyjnego.

Dane wyjściowe zawierają te sformatowane współrzędne (Landmarks):

  • xy: współrzędne punktu orientacyjnego znormalizowane w zakresie od 0,0 do 1,0 przez szerokość (x) i wysokość (y) obrazu.

  • z: głębokość punktu orientacyjnego, w której głębokość w środku bioder jest traktowana jako punkt początkowy. Im mniejsza wartość, tym obiekt jest bliżej kamery. Wielkość z używa mniej więcej tej samej skali co x.

  • visibility: prawdopodobieństwo, że punkt orientacyjny jest widoczny na zdjęciu.

Dane wyjściowe zawierają te współrzędne świata (WorldLandmarks):

  • x, yz: rzeczywiste współrzędne 3D w metrach, z środkiem bioder jako punktem początkowym.

  • visibility: prawdopodobieństwo, że punkt orientacyjny jest widoczny na zdjęciu.

Na ilustracji poniżej widać wynik wykonania zadania:

Kobieta w położeniu medytacji. Jej pozę wyróżnia szkielet, który wskazuje położenie kończyn i tułowia

Opcjonalna maska podziału na segmenty reprezentuje prawdopodobieństwo, że dany piksel należy do wykrytej osoby. Następujący obraz przedstawia maskę podziału na segmenty danych wyjściowych zadania:

Maska segmentacji poprzedniego obrazu, która wyznacza kształt kobiety

Przykładowy kod usługi Pose Landmarker pokazuje, jak wyświetlać wyniki zwrócone przez zadanie. Szczegółowe informacje znajdziesz w przykładowym kodzie.