Zadanie Wykrywanie twarzy umożliwia wykrywanie twarzy na obrazie lub w filmie. Za pomocą tego zadania możesz zlokalizować twarze i cechy twarzy w ramce. W tym zadaniu używamy modelu uczenia maszynowego, który działa z pojedynczymi obrazami lub ciągłym strumieniem obrazów. Zadanie to zwraca położenie twarzy oraz następujące kluczowe punkty twarzy: lewe oko, prawe oko, czubek nosa, usta, lewy kącik oka i prawy kącik oka.
Przykładowy kod opisany w tych instrukcjach jest dostępny na GitHub. Aby zobaczyć, jak to zadanie działa w praktyce, obejrzyj prezentację internetową. Więcej informacji o możliwościach, modelach i opcjach konfiguracji tego zadania znajdziesz w sekcji Przegląd.
Przykładowy kod
Przykładowy kod MediaPipe Tasks to prosta implementacja aplikacji wykrywającej twarz na iOS. Przykład wykorzystuje kamerę na fizycznym urządzeniu z Androidem do 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 do utworzenia własnej aplikacji na iOS lub skorzystać z niej podczas modyfikowania istniejącej aplikacji. Przykładowy kod detektory twarzy 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-samplesOpcjonalnie skonfiguruj instancję git, aby używać rzadkiego sprawdzania, dzięki czemu będziesz mieć tylko pliki przykładowej aplikacji Face Detector:
cd mediapipe-samples git sparse-checkout init --cone git sparse-checkout set examples/face_detector/ios/
Po utworzeniu lokalnej wersji przykładowego kodu możesz zainstalować bibliotekę zadań MediaPipe, otworzyć projekt za pomocą Xcode i uruchomić aplikację. Instrukcje znajdziesz w przewodniku konfiguracji na iOS.
Kluczowe komponenty
Te pliki zawierają kluczowy kod aplikacji przykładowej Wykrywanie twarzy:
- FaceDetectorService.swift inicjalizuje detektor, obsługuje wybór modelu i wykonuje wnioskowanie na podstawie danych wejściowych.
- CameraViewController: implementuje interfejs użytkownika w trybie wejścia z obrazu na żywo z kamery i wizualizuje wyniki wykrywania.
- MediaLibraryViewController.swift implementuje interfejs użytkownika dla trybu wprowadzania statycznych obrazów i plików wideo oraz wizualizuje wyniki wykrywania.
Konfiguracja
W tej sekcji opisaliśmy kluczowe kroki konfigurowania środowiska programistycznego i projektów kodu na potrzeby korzystania z usługi Face Detector. Ogólne informacje o konfigurowaniu środowiska programistycznego do korzystania z zadań MediaPipe, w tym wymagania dotyczące wersji platformy, znajdziesz w przewodniku konfiguracji dla iOS.
Zależności
Funkcja wykrywania twarzy korzysta z biblioteki MediaPipeTasksVision, którą należy zainstalować za pomocą CocoaPods. Biblioteka jest zgodna z aplikacją w języku Swift i Objective-C i nie wymaga dodatkowej konfiguracji językowej.
Instrukcje instalacji CocoaPods na macOS znajdziesz w przewodniku instalacji CocoaPods.
Instrukcje tworzenia Podfile z podstawowymi komponentami potrzebnymi do działania aplikacji znajdziesz w artykule Korzystanie z CocoaPods.
Dodaj podproces MediaPipeTasksVision w pliku Podfile, używając tego kodu:
target 'MyFaceDetectorApp' do
use_frameworks!
pod 'MediaPipeTasksVision'
end
Jeśli Twoja aplikacja zawiera cele testów jednostkowych, dodatkowe informacje o konfigurowaniu Podfile znajdziesz w przewodniku konfiguracji na iOS.
Model
Zadanie MediaPipe Face Detector wymaga wytrenowanego modelu, który jest zgodny z tym zadaniem. Więcej informacji o dostępnych wytrenowanych modelach usługi Face Detector znajdziesz w sekcji „Modele” w omówieniu zadania.
Wybierz i pobierz model, a następnie dodaj go do katalogu projektu za pomocą Xcode. Instrukcje dodawania plików do projektu Xcode znajdziesz w artykule Zarządzanie plikami i folderami w projekcie Xcode.
Użyj właściwości BaseOptions.modelAssetPath, aby określić ścieżkę do modelu w pakiecie aplikacji. Przykład kodu znajdziesz w następnej sekcji.
Tworzenie zadania
Zadaniem wykrywania twarzy możesz utworzyć, wywołując jedną z jego funkcji inicjujących. Inicjalizator FaceDetector(options:) może przyjmować wartości opcji konfiguracji.
Jeśli nie potrzebujesz wzorca do wykrywania twarzy zainicjowanego za pomocą niestandardowych opcji konfiguracji, możesz użyć funkcji inicjalizującej FaceDetector(modelPath:), aby utworzyć wzorzec do wykrywania twarzy z opcjami domyślnymi. Więcej informacji o opcjach konfiguracji znajdziesz w artykule Omówienie konfiguracji.
Zadanie wykrywacza twarzy obsługuje 3 typy danych wejściowych: obrazy, pliki wideo i transmisje wideo na żywo. Domyślnie FaceDetector(modelPath:) inicjuje zadanie dotyczące obrazów statycznych. Jeśli chcesz, aby zadanie zostało zainicjowane w celu przetwarzania plików wideo lub transmisji na żywo, użyj parametru FaceDetector(options:), aby określić tryb działania związany z odtwarzaniem filmów lub transmisji na żywo. Tryb transmisji na żywo wymaga też dodatkowej opcji konfiguracji faceDetectorLiveStreamDelegate, która umożliwia detekcja twarzy asynchroniczne przesyłanie wyników wykrywania twarzy do delegata.
Aby dowiedzieć się, jak utworzyć zadanie i przeprowadzić wnioskowanie, wybierz kartę odpowiadającą trybowi działania.
Swift
Obraz
import MediaPipeTasksVision let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = FaceDetectorOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .image let faceDetector = try FaceDetector(options: options)
Wideo
import MediaPipeTasksVision let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = FaceDetectorOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .video let faceDetector = try FaceDetector(options: options)
Transmisja na żywo
import MediaPipeTasksVision // Class that conforms to the `FaceDetectorLiveStreamDelegate` protocol and // implements the method that the face detector calls once it finishes // detecting faces in each input frame. class FaceDetectorResultProcessor: NSObject, FaceDetectorLiveStreamDelegate { func faceDetector( _ faceDetector: FaceDetector, didFinishDetection result: FaceDetectorResult?, timestampInMilliseconds: Int, error: Error?) { // Process the face detection result or errors here. } } let modelPath = Bundle.main.path( forResource: "model", ofType: "tflite") let options = FaceDetectorOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .liveStream // Assign an object of the class to the `faceDetectorLiveStreamDelegate` // property. let processor = FaceDetectorResultProcessor() options.faceDetectorLiveStreamDelegate = processor let faceDetector = try FaceDetector(options: options)
Objective-C
Obraz
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPFaceDetectorOptions *options = [[MPPFaceDetectorOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeImage; MPPFaceDetector *faceDetector = [[MPPFaceDetector alloc] initWithOptions:options error:nil];
Wideo
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPFaceDetectorOptions *options = [[MPPFaceDetectorOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeVideo; MPPFaceDetector *faceDetector = [[MPPFaceDetector alloc] initWithOptions:options error:nil];
Transmisja na żywo
@import MediaPipeTasksVision; // Class that conforms to the `MPPFaceDetectorLiveStreamDelegate` protocol // and implements the method that the face detector calls once it finishes // detecting faces in each input frame. @interface APPFaceDetectorResultProcessor : NSObject@end @implementation APPFaceDetectorResultProcessor - (void)faceDetector:(MPPFaceDetector *)faceDetector didFinishDetectionWithResult:(MPPFaceDetectorResult *)faceDetectorResult timestampInMilliseconds:(NSInteger)timestampInMilliseconds error:(NSError *)error { // Process the face detector result or errors here. } @end NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPFaceDetectorOptions *options = [[MPPFaceDetectorOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeLiveStream; // Assign an object of the class to the `faceDetectorLiveStreamDelegate` // property. APPFaceDetectorResultProcessor *processor = [APPFaceDetectorResultProcessor new]; options.faceDetectorLiveStreamDelegate = processor; MPPFaceDetector *faceDetector = [[MPPFaceDetector alloc] initWithOptions:options error:nil];
Uwaga: jeśli używasz trybu wideo lub transmisji na żywo, funkcja wykrywania twarzy korzysta z śledzenia, aby uniknąć uruchamiania modelu wykrywania na każdym klatce, co pomaga zmniejszyć opóźnienie.
Opcje konfiguracji
W tym zadaniu dostępne są te opcje konfiguracji aplikacji na iOS:
| 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. |
{RunningMode.image, RunningMode.video, RunningMode.liveStream} |
RunningMode.image |
minDetectionConfidence |
Minimalny wynik ufności, który pozwala uznać wykrywanie twarzy za skuteczne. | Float [0,1] |
0.5 |
minSuppressionThreshold |
Minimalny próg wygaszania niemaksymalizowanego wykrywania twarzy, który ma być traktowany jako nakładanie się. | Float [0,1] |
0.3 |
Konfiguracja transmisji na żywo
Gdy tryb działania jest ustawiony na transmisję na żywo, detektor twarzy wymaga dodatkowej opcji konfiguracji faceDetectorLiveStreamDelegate, która umożliwia mu przesyłanie wyników wykrywania asynchronicznie. Delegat implementuje metodę faceDetector(_:didFinishDetection:timestampInMilliseconds:error:), którą wywołuje detekcja twarzy po przetworzeniu wyników wykrywania twarzy w każdej klatce.
| Nazwa opcji | Opis | Zakres wartości | Wartość domyślna |
|---|---|---|---|
faceDetectorLiveStreamDelegate |
Umożliwia detekcja twarzy odbieranie wyników wykrywania twarzy asynchronicznie w trybie transmisji na żywo. Klasa, której instancja jest ustawiona w tej właściwości, musi implementować metodę faceDetector(_:didFinishDetection:timestampInMilliseconds:error:). |
Nie dotyczy | Nie ustawiono |
Przygotuj dane
Przed przekazaniem go do usługi Detector Face musisz przekonwertować wejściowy obraz lub ramkę na obiekt MPImage. MPImage obsługuje różne typy formatów obrazów iOS i może ich używać w dowolnym trybie działania do wnioskowania. Więcej informacji o MPImage znajdziesz w dokumentacji interfejsu MPImage API.
Wybierz format obrazu iOS na podstawie przypadku użycia i trybułu działania wymaganego przez aplikację.MPImage obsługuje formaty obrazów iOS UIImage, CVPixelBuffer i CMSampleBuffer.
UIImage
Format UIImage jest odpowiedni do tych trybów działania:
Obrazy: obrazy z pakietu aplikacji, galerii użytkownika lub systemu plików sformatowane jako obrazy
UIImagemożna przekształcić w obiektMPImage.Filmy: użyj narzędzia AVAssetImageGenerator, aby wyodrębnić klatki wideo do formatu CGImage, a następnie przekonwertuj je na obrazy
UIImage.
Swift
// Load an image on the user's device as an iOS `UIImage` object. // Convert the `UIImage` object to a MediaPipe's Image object having the default // orientation `UIImage.Orientation.up`. let image = try MPImage(uiImage: image)
Objective-C
// Load an image on the user's device as an iOS `UIImage` object. // Convert the `UIImage` object to a MediaPipe's Image object having the default // orientation `UIImageOrientationUp`. MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
Przykład inicjalizuje MPImage z domyślnym ułożeniem UIImage.Orientation.Up. Możesz zainicjować MPImage dowolną z obsługiwanych wartości UIImage.Orientation. Detektor twarzy nie obsługuje orientacji lustrzanych, takich jak .upMirrored, .downMirrored, .leftMirrored, .rightMirrored.
Więcej informacji o UIImage znajdziesz w dokumentacji UIImage dla deweloperów Apple.
CVPixelBuffer
Format CVPixelBuffer jest odpowiedni do aplikacji, które generują klatki i korzystają z ramy CoreImage na iOS do przetwarzania.
Format CVPixelBuffer jest odpowiedni do tych trybów działania:
Obrazy: aplikacje, które generują obrazy
CVPixelBufferpo przetworzeniu ich za pomocą platformyCoreImagew iOS, mogą wysyłać je do usługi Face Detector w trybie uruchamiania obrazu.Filmy: ramki wideo można przekształcić w format
CVPixelBufferdo przetwarzania, a następnie wysłać do usługi Detector twarzy w trybie wideo.transmisja na żywo: aplikacje korzystające z aparatu iOS do generowania klatek mogą być konwertowane do formatu
CVPixelBufferna potrzeby przetwarzania przed wysłaniem do usługi Face Detector w trybie transmisji na żywo.
Swift
// Obtain a CVPixelBuffer. // Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the default // orientation `UIImage.Orientation.up`. let image = try MPImage(pixelBuffer: pixelBuffer)
Objective-C
// Obtain a CVPixelBuffer. // Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the // default orientation `UIImageOrientationUp`. MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
Więcej informacji o CVPixelBuffer znajdziesz w dokumentacji dla deweloperów Apple dotyczącej CVPixelBuffer.
CMSampleBuffer
Format CMSampleBuffer przechowuje próbki multimediów o jednolitym typie i jest odpowiedni do uruchamiania transmisji na żywo. Ramki na żywo z kamer iOS są asynchronicznie dostarczane w formacie CMSampleBuffer przez AVCaptureVideoDataOutput.
Swift
// Obtain a CMSampleBuffer. // Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the default // orientation `UIImage.Orientation.up`. let image = try MPImage(sampleBuffer: sampleBuffer)
Objective-C
// Obtain a `CMSampleBuffer`. // Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the // default orientation `UIImageOrientationUp`. MPImage *image = [[MPPImage alloc] initWithSampleBuffer:sampleBuffer error:nil];
Więcej informacji o CMSampleBuffer znajdziesz w dokumentacji CMSampleBuffer dla deweloperów Apple.
Uruchamianie zadania
Aby uruchomić funkcję wykrywania twarzy, użyj metody detect() odpowiedniej do przypisanego trybu działania:
- Statyczny obraz:
detect(image:) - Film:
detect(videoFrame:timestampInMilliseconds:) - Transmisja na żywo:
detectAsync(image:timestampInMilliseconds:)
Funkcja wykrywania twarzy zwraca wykryte twarze na wejściowym obrazie lub klatce.
Poniższe przykłady kodu pokazują proste przykłady uruchamiania usługi Face Detector w tych trybach:
Swift
Obraz
let result = try faceDetector.detect(image: image)
Wideo
let result = try faceDetector.detect(
videoFrame: image,
timestampInMilliseconds: timestamp)
Transmisja na żywo
try faceDetector.detectAsync(
image: image,
timestampInMilliseconds: timestamp)
Objective-C
Obraz
MPPFaceDetectorResult *result = [faceDetector detectInImage:image error:nil];
Wideo
MPPFaceDetectorResult *result = [faceDetector detectInVideoFrame:image timestampInMilliseconds:timestamp error:nil];
Transmisja na żywo
BOOL success = [faceDetector detectAsyncInImage:image timestampInMilliseconds:timestamp error:nil];
Przykład kodu wykrywacza twarzy pokazuje szczegółowo implementację każdego z tych trybów: detect(image:), detect(videoFrame:timestampInMilliseconds:) i detectAsync(image:timestampInMilliseconds:). Przykładowy kod umożliwia użytkownikowi przełączanie się między trybami przetwarzania, które mogą nie być wymagane w Twoim przypadku.
Pamiętaj:
W trybie wideo lub transmisji na żywo musisz też podać zadaniu Wykrywanie twarzy sygnaturę czasową klatki wejściowej.
W trybie obrazu lub filmu zadanie wykrywacza twarzy blokuje bieżący wątek, dopóki nie przetworzy podawanego obrazu lub klatki. Aby uniknąć blokowania bieżącego wątku, przeprowadź przetwarzanie w wątku tła za pomocą frameworków iOS Dispatch lub NSOperation.
W trybie transmisji na żywo zadanie wykrywania twarzy zwraca wynik natychmiast i nie blokuje bieżącego wątku. Po przetworzeniu każdego obrazu wejściowego wywołuje metodę
faceDetector(_:didFinishDetection:timestampInMilliseconds:error:)z wynikiem wykrywania twarzy. Wykrywanie twarzy wywołuje tę metodę asynchronicznie na dedykowanej kolejce wysyłania sekwencyjnego. Aby wyświetlić wyniki w interfejsie, prześlij je do kolejki głównej po przetworzeniu. Jeśli funkcjadetectAsynczostanie wywołana, gdy zadanie Wykrywanie twarzy jest zajęte przetwarzaniem innego kadru, funkcja Wykrywanie twarzy zignoruje nowy kadr wejściowy.
Obsługa i wyświetlanie wyników
Po przeprowadzeniu wnioskowania zadanie wykrywania twarzy zwraca obiekt FaceDetectorResult, który zawiera ramki ograniczające wykryte twarze oraz wskaźnik ufności dla każdej z nich.
Poniżej znajdziesz przykład danych wyjściowych z 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)
Na ilustracji poniżej widać wizualizację wyniku zadania:
Obraz bez ramek ograniczających znajdziesz w oryginalnym pliku graficznym.
Przykładowy kod usługi Face Detector pokazuje, jak wyświetlać wyniki. Szczegółowe informacje znajdziesz w przykładowym kodzie.