Przewodnik wykrywania punktów orientacyjnych twarzy na Androidzie

Zadanie MediaPipe Face wygenerowane przez punkt orientacyjny pozwala wykrywać punkty orientacyjne i wyrazy twarzy (zdjęcia i filmy). Możesz używać tego zadania do rozpoznawania wyrazu twarzy ludzi, dodawać filtry i efekty twarzy oraz tworzyć wirtualne awatary; To zadanie używa modeli systemów uczących się, które mogą pracować z pojedynczymi obrazami wiele obrazów. Zadanie zwraca trójwymiarowe punkty orientacyjne płaszczyzny, kształt połączenia wyniki (współczynniki reprezentujące wyraz twarzy) pozwalające ocenić powierzchnie w czasie rzeczywistym oraz macierze transformacji, aby przeprowadzić przekształcenia wymagane do renderowania efektów.

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 narzędzia do określania punktów orientacyjnych 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 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 znacznika twarzy 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:

  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, aby tylko pliki przykładowej aplikacji FaceViewer:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/face_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ładu punktu orientacyjnego twarzy aplikacja:

  • FaceLandmarkerHelper.kt – inicjuje punkt orientacyjny według twarzy oraz obsługuje model i przekazuje dostęp do niego. 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świetlacz z siatką twarzy w przypadku wykrytych twarzy.

Konfiguracja

W tej sekcji opisujemy najważniejsze czynności związane z konfigurowaniem środowiska programistycznego oraz w projektach kodu przeznaczonych konkretnie dla Face Rewards. 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 znacznika twarzy 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 Face Uniqueer wymaga wytrenowanego pakietu modeli zgodnego z w tym zadaniu. Aby uzyskać więcej informacji o dostępnych wytrenowanych modelach dotyczących rozpoznawania 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 FaceLandmarkerHelper.kt plik:

baseOptionsBuilder.setModelAssetPath(MP_FACE_LANDMARKER_TASK)

Tworzenie zadania

Zadanie MediaPipe Face Markuper używa funkcji createFromOptions() do skonfigurowania zadanie. Funkcja createFromOptions() akceptuje wartości konfiguracji . Więcej informacji o opcjach konfiguracji znajdziesz w sekcji Konfiguracja .

Znacznik twarzy obsługuje te 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 i uruchomić wnioskowania.

Obraz

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

val optionsBuilder = 
    FaceLandmarker.FaceLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinFaceDetectionConfidence(minFaceDetectionConfidence)
        .setMinTrackingConfidence(minFaceTrackingConfidence)
        .setMinFacePresenceConfidence(minFacePresenceConfidence)
        .setNumFaces(maxNumFaces)
        .setRunningMode(RunningMode.IMAGE)

val options = optionsBuilder.build()
FaceLandmarker = FaceLandmarker.createFromOptions(context, options)
    

Wideo

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

val optionsBuilder = 
    FaceLandmarker.FaceLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinFaceDetectionConfidence(minFaceDetectionConfidence)
        .setMinTrackingConfidence(minFaceTrackingConfidence)
        .setMinFacePresenceConfidence(minFacePresenceConfidence)
        .setNumFaces(maxNumFaces)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()
FaceLandmarker = FaceLandmarker.createFromOptions(context, options)
    

Transmisja na żywo

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

val optionsBuilder = 
    FaceLandmarker.FaceLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinFaceDetectionConfidence(minFaceDetectionConfidence)
        .setMinTrackingConfidence(minFaceTrackingConfidence)
        .setMinFacePresenceConfidence(minFacePresenceConfidence)
        .setNumFaces(maxNumFaces)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.LIVE_STREAM)

val options = optionsBuilder.build()
FaceLandmarker = FaceLandmarker.createFromOptions(context, options)
    

Przykładowa implementacja kodu Face orientacyjnego 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 setupFaceLandmarker() w FaceLandmarkerHelper.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
numFaces Maksymalna liczba twarzy, które mogą wykryć FaceLandmarker. Wygładzanie jest stosowane tylko wtedy, gdy num_faces ma wartość 1. Integer > 0 1
minFaceDetectionConfidence Minimalny poziom ufności wymagany do wykrywania twarzy została uznana za udaną. Float [0.0,1.0] 0.5
minFacePresenceConfidence Minimalny wskaźnik ufności obecności twarzy punkty w wykrywaniu punktów orientacyjnych twarzy. Float [0.0,1.0] 0.5
minTrackingConfidence Minimalny wskaźnik ufności dla śledzenia twarzy można uznać za udany. Float [0.0,1.0] 0.5
outputFaceBlendshapes Określa, czy narzędzie Rozpoznania twarzy generuje połączenia kształtów twarzy. Połączenie kształtów twarzy służy do renderowania modelu twarzy 3D. Boolean False
outputFacialTransformationMatrixes Określa, czy FaceLandmarker wyświetla twarz macierz przekształceń. FaceLandmarker używa do przekształcenia punktów orientacyjnych twarzy z kanonicznego modelu twarzy na wykrytej twarzy, dzięki czemu użytkownicy mogą stosować efekty na wykrytych punktach orientacyjnych. Boolean False
resultListener Konfiguruje detektor wyników tak, aby otrzymywał wyniki z punktu orientacyjnego asynchronicznie, gdy FaceLandmarker 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

Face orientacyjnego 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 Face orientacyjnego przygotowywanie danych odbywa się w instrukcji FaceLandmarkerHelper.kt .

Uruchamianie zadania

W zależności od typu danych, z którymi pracujesz, skorzystaj z FaceLandmarker.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 interfejsu użytkownika.

Poniższe przykłady kodu pokazują proste przykłady uruchamiania punktu orientacyjnego twarzy w różnych trybach danych:

Obraz

val result = FaceLandmarker.detect(mpImage)
    

Wideo

val timestampMs = i * inferenceIntervalMs

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

Transmisja na żywo

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

FaceLandmarker.detectAsync(mpImage, frameTime)
    

Pamiętaj:

  • Korzystając z trybu wideo lub transmisji na żywo, musisz podać: sygnatura czasowa ramki danych wejściowych do zadania Face orientacyjnego.
  • W przypadku działania w trybie obrazu lub filmu zadanie pomiaru twarzy blokuje zadanie. w bieżącym wątku aż do zakończenia przetwarzania obrazu lub ramki wejściowej. Do unikaj blokowania interfejsu użytkownika, przeprowadzaj przetwarzanie w tle w wątku.
  • W trybie transmisji na żywo zadanie pomiaru twarzy zostanie przywrócone. 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 znacznika twarzy: detect, detectForVideo i Funkcje detectAsync są zdefiniowane w sekcji FaceLandmarkerHelper.kt .

Obsługa i wyświetlanie wyników

Znacznik twarzy zwraca obiekt FaceLandmarkerResult przy każdym wykryciu bieganie. Obiekt wynikowy zawiera siatkę twarzy dla każdej wykrytej twarzy, w której dla każdego punktu orientacyjnego twarzy. Opcjonalnie obiekt wyniku może też zawierają elementy łączące mimikę macierze przekształceń, aby zastosować efekty twarzy do wykrytych punktów orientacyjnych.

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

FaceLandmarkerResult:
  face_landmarks:
    NormalizedLandmark #0:
      x: 0.5971359014511108
      y: 0.485361784696579
      z: -0.038440968841314316
    NormalizedLandmark #1:
      x: 0.3302789330482483
      y: 0.29289937019348145
      z: -0.09489090740680695
    ... (478 landmarks for each face)
  face_blendshapes:
    browDownLeft: 0.8296722769737244
    browDownRight: 0.8096957206726074
    browInnerUp: 0.00035583582939580083
    browOuterUpLeft: 0.00035752105759456754
    ... (52 blendshapes for each face)
  facial_transformation_matrixes:
    [9.99158978e-01, -1.23036895e-02, 3.91213447e-02, -3.70770246e-01]
    [1.66496094e-02,  9.93480563e-01, -1.12779640e-01, 2.27719707e+01]
    ...

Ten obraz przedstawia wizualizację danych wyjściowych zadania:

Przykładowy kod znacznika twarzy pokazuje, jak wyświetlać zwrócone wyniki zobaczysz OverlayView klasy, by dowiedzieć się więcej.