Przewodnik wykrywania twarzy w przypadku Androida

Zadanie MediaPipe Wykrywanie twarzy umożliwia wykrywanie twarzy na zdjęciach lub filmach. Za pomocą to zadanie, aby znajdować twarze i twarze w kadrze. To zadanie używa model uczenia maszynowego, który działa z pojedynczymi obrazami lub wiele obrazów. Zadanie generuje lokalizacje twarzy, a także: charakterystyczne elementy twarzy: lewe i prawe oko, czubek nosa, usta, uraz lewego oka oraz do urazu prawego oka.

Dostępny jest przykładowy kod opisany w tych instrukcjach włączono GitHub Więcej informacji o możliwościach, modelach i modelach dotyczących opcji konfiguracji tego zadania, zobacz Omówienie.

Przykładowy kod

Przykładowy kod MediaPipe Tasks to prosta implementacja wykrywania twarzy na Androida. W tym przykładzie użyliśmy aparatu w fizycznym urządzeniu z Androidem, wykrywania twarzy w ciągłym strumieniu wideo. Aplikacja może też wykrywać twarze na zdjęciach i filmach 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 wykrywania twarzy 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:

  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 Wykrywacz twarzy:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/face_detector/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ą kluczowy kod dotyczący tego przykładu wykrywania twarzy aplikacja:

  • FaceDetectorHelper.kt – Inicjuje wykrywanie twarzy i obsługuje model oraz przedstawiciela wyboru.
  • CameraFragment.kt – Obsługuje aparat urządzenia i przetwarza dane wejściowe obrazu i filmu.
  • GalleryFragment.kt – Wchodzi w interakcję z tagiem OverlayView, aby wyświetlić obraz wyjściowy lub film.
  • OverlayView.kt – Implementuje wyświetlacz z ramkami ograniczającymi wykryte twarze.

Konfiguracja

W tej sekcji opisujemy najważniejsze czynności związane z konfigurowaniem środowiska programistycznego oraz projektów kodu, w których mają być używane wykrywanie twarzy. 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 Wykrywanie twarzy 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 wykrywania twarzy MediaPipe wymaga wytrenowanego pakietu modeli zgodnego z w tym zadaniu. Aby dowiedzieć się więcej o dostępnych wytrenowanych modelach wykrywania twarzy, 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 FaceDetectorHelper.kt plik:

val modelName = "face_detection_short_range.tflite"
baseOptionsBuilder.setModelAssetPath(modelName)

Tworzenie zadania

Zadanie Wykrywanie twarzy MediaPipe używa funkcji createFromOptions() do skonfigurowania zadanie. Funkcja createFromOptions() akceptuje wartości konfiguracji . Więcej informacji o opcjach konfiguracji znajdziesz w artykule Opcje konfiguracji:

Wykrywanie twarzy obsługuje następujące typy danych wejściowych: obrazy, pliki wideo i strumieniowania wideo 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(modelName)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder =
    FaceDetector.FaceDetectorOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinDetectionConfidence(threshold)
        .setRunningMode(RunningMode.IMAGE)

val options = optionsBuilder.build()

FaceDetector =
    FaceDetector.createFromOptions(context, options)
    

Wideo

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

val optionsBuilder =
    FaceDetector.FaceDetectorOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinDetectionConfidence(threshold)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()

FaceDetector =
    FaceDetector.createFromOptions(context, options)
    

Transmisja na żywo

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

val optionsBuilder =
    FaceDetector.FaceDetectorOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinDetectionConfidence(threshold)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.LIVE_STREAM)

val options = optionsBuilder.build()

FaceDetector =
    FaceDetector.createFromOptions(context, options)
    

Przykładowa implementacja kodu Wykrywacz twarzy umożliwia użytkownikowi przełączanie się 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 setupFaceDetector() w FaceDetectorHelper.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
minDetectionConfidence Minimalny wskaźnik ufności, który musi spełniać, aby wykrywanie twarzy zostało uznane za udane. Float [0,1] 0.5
minSuppressionThreshold Minimalny niemaksymalny próg wyłączenia funkcji wykrywania twarzy, który może zostać uznany za pokrywający się. Float [0,1] 0.3
resultListener Konfiguruje detektor wyników, który otrzymuje wyniki wykrywania asynchronicznie, gdy funkcja wykrywania twarzy jest włączona w transmisji na żywo. i trybu uzyskiwania zgody. Tej opcji można używać tylko wtedy, gdy tryb działania jest ustawiony na LIVE_STREAM. N/A Not set
errorListener Ustawia opcjonalny detektor błędów. N/A Not set

Przygotuj dane

Wykrywanie twarzy działa w przypadku zdjęć, plików 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ładowy kod wykrywania twarzy. Przygotowanie danych odbywa się w FaceDetectorHelper.kt .

Uruchamianie zadania

W zależności od typu danych, z którymi pracujesz, skorzystaj z faceDetector.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żej znajdziesz przykładowy kod pokazujący, jak w prosty sposób uruchomić Wykrywacz twarzy w różnych trybach danych:

Obraz

val result = faceDetector.detect(mpImage)
    

Wideo

val timestampMs = i * inferenceIntervalMs

faceDetector.detectForVideo(mpImage, timestampMs)
    .let { detectionResult ->
        resultList.add(detectionResult)
    }
    

Transmisja na żywo

val mpImage = BitmapImageBuilder(rotatedBitmap).build()
val frameTime = SystemClock.uptimeMillis()

faceDetector.detectAsync(mpImage, frameTime)
    

Pamiętaj:

  • Korzystając z trybu wideo lub transmisji na żywo, musisz: powoduje podanie sygnatury czasowej ramki wejściowej zadania Wykrywacz twarzy.
  • W trybie obrazu lub wideo zadanie Wykrywanie twarzy blokuje 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 Wykrywacz twarzy 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. Jeśli funkcja wykrywania jest wywoływana, gdy zadanie Wykrywacz twarzy jest zajęty przetwarzaniem innej ramki, zadanie zignoruje nową ramkę wejściową.

W Przykładowy kod wykrywania twarzy, detect, detectForVideo i Funkcje detectAsync są zdefiniowane w sekcji FaceDetectorHelper.kt .

Obsługa i wyświetlanie wyników

Wykrywanie twarzy zwraca obiekt FaceDetectorResult przy każdym wykryciu bieganie. Obiekt wynikowy zawiera ramki ograniczające dla wykrytych twarzy oraz wskaźnik ufności dla każdej wykrytej twarzy.

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

FaceDetectionResult:
  Detections:
    Detection #0:
      BoundingBox:
        origin_x: 126
        origin_y: 100
        width: 463
        height: 463
      Categories:
        Category #0:
          index: 0
          score: 0.9729152917861938
      NormalizedKeypoints:
        NormalizedKeypoint #0:
          x: 0.18298381567001343
          y: 0.2961040139198303
        NormalizedKeypoint #1:
          x: 0.3302789330482483
          y: 0.29289937019348145
        ... (6 keypoints for each face)
    Detection #1:
      BoundingBox:
        origin_x: 616
        origin_y: 193
        width: 430
        height: 430
      Categories:
        Category #0:
          index: 0
          score: 0.9251380562782288
      NormalizedKeypoints:
        NormalizedKeypoint #0:
          x: 0.6151331663131714
          y: 0.3713381886482239
        NormalizedKeypoint #1:
          x: 0.7460576295852661
          y: 0.38825345039367676
        ... (6 keypoints for each face)

Ten obraz przedstawia wizualizację danych wyjściowych zadania:

Zobacz oryginalny obraz obrazu bez ramek ograniczających.

Przykładowy kod Wykrywania twarzy pokazuje, jak wyświetlać wyników zwróconych przez zadanie, patrz OverlayView klasy, by dowiedzieć się więcej.