Zadanie MediaPipe Pose Markuper umożliwia wykrywanie punktów orientacyjnych ludzkich ciał na zdjęciach lub film. Możesz użyć tego zadania, aby zidentyfikować kluczowe lokalizacje ciała, przeanalizować postawę i kategoryzować ruchy. W tym zadaniu używane są modele systemów uczących się, które z pojedynczymi obrazami lub filmami. Zadanie generuje na obrazie punkty orientacyjne w pozycji ciała i trójwymiarowych współrzędnych świata.
Przykładowy kod opisany w tych instrukcjach jest dostępny na GitHub Więcej informacji o funkcjach, modelach i opcjach konfiguracji zapoznaj się z Przeglądem.
Przykładowy kod
Przykładowy kod MediaPipe Tasks to prosta implementacja punktu orientacyjnego umiejscowienia na Androida. W tym przykładzie użyliśmy aparatu w fizycznym urządzeniu z Androidem, Wykrywaj pozy w ciągłym strumieniu wideo. Aplikacja może też wykrywać pozy w obrazów i filmów z galerii urządzenia.
Możesz użyć tej aplikacji jako punktu wyjścia dla własnej aplikacji na Androida lub odnieść się do niej podczas modyfikowania istniejącej aplikacji. Przykładowy kod punktu orientacyjnego położenia jest hostowany GitHub
Pobieranie kodu
Poniżej znajdziesz instrukcje tworzenia lokalnej kopii przykładu. za pomocą narzędzia wiersza poleceń git.
Aby pobrać przykładowy kod:
- Sklonuj repozytorium git za pomocą tego polecenia:
git clone https://github.com/google-ai-edge/mediapipe-samples
- Opcjonalnie możesz skonfigurować instancję git tak, aby wykorzystywała rozproszony proces płatności, aby
tylko pliki przykładowej aplikacji Pose Notebooker:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/pose_landmarker/android
Po utworzeniu lokalnej wersji przykładowego kodu możesz zaimportować projekt w Android Studio i uruchom aplikację. Odpowiednie instrukcje znajdziesz w Przewodniku po konfiguracji na urządzeniu z Androidem.
Kluczowe elementy
Te pliki zawierają kluczowy kod tego przykładowego punktu orientacyjnego położenia aplikacja:
- PoseLandmarkerHelper.kt – inicjuje punkt orientacyjny ułożenia oraz obsługuje model i przekazuje do niego dostęp. wyboru.
- CameraFragment.kt – obsługuje aparat urządzenia i przetwarza dane wejściowe obrazu i filmu.
- GalleryFragment.kt – wchodzi w interakcję z parametrem
OverlayView
, aby wyświetlić obraz wyjściowy lub film. - OverlayView.kt – implementuje wyświetlanie obrazu wykrytego umiejscowienia.
Konfiguracja
W tej sekcji opisujemy najważniejsze czynności związane z konfigurowaniem środowiska programistycznego oraz w projektach kodu do użycia punktów orientacyjnych. Ogólne informacje na temat: skonfigurować środowisko programistyczne do korzystania z zadań MediaPipe, w tym wymagań wersji platformy znajdziesz w przewodniku konfiguracji dla na urządzeniu z Androidem.
Zależności
Zadanie wyznaczania pozycji korzysta z biblioteki com.google.mediapipe:tasks-vision
. Dodaj
tę zależność od pliku build.gradle
aplikacji na Androida:
dependencies {
implementation 'com.google.mediapipe:tasks-vision:latest.release'
}
Model
Zadanie MediaPipe Pose Markuper wymaga wytrenowanego pakietu modeli zgodnego z w tym zadaniu. Aby uzyskać więcej informacji o dostępnych wytrenowanych modelach z punktu wyznaczania pozycji, zapoznaj się z omówieniem zadania sekcją Modele.
Wybierz i pobierz model oraz zapisz go w katalogu projektu:
<dev-project-root>/src/main/assets
Określ ścieżkę modelu w parametrze ModelAssetPath
. W
przykładowy kod, model jest zdefiniowany w
PoseLandmarkerHelper.kt
plik:
val modelName = "pose_landmarker_lite.task"
baseOptionsBuilder.setModelAssetPath(modelName)
Tworzenie zadania
Zadanie MediaPipe Pose Notebooker używa funkcji createFromOptions()
do skonfigurowania
zadanie. Funkcja createFromOptions()
akceptuje wartości konfiguracji
. Więcej informacji o opcjach konfiguracji znajdziesz w sekcji Konfiguracja
.
Punkt orientacyjny pozycji obsługuje następujące typy danych wejściowych: zdjęcia, filmy pliki i transmisje wideo na żywo. Musisz określić tryb działania odpowiadający typowi danych wejściowych podczas tworzenia zadania. Wybierz kartę dla typu danych wejściowych, aby zobaczyć, jak utworzyć zadanie.
Obraz
val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(modelName) val baseOptions = baseOptionBuilder.build() val optionsBuilder = poseLandmarker.poseLandmarkerOptions.builder() .setBaseOptions(baseOptionsBuilder.build()) .setMinPoseDetectionConfidence(minPoseDetectionConfidence) .setMinTrackingConfidence(minPoseTrackingConfidence) .setMinPosePresenceConfidence(minposePresenceConfidence) .setNumPoses(maxNumPoses) .setRunningMode(RunningMode.IMAGE) val options = optionsBuilder.build() poseLandmarker = poseLandmarker.createFromOptions(context, options)
Wideo
val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(modelName) val baseOptions = baseOptionBuilder.build() val optionsBuilder = poseLandmarker.poseLandmarkerOptions.builder() .setBaseOptions(baseOptionsBuilder.build()) .setMinPoseDetectionConfidence(minPoseDetectionConfidence) .setMinTrackingConfidence(minPoseTrackingConfidence) .setMinPosePresenceConfidence(minposePresenceConfidence) .setNumPoses(maxNumPoses) .setRunningMode(RunningMode.VIDEO) val options = optionsBuilder.build() poseLandmarker = poseLandmarker.createFromOptions(context, options)
Transmisja na żywo
val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(modelName) val baseOptions = baseOptionBuilder.build() val optionsBuilder = poseLandmarker.poseLandmarkerOptions.builder() .setBaseOptions(baseOptionsBuilder.build()) .setMinPoseDetectionConfidence(minPoseDetectionConfidence) .setMinTrackingConfidence(minPoseTrackingConfidence) .setMinPosePresenceConfidence(minposePresenceConfidence) .setNumPoses(maxNumPoses) .setResultListener(this::returnLivestreamResult) .setErrorListener(this::returnLivestreamError) .setRunningMode(RunningMode.LIVE_STREAM) val options = optionsBuilder.build() poseLandmarker = poseLandmarker.createFromOptions(context, options)
Przykładowa implementacja kodu punktu orientacyjnego Pose Notebooker pozwala użytkownikowi przełączać się między
i przetwarzania danych. Takie podejście sprawia, że kod tworzenia zadań jest bardziej skomplikowany,
może nie być odpowiednia w Twoim przypadku użycia. Możesz zobaczyć ten kod w
setupPoseLandmarker()
w
PoseLandmarkerHelper.kt
.
.
Opcje konfiguracji
To zadanie zawiera te opcje konfiguracji aplikacji na Androida:
Nazwa opcji | Opis | Zakres wartości | Wartość domyślna |
---|---|---|---|
runningMode |
Ustawia tryb działania zadania. Są trzy
tryby: IMAGE: tryb wprowadzania pojedynczego obrazu. WIDEO: tryb zdekodowanych klatek filmu. LIVE_STREAM: tryb transmisji danych wejściowych na przykład z kamery. W tym trybie detektor wyników musi mieć wartość wywołano, aby skonfigurować detektor i otrzymywać wyniki asynchronicznie. |
{IMAGE, VIDEO, LIVE_STREAM } |
IMAGE |
numposes |
Maksymalna liczba pozycji, które może wykryć Punkt orientacyjny. | Integer > 0 |
1 |
minPoseDetectionConfidence |
Minimalny wskaźnik ufności, z którego ustala się pozycję została uznana za udaną. | Float [0.0,1.0] |
0.5 |
minPosePresenceConfidence |
Minimalny wskaźnik ufności obecności pozycji podczas wykrywania punktów orientacyjnych. | Float [0.0,1.0] |
0.5 |
minTrackingConfidence |
Minimalny wynik ufności dla śledzenia pozycji można uznać za udany. | Float [0.0,1.0] |
0.5 |
outputSegmentationMasks |
Określa, czy punkt orientacyjny położenia wyświetla maskę segmentacji dla wykrytego w pozycji. | Boolean |
False |
resultListener |
Konfiguruje detektor wyników tak, aby otrzymywał wyniki z punktu orientacyjnego
asynchronicznie wtedy, gdy Pose Notebooker jest w trybie transmisji na żywo.
Tej opcji można używać tylko wtedy, gdy tryb działania jest ustawiony na LIVE_STREAM |
ResultListener |
N/A |
errorListener |
Ustawia opcjonalny detektor błędów. | ErrorListener |
N/A |
Przygotuj dane
Pose Pointer obsługuje zdjęcia, pliki wideo i strumieni wideo na żywo. Zadanie obsługuje wstępne przetwarzanie danych wejściowych, w tym zmianę rozmiaru, obrót i wartość ich normalizację.
Ten kod pokazuje, jak przekazywać dane do przetworzenia. Te przykłady zawierają szczegółowe instrukcje postępowania z danymi z obrazów, plików wideo i transmisji na żywo strumienie wideo.
Obraz
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()
Wideo
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()
Transmisja na żywo
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()
W przykładowym kodzie położenia punktu orientacyjnego przygotowywanie danych odbywa się w instrukcji
PoseLandmarkerHelper.kt
.
Uruchamianie zadania
W zależności od typu danych, z którymi pracujesz, skorzystaj z
poseLandmarker.detect...()
, która jest specyficzna dla tego typu danych. Używaj
detect()
– pojedyncze zdjęcia, detectForVideo()
– klatki w plikach wideo,
i detectAsync()
w przypadku strumieni wideo. Jeśli wykonujesz wykrywanie na
wideo, pamiętaj, aby uruchomić wykrywanie w oddzielnym wątku, aby uniknąć
blokując wątek interpunkcji przez użytkownika.
Poniższe przykładowe fragmenty kodu pokazują proste przykłady sposobu uruchamiania punktu orientacyjnego położenia w różnych trybach danych:
Obraz
val result = poseLandmarker.detect(mpImage)
Wideo
val timestampMs = i * inferenceIntervalMs poseLandmarker.detectForVideo(mpImage, timestampMs) .let { detectionResult -> resultList.add(detectionResult) }
Transmisja na żywo
val mpImage = BitmapImageBuilder(rotatedBitmap).build() val frameTime = SystemClock.uptimeMillis() poseLandmarker.detectAsync(mpImage, frameTime)
Pamiętaj:
- Korzystając z trybu wideo lub transmisji na żywo, musisz podać: sygnatura czasowa klatki wejściowej do zadania Pose Pointer.
- Podczas pracy w trybie obrazu lub wideo zadanie Pose Markuper blokuje w bieżącym wątku aż do zakończenia przetwarzania obrazu lub ramki wejściowej. Do unikaj blokowania interpunkcji przez użytkownika, wykonywanie przetwarzania w tle w wątku.
- W trybie transmisji na żywo zadanie Pose Latitudeer powraca od razu i nie zablokuje bieżącego wątku. Wywoła wynik detektor z wynikiem wykrywania po każdym zakończeniu przetwarzania ramki wejściowej.
W przykładowym kodzie punktu orientacyjnego Pozycja: detect
, detectForVideo
i
Funkcje detectAsync
są zdefiniowane w sekcji
PoseLandmarkerHelper.kt
.
Obsługa i wyświetlanie wyników
Punkt orientacyjny pozycji zwraca obiekt poseLandmarkerResult
przy każdym wykryciu wykrycia
bieganie. Obiekt wynikowy zawiera współrzędne każdego punktu orientacyjnego pozycji.
Poniżej znajdziesz przykładowe dane wyjściowe 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 świat
(WorldLandmarks
) każdego punktu orientacyjnego.
Dane wyjściowe zawierają następujące znormalizowane współrzędne (Landmarks
):
x
iy
: współrzędne punktu orientacyjnego znormalizowane między 0,0 a 1,0 przez szerokość (x
) i wysokość (y
) obrazu.z
: głębokość punktu orientacyjnego, której głębia znajduje się w połowie bioder pochodzeniu danych. Im mniejsza wartość, tym punkt orientacyjny jest bliżej kamery. magnituda wielkości z używa mniej więcej takiej samej skali jak funkcjax
.visibility
: prawdopodobieństwo, że punkt orientacyjny jest widoczny na zdjęciu.
Dane wyjściowe zawierają następujące współrzędne świata (WorldLandmarks
):
x
,y
iz
: rzeczywiste, trójwymiarowe współrzędne w metrach, punktu środkowego bioder jako punktu początkowego.visibility
: prawdopodobieństwo, że punkt orientacyjny jest widoczny na zdjęciu.
Ten obraz przedstawia wizualizację danych wyjściowych zadania:
Opcjonalna maska segmentacji odpowiada prawdopodobieństwu przynależności każdego piksela wykrytej osobie. Na tej ilustracji widać maskę segmentacji wynik zadania:
Przykładowy kod elementu orientacyjnego pozycji pokazuje, jak wyświetlić zwrócone wyniki
zobaczysz
OverlayView
klasy, by dowiedzieć się więcej.