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 zwraca pozycje 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 to demo. Więcej informacji o możliwościach, modelach i opcjach konfiguracji tego zadania znajdziesz w omówieniu.
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 usługi Face Detector 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 Detector:
cd mediapipe 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 dla 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 do obsługi trybu wprowadzania nieruchomych obrazów i plików wideo oraz wizualizuje wyniki wykrywania.
Konfiguracja
W tej sekcji znajdziesz najważniejsze czynności, które musisz wykonać, aby skonfigurować środowisko programistyczne i projekty kodu pod kątem używania Wykrywania twarzy. 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 podami niezbędnymi dla 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 na potrzeby Wykrywania twarzy znajdziesz w omówieniu zadania w sekcji Modele.
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ładowy kod znajdziesz w następnej sekcji.
Tworzenie zadania
Zadanie wykrywania twarzy możesz utworzyć, wywołując jedną z jego funkcji inicjującej. 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: IMAGE (Obraz): tryb do wprowadzania pojedynczych obrazów. 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 niemaksymalizacji dla wykrywania twarzy, który ma być uznany za nakładający 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. Przedstawiciel implementuje metodę faceDetector(_:didFinishDetection:timestampInMilliseconds:error:)
, którą detektor twarzy wywołuje 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
UIImage
moż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
przy użyciu dowolnej z obsługiwanych wartości UIImage.Orientation. Wykrywanie twarzy nie obsługuje lustrzanych orientacji, takich jak .upMirrored
, .downMirrored
, .leftMirrored
, .rightMirrored
.
Więcej informacji o UIImage
znajdziesz w dokumentacji UIImage dla deweloperów Apple.
CVPixelBuffer
Format CVPixelBuffer
jest odpowiedni dla 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
CVPixelBuffer
po przetworzeniu ich za pomocą platformyCoreImage
w iOS, mogą wysyłać je do usługi Face Detector w trybie uruchamiania obrazu.Filmy: ramki wideo można przekształcić w format
CVPixelBuffer
do przetwarzania, a następnie wysłać do usługi Detector twarzy w trybie wideo.transmisja na żywo: aplikacje korzystające z aparatu w iOS do generowania klatek mogą być konwertowane do formatu
CVPixelBuffer
w celu przetworzenia, zanim zostaną przesłane do wykrywania twarzy 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:
- Zdjęcie:
detect(image:)
- Film:
detect(videoFrame:timestampInMilliseconds:)
- Transmisja na żywo:
detectAsync(image:timestampInMilliseconds:)
Wykrywanie twarzy zwraca wykryte twarze na zdjęciu lub w ramce.
Poniżej znajdziesz przykładowy kod pokazujący, jak uruchomić Wykrywacz twarzy w różnych trybach działania:
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 wykrywania twarzy bardziej szczegółowo pokazuje implementacje 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ć sygnaturę czasową ramki wejściowej do zadania Wykrywanie twarzy.
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żdej ramki wejściowej wywołuje metodę
faceDetector(_:didFinishDetection:timestampInMilliseconds:error:)
z wynikiem wykrywania twarzy. Wykrywanie twarzy wywołuje tę metodę asynchronicznie w dedykowanej kolejce szeregowej kolejki. Aby wyświetlić wyniki w interfejsie, prześlij je do kolejki głównej po przetworzeniu. Jeśli funkcjadetectAsync
zostanie 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)
Ten obraz przedstawia wizualizację danych wyjściowych zadania:
Obraz bez ramek ograniczających znajdziesz w oryginale.
Przykładowy kod usługi Face Detector pokazuje, jak wyświetlać wyniki. Szczegółowe informacje znajdziesz w przykładowym kodzie.