Przewodnik po rozpoznaniu gestów w Androidzie

Narzędzie do rozpoznawania gestów MediaPipe umożliwia rozpoznawanie gestów w czasie rzeczywistym. udostępnia rozpoznane gesty i punkty orientacyjne dłoni wykryte ręce. Te instrukcje pokazują, jak korzystać z rozpoznawania gestów w aplikacjach na Androida. Dostępny jest przykładowy kod opisany w tych instrukcjach w GitHub.

Aby zobaczyć, jak działa to zadanie, wyświetl internetowej wersji demonstracyjnej. 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 modułu do rozpoznawania gestów na Androida. W tym przykładzie użyliśmy aparatu w fizycznym urządzeniu z Androidem, stale wykrywa gesty rąk i może używać obrazów i filmów Galerii urządzenia do statycznego wykrywania gestów.

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 narzędzia do rozpoznawania gestów znajduje się na serwerze GitHub

Pobieranie kodu

Poniżej znajdziesz instrukcje tworzenia lokalnej kopii przykładu. za pomocą narzędzia wiersza poleceń git.

Aby pobrać przykładowy kod:

  1. Sklonuj repozytorium git za pomocą tego polecenia:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Opcjonalnie możesz skonfigurować instancję git tak, aby wykorzystywała rozproszony proces płatności, masz więc tylko pliki przykładowej aplikacji do rozpoznawania gestów:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/gesture_recognizer/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

Te pliki zawierają kod niezbędny do tego gestu dłoni przykładowa aplikacja dotycząca rozpoznawania:

Konfiguracja

W tej sekcji opisujemy najważniejsze czynności związane z konfigurowaniem środowiska programistycznego oraz w projektach w których ma być używane narzędzie do rozpoznawania gestów. 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 rozpoznawania gestów używa: 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 Migrate Diagnosticr wymaga wytrenowanego pakietu modeli zgodnego z w tym zadaniu. Więcej informacji na temat dostępnych wytrenowanych modeli rozpoznawania gestów 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 GestureRecognizerHelper.kt plik:

baseOptionBuilder.setModelAssetPath(MP_RECOGNIZER_TASK)

Tworzenie zadania

Zadanie rozpoznawania gestów MediaPipe używa funkcji createFromOptions() do załatwić sprawę. Funkcja createFromOptions() akceptuje wartości dla i wybierz opcje konfiguracji. Więcej informacji o opcjach konfiguracji znajdziesz zapoznaj się z sekcją Opcje konfiguracji.

Moduł do rozpoznawania gestów obsługuje 3 typy danych wejściowych: nieruchome obrazy, pliki wideo strumieniowania wideo na żywo. Musisz określić tryb działania odpowiadający parametrowi typ danych wejściowych podczas tworzenia zadania. Wybierz kartę odpowiadającą typ danych wejściowych, aby zobaczyć, jak utworzyć zadanie i uruchomić wnioskowanie.

Obraz

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_RECOGNIZER_TASK)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder =
    GestureRecognizer.GestureRecognizerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setRunningMode(RunningMode.IMAGE)

val options = optionsBuilder.build()
gestureRecognizer =
    GestureRecognizer.createFromOptions(context, options)
    

Wideo

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_RECOGNIZER_TASK)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder =
    GestureRecognizer.GestureRecognizerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()
gestureRecognizer =
    GestureRecognizer.createFromOptions(context, options)
    

Transmisja na żywo

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_RECOGNIZER_TASK)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder =
    GestureRecognizer.GestureRecognizerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.LIVE_STREAM)

val options = optionsBuilder.build()
gestureRecognizer =
    GestureRecognizer.createFromOptions(context, options)
    

Przykładowa implementacja kodu rozpoznawania gestów 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 setupGestureRecognizer() w GestureRecognizerHelper.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 Maksymalną liczbę rąk może wykryć GestureRecognizer. 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 wynik ufności dłoni na ręce model wykrywania punktów orientacyjnych. W trybie wideo i trybie transmisji na żywo modułu rozpoznawania gestów jeśli wynik pewności obecności ręki z modelu punktu orientacyjnego ręki jest poniżej ten próg aktywuje model wykrywania dłoni. W przeciwnym razie lekki algorytm śledzenia dłoni jest używany do określania lokalizacji ręce do późniejszego wykrycia 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 Moduł rozpoznawania gestów, jeśli śledzenie nie działa, moduł rozpoznawania gestów uruchamia dłoń wykrywaniem zagrożeń. W przeciwnym razie wykrywanie rąk zostanie pominięte. 0.0 - 1.0 0.5
cannedGesturesClassifierOptions Opcje konfiguracji działania klasyfikatora gestów bazujących na szablonach. Gotowe gesty: ["None", "Closed_Fist", "Open_Palm", "Pointing_Up", "Thumb_Down", "Thumb_Up", "Victory", "ILoveYou"]
  • Wyświetlane nazwy – język: język używany na potrzeby wyświetlanych nazw określonych za pomocą metadanych modelu TFLite (jeśli występują).
  • Maksymalna liczba wyników: maksymalna liczba najwyżej punktowanych wyników klasyfikacji do zwrócenia. Jeśli < 0 – zostaną zwrócone wszystkie dostępne wyniki.
  • Próg wyniku: wynik, poniżej którego wyniki są odrzucane. Jeśli ma wartość 0, zwracane są wszystkie dostępne wyniki.
  • Lista dozwolonych kategorii: lista dozwolonych nazw kategorii. Jeśli pole nie jest puste, wyniki klasyfikacji, których kategoria nie należy do tego zbioru, zostaną odfiltrowane. Wzajemnie wyklucza się z listą odrzuconych.
  • Lista odrzuconych kategorii: lista odrzuconych nazw kategorii. Jeśli pole nie jest puste, wyniki klasyfikacji, które należą do tego zbioru, zostaną odfiltrowane. Wzajemne wykluczanie z listy dozwolonych.
    • Język wyświetlanych nazw: any string
    • Maksymalna liczba wyników: any integer
    • Próg wyniku: 0.0-1.0
    • Lista dozwolonych kategorii: vector of strings
    • Lista odrzuconych kategorii: vector of strings
    • Język wyświetlanych nazw: "en"
    • Maksymalna liczba wyników: -1
    • Próg wyniku: 0
    • Lista dozwolonych kategorii: pusta
    • Lista odrzuconych kategorii: pusta
    customGesturesClassifierOptions Opcje konfigurowania działania klasyfikatora gestów niestandardowych.
  • Wyświetlane nazwy – język: język używany na potrzeby wyświetlanych nazw określonych za pomocą metadanych modelu TFLite (jeśli występują).
  • Maksymalna liczba wyników: maksymalna liczba najwyżej punktowanych wyników klasyfikacji do zwrócenia. Jeśli < 0 – zostaną zwrócone wszystkie dostępne wyniki.
  • Próg wyniku: wynik, poniżej którego wyniki są odrzucane. Jeśli ma wartość 0, zwracane są wszystkie dostępne wyniki.
  • Lista dozwolonych kategorii: lista dozwolonych nazw kategorii. Jeśli pole nie jest puste, wyniki klasyfikacji, których kategoria nie należy do tego zbioru, zostaną odfiltrowane. Wzajemnie wyklucza się z listą odrzuconych.
  • Lista odrzuconych kategorii: lista odrzuconych nazw kategorii. Jeśli pole nie jest puste, wyniki klasyfikacji, które należą do tego zbioru, zostaną odfiltrowane. Wzajemne wykluczanie z listy dozwolonych.
    • Język wyświetlanych nazw: any string
    • Maksymalna liczba wyników: any integer
    • Próg wyniku: 0.0-1.0
    • Lista dozwolonych kategorii: vector of strings
    • Lista odrzuconych kategorii: vector of strings
    • Język wyświetlanych nazw: "en"
    • Maksymalna liczba wyników: -1
    • Próg wyniku: 0
    • Lista dozwolonych kategorii: pusta
    • Lista odrzuconych kategorii: pusta
    resultListener Konfiguruje detektor wyników, aby otrzymywać wyniki klasyfikacji asynchronicznie, gdy moduł rozpoznawania gestów działa w trybie transmisji na żywo. Tej opcji można używać tylko wtedy, gdy tryb działania jest ustawiony na LIVE_STREAM ResultListener Nie dotyczy Nie dotyczy
    errorListener Ustawia opcjonalny detektor błędów. ErrorListener Nie dotyczy Nie dotyczy

    Przygotuj dane

    Rozpoznawanie gestów obsługuje obrazy, plik wideo i transmisję 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 aplikacji do rozpoznawania gestów. Przygotowanie danych odbywa się w sekcji GestureRecognizerHelper.kt .

    Uruchamianie zadania

    Moduł rozpoznawania gestów używa tych funkcji: recognize, recognizeForVideo oraz recognizeAsync w celu aktywowania zależności. Rozpoznawanie gestów wymaga: wstępne przetwarzanie danych wejściowych, wykrywanie rąk na zdjęciu, wykrywanie dłoni za punkty orientacyjne i rozpoznawanie gestów dłoni z nich.

    Poniższy kod pokazuje, jak wykonać przetwarzanie za pomocą modelu zadań. Zawierają one szczegółowe instrukcje postępowania z danymi z obrazów, plików wideo, i transmisje wideo na żywo.

    Obraz

    val result = gestureRecognizer?.recognize(mpImage)
        

    Wideo

    val timestampMs = i * inferenceIntervalMs
    
    gestureRecognizer?.recognizeForVideo(mpImage, timestampMs)
        ?.let { recognizerResult ->
            resultList.add(recognizerResult)
        }
        

    Transmisja na żywo

    val mpImage = BitmapImageBuilder(rotatedBitmap).build()
    val frameTime = SystemClock.uptimeMillis()
    
    gestureRecognizer?.recognizeAsync(mpImage, frameTime)
        

    Pamiętaj:

    • Gdy pracujesz w trybie wideo lub w trybie transmisji na żywo, musisz też podać sygnaturę czasową ramki wejściowej zadania Rozpoznawanie gestów.
    • W trybie obrazu lub wideo zadanie Rozpoznawanie gestów będzie 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 rozpoznawania gestów nie blokuje w bieżącym wątku, ale wraca natychmiast. Wywoła swój wynik detektor z wynikiem rozpoznawania po każdym zakończeniu przetwarzania ramki wejściowej. Jeśli funkcja rozpoznawania jest wywoływana, gdy moduł rozpoznawania gestów zadanie jest zajęte przetwarzaniem innej ramki, zadanie zignoruje nową ramkę wejściową.

    W Przykładowy kod modułu rozpoznawania gestów: recognize, recognizeForVideo i Funkcje recognizeAsync są zdefiniowane w sekcji GestureRecognizerHelper.kt .

    Obsługa i wyświetlanie wyników

    Moduł rozpoznawania gestów generuje obiekt wyniku wykrywania gestów dla każdego podczas rozpoznawania. Obiekt wynikowy zawiera punkty orientacyjne we współrzędnych obrazu, punkty orientacyjne we współrzędnych świata, leworęczność(lewa/prawa ręka) i ręka kategorie gestów wykrytych rąk.

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

    Wynik GestureRecognizerResult zawiera 4 komponenty, a każdy z nich to tablica, w której każdy element zawiera wykryty wynik 1 wykrytej dłoni.

    • Ręka dominująca

      Ręka wskazuje, czy wykryte ręce są lewe czy prawa.

    • Gesty

      Kategorie rozpoznanych gestów wykrytych rąk.

    • 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 i z. Współrzędne x i y są normalizowane do wartości [0,0, 1,0] przez szerokość obrazu i wysokości. Współrzędna z 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ę jak x

    • 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 i z, reprezentujących rzeczywiste współrzędne 3D w m, którego punkt początkowy znajduje się w środku geometrycznym dłoni.

    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)
    

    Te obrazy przedstawiają wizualizację danych wyjściowych zadania:

    W Przykładowy kod modułu rozpoznawania gestów, klasa GestureRecognizerResultsAdapter w GestureRecognizerResultsAdapter.kt. obsługuje wyniki.