Zadanie Wykrywacz twarzy umożliwia wykrywanie twarzy na zdjęciu lub filmie. Dzięki temu możesz zlokalizować twarze w kadrze. To zadanie wykorzystuje model systemów uczących się (ML), który działa z pojedynczymi obrazami lub ciągłym strumieniem obrazów. Zadanie określa lokalizacje twarzy i następujące punkty twarzy: lewe i prawe oko, opuszkę nosa, usta, tragiczne oko dla lewego i prawego oka.
Przykładowy kod opisany w tych instrukcjach jest dostępny na GitHub. Działanie tego zadania możesz zobaczyć w tej wersji demonstracyjnej. Więcej informacji o możliwościach, modelach i opcjach konfiguracji tego zadania znajdziesz w artykule Omówienie.
Przykładowy kod
Przykładowy kod aplikacji MediaPipe Tasks to prosta implementacja aplikacji do wykrywania twarzy na iOS. W tym przykładzie użyto kamery w fizycznym urządzeniu z Androidem, aby wykrywać twarze 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ć aplikacji jako punktu wyjścia dla własnej aplikacji na iOS lub skorzystać z niej podczas modyfikowania istniejącej aplikacji. Przykładowy kod wykrywacza twarzy jest hostowany na GitHub.
Pobieranie kodu
Z instrukcji poniżej 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 tak, aby używała rozproszonego procesu płatności, aby mieć tylko pliki z przykładowej aplikacji do wykrywania twarzy:
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 po konfiguracji na iOS.
Kluczowe elementy
Te pliki zawierają kluczowy kod przykładowej aplikacji do wykrywania twarzy:
- FaceDetectorService.swift: inicjuje detektor, wybiera model i uruchamia wnioskowanie na danych wejściowych.
- CameraViewController: implementuje interfejs do obsługi trybu wprowadzania danych z kamery na żywo i wizualizuje wyniki wykrywania.
- MediaLibraryViewController.swift: implementuje interfejs użytkownika w trybie wprowadzania plików ze zdjęciami i filmami oraz wizualizuje wyniki wykrywania.
Konfiguracja
W tej sekcji opisano najważniejsze czynności, jakie należy wykonać, aby skonfigurować środowisko programistyczne i projekty kodu tak, aby używały funkcji wykrywania twarzy. Ogólne informacje o konfigurowaniu środowiska programistycznego na potrzeby zadań MediaPipe, w tym o wymaganiach dotyczących wersji platformy, znajdziesz w przewodniku konfiguracji dla iOS.
Zależności
Wykrywacz twarzy korzysta z biblioteki MediaPipeTasksVision
, która musi być zainstalowana za pomocą CocoaPods. Biblioteka jest zgodna z aplikacjami Swift i Objective-C i nie wymaga dodatkowej konfiguracji pod kątem określonego języka.
Instrukcje instalowania CocoaPods w systemie macOS znajdziesz w przewodniku instalacji CocoaPods.
Instrukcje tworzenia Podfile
z podami niezbędnymi do działania aplikacji znajdziesz w artykule Korzystanie z CocoaPods.
Dodaj pod MediaPipeTasksVision w narzędziu Podfile
za pomocą tego kodu:
target 'MyFaceDetectorApp' do
use_frameworks!
pod 'MediaPipeTasksVision'
end
Jeśli aplikacja zawiera cele testu jednostkowego, 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 do wykrywania twarzy znajdziesz w sekcji poświęconej modelom, w sekcji omawiającej zadanie.
Wybierz i pobierz model, a potem dodaj go do katalogu projektów za pomocą Xcode. Instrukcje dodawania plików do projektu Xcode znajdziesz w artykule Zarządzanie plikami i folderami w projekcie Xcode.
Aby określić ścieżkę do modelu w pakiecie aplikacji, użyj właściwości BaseOptions.modelAssetPath
. Przykładowy kod znajdziesz w następnej sekcji.
Tworzenie zadania
Aby utworzyć zadanie Wykrywacz twarzy, wywołaj jeden z jego inicjatorów. Inicjator FaceDetector(options:)
akceptuje wartości opcji konfiguracji.
Jeśli nie potrzebujesz wykrywacza twarzy zainicjowanego z dostosowanymi opcjami konfiguracji, możesz użyć inicjatora FaceDetector(modelPath:)
, aby utworzyć wykrywacz twarzy z opcjami domyślnymi. Więcej informacji o opcjach konfiguracji znajdziesz w artykule Omówienie konfiguracji.
Zadanie Wykrywacz twarzy obsługuje 3 typy danych wejściowych: obrazy, pliki wideo i strumienie wideo na żywo. Domyślnie FaceDetector(modelPath:)
inicjuje zadanie dotyczące nieruchomych obrazów. Jeśli chcesz zainicjować zadanie na potrzeby przetwarzania plików wideo lub strumieni wideo na żywo, użyj funkcji FaceDetector(options:)
, aby określić tryb transmisji wideo lub transmisji na żywo. Tryb transmisji na żywo wymaga też dodatkowej opcji konfiguracji faceDetectorLiveStreamDelegate
, która umożliwia wykrywanie twarzy asynchronicznie dostarczać wyników wykrywania twarzy przedstawicielowi.
Wybierz kartę odpowiadającą Twojemu trybowi biegowemu, aby zobaczyć, jak utworzyć zadanie i uruchomić wnioskowanie.
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, Wykrywacz twarzy używa śledzenia, aby uniknąć uruchamiania modelu wykrywania przy każdej klatce, co pozwala zmniejszyć opóźnienie.
Opcje konfiguracji
To zadanie ma te opcje konfiguracji w przypadku aplikacji na iOS:
Nazwa opcji | Opis | Zakres wartości | Wartość domyślna |
---|---|---|---|
runningMode |
Ustawia tryb działania zadania. Są 3 tryby: IMAGE: tryb wprowadzania pojedynczych obrazów. WIDEO: tryb dekodowanych klatek filmu. TRANSMISJA NA ŻYWO: tryb transmisji danych wejściowych na żywo, np. z kamery. W tym trybie należy wywołać metodę resultListener, aby skonfigurować odbiornik, który będzie odbierał wyniki asynchronicznie. |
{RunningMode.image, RunningMode.video, RunningMode.liveStream } |
RunningMode.image |
minDetectionConfidence |
Minimalny stopień pewności, że wykrywanie twarzy zostanie uznane za udane. | Float [0,1] |
0.5 |
minSuppressionThreshold |
Minimalny próg niemaksymalnego ograniczenia wykrywania twarzy, który ma być uznawany za nakładający się. | Float [0,1] |
0.3 |
Konfiguracja transmisji na żywo
Gdy tryb biegowy jest ustawiony na transmisję na żywo, wykrywacz twarzy wymaga dodatkowej opcji konfiguracji faceDetectorLiveStreamDelegate
, która umożliwia asynchronicznie dostarczanie wyników wykrywania. Osoba, której przekazano dostęp, wdraża metodę faceDetector(_:didFinishDetection:timestampInMilliseconds:error:)
, która jest wywoływana przez wykrywanie twarzy po przetworzeniu wyników wykrywania twarzy dla każdej klatki.
Nazwa opcji | Opis | Zakres wartości | Wartość domyślna |
---|---|---|---|
faceDetectorLiveStreamDelegate |
Włącza asynchronicznie odbieranie wyników wykrywania twarzy przez wykrywanie twarzy w trybie transmisji na żywo. Klasa, której instancja jest ustawiona na tę właściwość, musi implementować metodę faceDetector(_:didFinishDetection:timestampInMilliseconds:error:) . |
Nie dotyczy | Nie ustawiono |
Przygotuj dane
Zanim prześlesz zdjęcie lub klatkę do czytnika twarzy, musisz przekonwertować zdjęcie wejściowe lub klatkę na obiekt MPImage
. MPImage
obsługuje różne typy formatów obrazów na iOS i może ich używać w każdym trybie działania, aby wnioskować. Więcej informacji na temat MPImage
znajdziesz w interfejsie MPImage API
Wybierz format obrazu na iOS zależnie od swojego przypadku użycia i trybu uruchamiania, którego wymaga Twoja aplikacja.MPImage
akceptuje formaty obrazów UIImage
, CVPixelBuffer
i CMSampleBuffer
(iOS).
UIImage
Format UIImage
dobrze sprawdza się w tych trybach biegania:
Obrazy: obrazy z pakietu aplikacji, galerii użytkownika lub systemu plików sformatowane jako obrazy
UIImage
można przekonwertować na 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];
W tym przykładzie inicjuje się MPImage
z domyślną orientacją UIImage.Orientation.Up. Możesz zainicjować MPImage
przy użyciu dowolnej z obsługiwanych wartości UIImage.Orientation. Czujnik twarzy nie obsługuje odbicia lustrzanego w orientacji, np. .upMirrored
, .downMirrored
, .leftMirrored
i .rightMirrored
.
Więcej informacji na temat UIImage
znajdziesz w dokumentacji dla programistów Apple dotyczącej UIImage (w języku angielskim).
CVPixelBuffer
Format CVPixelBuffer
dobrze sprawdza się w aplikacjach, które generują ramki i wykorzystują do przetwarzania platformę CoreImage w systemie iOS.
Format CVPixelBuffer
dobrze sprawdza się w tych trybach biegania:
Obrazy: aplikacje generujące obrazy
CVPixelBuffer
po przetworzeniu przy użyciu platformyCoreImage
systemu iOS mogą być wysyłane do funkcji wykrywania twarzy w trybie uruchamiania obrazów.Filmy: klatki wideo można przekonwertować na format
CVPixelBuffer
w celu przetworzenia, a następnie wysłać do wykrywacza twarzy w trybie wideo.transmisja na żywo: aplikacje korzystające z kamery w systemie iOS do generowania klatek można skonwertować do formatu
CVPixelBuffer
w celu przetworzenia, zanim zostaną wysłane do wykrywacza 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 na temat CVPixelBuffer
znajdziesz w dokumentacji dla programistów Apple CVPixelBuffer.
CMSampleBuffer
Format CMSampleBuffer
przechowuje próbki multimediów jednolitego typu i dobrze sprawdza się w trybie transmisji na żywo. Klatki na żywo z kamer na iOS są przesyłane asynchronicznie w formacie CMSampleBuffer
przez system iOS 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 na temat CMSampleBuffer
znajdziesz w dokumentacji dla programistów Apple CMSampleBuffer.
Uruchamianie zadania
Aby uruchomić wykrywanie twarzy, użyj metody detect()
odpowiedniej dla przypisanego trybu biegowego:
- Nieruchomy obraz:
detect(image:)
- Film:
detect(videoFrame:timestampInMilliseconds:)
- Transmisja na żywo:
detectAsync(image:timestampInMilliseconds:)
Wykrywacz twarzy zwraca wykryte twarze na zdjęciu lub ramce.
Na tych przykładach kodu widać proste przykłady uruchamiania czytnika 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 Wykrywacza twarzy szczegółowo przedstawia implementacje każdego z tych trybów: detect(image:)
, detect(videoFrame:timestampInMilliseconds:)
i detectAsync(image:timestampInMilliseconds:)
. Przykładowy kod pozwala użytkownikowi przełączać się między trybami przetwarzania, które mogą nie być wymagane w Twoim przypadku.
Uwaga:
W trybie wideo lub transmisji na żywo musisz też podać sygnaturę czasową klatki wejściowej w zadaniu Wykrywacz twarzy.
W trybie obrazu lub filmu zadanie Wykrywacz twarzy blokuje bieżący wątek, dopóki nie zakończy przetwarzania obrazu wejściowego lub klatki. Aby uniknąć zablokowania bieżącego wątku, wykonaj przetwarzanie w wątku w tle za pomocą platform Dispatch lub NSOperation w systemie iOS.
W trybie transmisji na żywo zadanie Wykrywanie twarzy wraca natychmiast i nie blokuje bieżącego wątku. Po przetworzeniu każdej klatki wejściowej wywołuje metodę
faceDetector(_:didFinishDetection:timestampInMilliseconds:error:)
z wynikiem wykrywania twarzy. Wykrywanie twarzy asynchronicznie wywołuje tę metodę w dedykowanej szeregowej kolejce wysyłania. W przypadku wyświetlania wyników w interfejsie po ich przetworzeniu wyślij do głównej kolejki. Jeśli funkcjadetectAsync
zostanie wywołana, gdy zadanie Wykrywanie twarzy jest zajęte przetwarzaniem innej klatki, Wykrywacz twarzy ignoruje nową klatkę wejściową.
Obsługa i wyświetlanie wyników
Po uruchomieniu wnioskowania zadanie Wykrywacz twarzy zwraca obiekt FaceDetectorResult
zawierający ramki ograniczające wykryte twarze oraz poziom ufności każdej wykrytej twarzy.
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)
Poniższy obraz przedstawia wizualizację wyników zadania:
W przypadku obrazu bez ramek ograniczających wyświetl oryginalny obraz.
Przykładowy kod Wykrywacza twarzy pokazuje, jak wyświetlić wyniki. Szczegóły znajdziesz w przykładowym kodzie.