Zadanie MediaPipe Face Landmarker umożliwia wykrywanie punktów orientacyjnych twarzy i wyrazów twarzy na zdjęciach i w filmach. Za pomocą tego zadania możesz rozpoznawać ludzkie mimiki, stosować filtry i efekty twarzy oraz tworzyć wirtualnych awatarów. To zadanie korzysta z modeli uczenia maszynowego, które mogą działać z pojedynczymi obrazami lub ciągłym strumieniem obrazów. Zadanie to generuje 3D-wymiarowe punkty orientacyjne twarzy, wartości blendshape (współczynniki reprezentujące mimikę twarzy), aby w czasie rzeczywistym wywnioskować szczegółowe powierzchnie twarzy, oraz macierze przekształceń, aby wykonać przekształcenia wymagane do renderowania efektów.
Przykładowy kod opisany w tych instrukcjach jest dostępny na GitHub. Więcej informacji o możliwościach, modelach i opcjach konfiguracji związanych z tym zadaniem znajdziesz w sekcji Omówienie.
Przykładowy kod
Przykładowy kod MediaPipe Tasks to prosta implementacja aplikacji Face Landmarker na Androida. W tym przykładzie do wykrywania twarzy w ciągłym strumieniu wideo użyto kamery na fizycznym urządzeniu z Androidem. 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 do stworzenia własnej aplikacji na Androida lub skorzystać z niej podczas modyfikowania istniejącej aplikacji. Przykładowy kod usługi Face Landmarker jest hostowany na GitHub.
Pobieranie kodu
Z tych instrukcji dowiesz się, jak utworzyć lokalną kopię przykładowego kodu 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 skonfiguruj instancję git, aby używać rzadkiego sprawdzania, dzięki czemu będziesz mieć tylko pliki przykładowej aplikacji Face Landmarker:
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 do Android Studio i uruchomić aplikację. Instrukcje znajdziesz w przewodniku konfiguracji Androida.
Kluczowe komponenty
Te pliki zawierają kluczowy kod przykładowej aplikacji do wykrywania punktów charakterystycznych twarzy:
- FaceLandmarkerHelper.kt – inicjuje punkty orientacyjne twarzy i obsługuje model oraz wybór delegata.
- CameraFragment.kt – obsługuje kamerę urządzenia i przetwarza dane wejściowe obrazu i wideo.
- GalleryFragment.kt – współpracuje z
OverlayView
, aby wyświetlić obraz lub film wyjściowy. - OverlayView.kt – implementuje wyświetlanie siatki twarzy dla wykrytych twarzy.
Konfiguracja
W tej sekcji opisaliśmy kluczowe kroki konfigurowania środowiska programistycznego i projektów kodu w celu używania narzędzia Face Landmarker. Ogólne informacje o konfigurowaniu środowiska programistycznego do korzystania z zadań MediaPipe, w tym wymagania dotyczące wersji platformy, znajdziesz w przewodniku konfiguracji na Androida.
Zależności
Zadanie polegające na wykrywaniu punktów orientacyjnych twarzy korzysta z biblioteki com.google.mediapipe:tasks-vision
. Dodaj tę zależność do pliku build.gradle
aplikacji na Androida:
dependencies {
implementation 'com.google.mediapipe:tasks-vision:latest.release'
}
Model
Zadanie MediaPipe Face Landmarker wymaga pakietu wytrenowanych modeli zgodnego z tym zadaniem. Więcej informacji o dostępnych wytrenowanych modelach usługi Face Landmarker znajdziesz w sekcji Modele w omówieniu zadania.
Wybierz i pobierz model, a potem zapisz go w katalogu projektu:
<dev-project-root>/src/main/assets
W parametrze ModelAssetPath
podaj ścieżkę do modelu. W przykładowym kodzie model jest zdefiniowany w pliku FaceLandmarkerHelper.kt
:
baseOptionsBuilder.setModelAssetPath(MP_FACE_LANDMARKER_TASK)
Tworzenie zadania
Zadanie MediaPipe Face Landmarker używa funkcji createFromOptions()
do konfigurowania zadania. Funkcja createFromOptions()
akceptuje wartości opcji konfiguracji. Więcej informacji o opcjach konfiguracji znajdziesz w artykule Opcje konfiguracji.
Narzędzie Face Landmarker obsługuje te typy danych wejściowych: obrazy, pliki wideo i transmisje wideo na żywo. Podczas tworzenia zadania musisz określić tryb wykonywania odpowiadający typowi danych wejściowych. Wybierz kartę odpowiadającą typowi danych wejściowych, aby dowiedzieć się, jak utworzyć zadanie i przeprowadzić wnioskowanie.
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)
Implementacja przykładowego kodu usługi Face Landmarker umożliwia użytkownikowi przełączanie się między trybami przetwarzania. Takie podejście skomplikuje kod tworzący zadanie i może nie być odpowiednie w Twoim przypadku. Ten kod znajdziesz w funkcji setupFaceLandmarker()
w pliku FaceLandmarkerHelper.kt
.
Opcje konfiguracji
W tym zadaniu dostępne są te opcje konfiguracji aplikacji na Androida:
Nazwa opcji | Opis | Zakres wartości | Wartość domyślna |
---|---|---|---|
runningMode |
Ustawia tryb działania zadania. Dostępne są 3 tryby: OBRAZ: tryb dla pojedynczych obrazów wejściowych. FILM: tryb dekodowanych klatek filmu. LIVE_STREAM: tryb transmisji na żywo danych wejściowych, takich jak dane z kamery. W tym trybie należy wywołać metodę resultListener, aby skonfigurować odbiornik, który będzie asynchronicznie odbierał wyniki. |
{IMAGE, VIDEO, LIVE_STREAM } |
IMAGE |
numFaces |
Maksymalna liczba twarzy, którą może wykryć FaceLandmarker . Wygładzanie jest stosowane tylko wtedy, gdy parametr num_faces ma wartość 1.
|
Integer > 0 |
1 |
minFaceDetectionConfidence |
Minimalny wynik ufności dla wykrywania twarzy, aby uznać go za udany. | Float [0.0,1.0] |
0.5 |
minFacePresenceConfidence |
Minimalny wynik ufności wykrywania obecności twarzy w detekcji punktów orientacyjnych twarzy. | Float [0.0,1.0] |
0.5 |
minTrackingConfidence |
Minimalny wynik ufności śledzenia twarzy, aby uznać go za udany. | Float [0.0,1.0] |
0.5 |
outputFaceBlendshapes |
Określa, czy narzędzie Face Landmarker ma generować blendshape’y twarzy. Blendshape’y twarzy są używane do renderowania modelu 3D twarzy. | Boolean |
False |
outputFacialTransformationMatrixes |
Określa, czy FaceLandmarker ma zwrócić macierz przekształceń twarzy. Funkcja FaceLandmarker korzysta z macierzy, aby przekształcać punkty orientacyjne twarzy z kanonicznego modelu twarzy na wykrywaną twarz, dzięki czemu użytkownicy mogą stosować efekty na wykrytych punktach orientacyjnych. | Boolean |
False |
resultListener |
Ustawia odbiornik wyników tak, aby asynchronicznie otrzymywał wyniki wyszukiwania punktów orientacyjnych, gdy usługa FaceLandmarker jest w trybie transmisji na żywo.
Można go używać tylko wtedy, gdy tryb działania ma wartość LIVE_STREAM . |
ResultListener |
N/A |
errorListener |
Ustawia opcjonalny odbiornik błędów. | ErrorListener |
N/A |
Przygotuj dane
Narzędzie Face Landmarker działa z obrazami, plikami wideo i transmisjami na żywo. Zadanie to obsługuje wstępną obróbkę danych wejściowych, w tym zmianę rozmiaru, obrót i normalizację wartości.
Poniższy kod pokazuje, jak przekazywać dane do przetwarzania. Te przykłady zawierają szczegółowe informacje o obsługiwaniu danych z obrazów, plików wideo i transmisji na żywo.
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 usługi Face Landmarker przygotowanie danych jest obsługiwane w pliku FaceLandmarkerHelper.kt
.
Uruchamianie zadania
W zależności od typu danych, z którymi pracujesz, użyj metody FaceLandmarker.detect...()
odpowiedniej dla tego typu danych. Użyj wartości detect()
dla pojedynczych obrazów, detectForVideo()
dla klatek w plikach wideo oraz detectAsync()
dla strumieni wideo. Podczas wykrywania treści w strumieniach wideo należy uruchamiać wykrywanie na osobnym wątku, aby nie blokować wątku interfejsu użytkownika.
Poniższe przykłady kodu pokazują proste przykłady uruchamiania usługi Face Landmarker 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:
- W trybie wideo lub trybie transmisji na żywo zadanie wyodrębniania punktów orientacyjnych twarzy musi zawierać sygnaturę czasową ramki wejściowej.
- W trybie obrazu lub filmu zadanie wykrywania punktów orientacyjnych twarzy blokuje bieżący wątek, dopóki nie przetworzy wstępnego obrazu lub ramki. Aby uniknąć blokowania interfejsu użytkownika, przetwarzanie należy wykonać w tle.
- W trybie transmisji na żywo zadanie wykrywania punktów orientacyjnych twarzy zwraca dane natychmiast i nie blokuje bieżącego wątku. Za każdym razem, gdy skończy przetwarzać daną klatkę wejściową, wywoła komponent odbiorczy z wynikiem wykrywania.
W przykładowym kodzie funkcji Face Landmarker funkcje detect
, detectForVideo
i detectAsync
są zdefiniowane w pliku FaceLandmarkerHelper.kt
.
Obsługa i wyświetlanie wyników
Funkcja Face Landmarker zwraca obiekt FaceLandmarkerResult
dla każdego przebiegu wykrywania. Obiekt result zawiera siatkę twarzy dla każdej wykrytej twarzy wraz z współrzędnymi każdego punktu odniesienia twarzy. Opcjonalnie obiekt wyniku może też zawierać blendshape’y, które oznaczają mimikę twarzy, oraz macierze transformacji twarzy, aby stosować efekty twarzy na wykrytych punktach orientacyjnych.
Poniżej znajdziesz przykład danych wyjściowych z 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]
...
Na ilustracji poniżej widać wynik wykonania zadania:
Przykładowy kod usługi Face Landmarker pokazuje, jak wyświetlać wyniki zwrócone przez zadanie. Więcej informacji znajdziesz w klasie OverlayView
.