Zadanie MediaPipe Ręka umożliwia wykrywanie punktów orientacyjnych rąk na zdjęciu. Te instrukcje pokazują, jak korzystać z rękiego punktu orientacyjnego w aplikacjach na Androida. 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 na Androida. W tym przykładzie użyliśmy aparatu w fizycznym urządzeniu z Androidem, stale wykrywają punkty orientacyjne z ręką, a także wykorzystywać zdjęcia i filmy do statycznego wykrywania punktów orientacyjnych.
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 Ręka jest hostowany na 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,
masz więc tylko pliki przykładowej aplikacji Hand odsyłacz:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/hand_landmarker/android
Po utworzeniu lokalnej wersji przykładowego kodu możesz zaimportować projekt w Android Studio i uruchom aplikację. Instrukcje znajdziesz w Przewodnik po konfiguracji na Androida
Kluczowe elementy
Poniższe pliki zawierają kluczowy kod tego punktu orientacyjnego przykładowa aplikacja do wykrywania:
- HandLandmarkerHelper.kt – Inicjuje wykrywanie punktów orientacyjnych rąk i obsługuje model oraz przedstawiciela wyboru.
- MainActivity.kt –
Implementuje aplikację, w tym wywołuje funkcję
HandLandmarkerHelper
.
Konfiguracja
W tej sekcji opisujemy najważniejsze czynności związane z konfigurowaniem środowiska programistycznego oraz w projektach kodu wyłącznie z zastosowaniem punktów orientacyjnych handel. Ogólne informacje na temat: skonfigurować środowisko programistyczne do korzystania z zadań MediaPipe, w tym wymagań wersji platformy, patrz Przewodnik po konfiguracji na Androida
Zależności
Zadanie wyznaczania punktów orientacyjnych korzysta z punktu com.google.mediapipe:tasks-vision
bibliotece. Dodaj tę zależność do pliku build.gradle
aplikacji na Androida:
dependencies {
implementation 'com.google.mediapipe:tasks-vision:latest.release'
}
Model
Zadanie MediaPipe Hand Markuper wymaga wytrenowanego pakietu modeli zgodnego z w tym zadaniu. Aby uzyskać więcej informacji na temat dostępnych wytrenowanych modeli dla punktu orientacyjnego w ręku, 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 HandLandmarkerHelper.kt
plik:
baseOptionBuilder.setModelAssetPath(MP_HAND_LANDMARKER_TASK)
Tworzenie zadania
Zadanie MediaPipe Hand Pointer używa funkcji createFromOptions()
do konfigurowania
zadanie. Funkcja createFromOptions()
akceptuje wartości konfiguracji
. Więcej informacji o opcjach konfiguracji znajdziesz w artykule
Opcje konfiguracji:
Ręczny punkt orientacyjny obsługuje 3 typy danych wejściowych: obrazy, pliki wideo transmisji na żywo. Musisz określić tryb działania odpowiadający Twojej typu danych wejściowych podczas tworzenia zadania. Wybierz kartę odpowiadającą typu danych wejściowych, aby zobaczyć, jak utworzyć zadanie i uruchomić wnioskowanie.
Obraz
val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_HAND_LANDMARKER_TASK) val baseOptions = baseOptionBuilder.build() val optionsBuilder = HandLandmarker.HandLandmarkerOptions.builder() .setBaseOptions(baseOptions) .setMinHandDetectionConfidence(minHandDetectionConfidence) .setMinTrackingConfidence(minHandTrackingConfidence) .setMinHandPresenceConfidence(minHandPresenceConfidence) .setNumHands(maxNumHands) .setRunningMode(RunningMode.IMAGE) val options = optionsBuilder.build() handLandmarker = HandLandmarker.createFromOptions(context, options)
Wideo
val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_HAND_LANDMARKER_TASK) val baseOptions = baseOptionBuilder.build() val optionsBuilder = HandLandmarker.HandLandmarkerOptions.builder() .setBaseOptions(baseOptions) .setMinHandDetectionConfidence(minHandDetectionConfidence) .setMinTrackingConfidence(minHandTrackingConfidence) .setMinHandPresenceConfidence(minHandPresenceConfidence) .setNumHands(maxNumHands) .setRunningMode(RunningMode.VIDEO) val options = optionsBuilder.build() handLandmarker = HandLandmarker.createFromOptions(context, options)
Transmisja na żywo
val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_HAND_LANDMARKER_TASK) val baseOptions = baseOptionBuilder.build() val optionsBuilder = HandLandmarker.HandLandmarkerOptions.builder() .setBaseOptions(baseOptions) .setMinHandDetectionConfidence(minHandDetectionConfidence) .setMinTrackingConfidence(minHandTrackingConfidence) .setMinHandPresenceConfidence(minHandPresenceConfidence) .setNumHands(maxNumHands) .setResultListener(this::returnLivestreamResult) .setErrorListener(this::returnLivestreamError) .setRunningMode(RunningMode.VIDEO) val options = optionsBuilder.build() handLandmarker = HandLandmarker.createFromOptions(context, options)
Przykładowa implementacja kodu punktu orientacyjnego Ręka 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
setupHandLandmarker()
w
HandLandmarkerHelper.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 |
numHands |
Maksymalna liczba rąk wykrytych przez wykrywacz punktów orientacyjnych „Dłoń”. | Any integer > 0 |
1 |
minHandDetectionConfidence |
Minimalny wskaźnik ufności, jaki musi osiągnąć wykrywanie ręki uznane za udane w modelu wykrywania dłoni. | 0.0 - 1.0 |
0.5 |
minHandPresenceConfidence |
Minimalny wskaźnik ufności dla wyniku obecności dłoni na ręce model wykrywania punktów orientacyjnych. W trybie wideo i transmisji na żywo jeśli wskaźnik ufności obecności dłoni z modelu punktu orientacyjnego dłoni jest poniżej po osiągnięciu tego progu, aplikacja Ręka odwołuje się do modelu wykrywania dłoni. W przeciwnym razie łatwy algorytm śledzenia dłoni określa lokalizację ręce do późniejszego wykrywania punktu orientacyjnego. | 0.0 - 1.0 |
0.5 |
minTrackingConfidence |
Minimalny wskaźnik ufności, z którego można korzystać podczas śledzenia dłoni udało się. Jest to wartość progowa współczynnika podobieństwa między dłońmi bieżącej i ostatniej klatki. W trybie wideo i w trybie strumienia Ręczny punkt orientacyjny, jeśli śledzenie nie powiedzie się, aktywuje punkt orientacyjny ręcznie wykrywaniem zagrożeń. W przeciwnym razie pomija wykrywanie rąk. | 0.0 - 1.0 |
0.5 |
resultListener |
Konfiguruje detektor wyników, który otrzymuje wyniki wykrywania
asynchronicznie, 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 |
errorListener |
Ustawia opcjonalny detektor błędów. | Nie dotyczy | Nie dotyczy |
Przygotuj dane
Hand Pointer obsługuje zdjęcia, pliki wideo i transmisje 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. Tezy 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ładowy kod punktu orientacyjnego rękodzieła. Przygotowanie danych odbywa się w
HandLandmarkerHelper.kt
.
Uruchamianie zadania
W zależności od typu danych, z którymi pracujesz, skorzystaj z
HandLandmarker.detect...()
, która jest specyficzna dla tego typu danych. Używaj
detect()
w przypadku pojedynczych zdjęć,
detectForVideo()
w przypadku klatek w plikach wideo oraz
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 interfejsu użytkownika.
Poniższe przykłady kodu pokazują proste przykłady uruchamiania punktu orientacyjnego Ręka w różnych trybach danych:
Obraz
val result = handLandmarker?.detect(mpImage)
Wideo
val timestampMs = i * inferenceIntervalMs handLandmarker?.detectForVideo(mpImage, timestampMs) ?.let { detectionResult -> resultList.add(detectionResult) }
Transmisja na żywo
val mpImage = BitmapImageBuilder(rotatedBitmap).build() val frameTime = SystemClock.uptimeMillis() handLandmarker?.detectAsync(mpImage, frameTime)
Pamiętaj:
- Gdy pracujesz w trybie wideo lub w trybie transmisji na żywo, musisz też podać sygnaturę czasową ramki wejściowej zadania punktu orientacyjnego
- Podczas pracy w trybie obrazu lub wideo zadanie wskażnik ręcznie zablokuj bieżący wątek do czasu zakończenia przetwarzania obrazu wejściowego lub ramki. Aby uniknąć blokowania interfejsu użytkownika, wykonaj przetwarzanie w w wątku w tle.
- W trybie transmisji na żywo zadanie punktu orientacyjnego Ręka nie blokuje w bieżącym wątku, ale wraca natychmiast. Wywoła swój wynik detektor z wynikiem wykrywania za każdym razem, gdy zakończy przetwarzanie ramki wejściowej. Jeśli funkcja wykrywania jest wywoływana podczas jest zajęty przetwarzaniem innej ramki, zadanie zignoruje nową ramkę wejściową.
W
Przykładowy kod punktu orientacyjnego: detect
, detectForVideo
i
Funkcje detectAsync
są zdefiniowane w sekcji
HandLandmarkerHelper.kt
.
Obsługa i wyświetlanie wyników
Ręka zakreślacza generuje obiekt wynikowy narzędzia do punktów orientacyjnych „ręka” dla każdego wykrycia bieganie. Obiekt wynikowy zawiera punkty orientacyjne we współrzędnych obrazu, ręka punkty orientacyjne we współrzędnych świata i określonej orientacji(lewa/prawa ręka) wykrytego obiektu ręce.
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 wskazuje, czy wykryte ręce są lewe czy prawa.
Punkty orientacyjne
Dostępnych jest 21 punktów orientacyjnych rozmieszczonych na dłoni, a każdy z nich składa się ze współrzędnych
x
,y
iz
. Współrzędnex
iy
są normalizowane do wartości [0,0, 1,0] przez szerokość obrazu i wysokości. Współrzędnaz
reprezentuje głębokość punktu orientacyjnego, a przy tym jest ich głębia na nadgarstku. Im mniejsza wartość, tym bliższa jest punktem orientacyjnym.z
– magnituda ma mniej więcej taką samą skalę jakx
Punkty orientacyjne na świecie
Współrzędne świata przedstawiają również 21 ręcznych punktów orientacyjnych. Każdy punkt orientacyjny składa się z elementów
x
,y
iz
, reprezentujących rzeczywiste współrzędne 3D w m, którego punkt początkowy znajduje się 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)
Ten obraz przedstawia wizualizację danych wyjściowych zadania:
Przykładowy kod punktu orientacyjnego pokazuje, jak wyświetlać
wyników zwróconych przez zadanie, patrz
OverlayView
klasy, by dowiedzieć się więcej.