Przewodnik po wykrywaniu punktów orientacyjnych twarzy w systemie iOS

Zadanie MediaPipe Face Landmarker umożliwia wykrywanie punktów orientacyjnych twarzy i wyrazów twarzy na zdjęciach i filmach. Za pomocą tego zadania możesz rozpoznawać ludzkie wyrazy twarzy, stosować filtry i efekty twarzy oraz tworzyć wirtualnych awatarów. To zadanie korzysta z modeli systemów uczących się, które mogą działać z pojedynczymi obrazami, filmami lub ciągłym strumieniem obrazów. Zadanie zwraca trójwymiarowe 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. Aby zobaczyć, jak to zadanie działa w praktyce, obejrzyj prezentację internetową. 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 podstawowa implementacja aplikacji Face Landmarker na iOS. Przykład wykorzystuje kamerę na fizycznym urządzeniu z iOS do wykrywania punktów orientacyjnych twarzy w ciągłym strumieniu wideo. Aplikacja może też wykrywać punkty orientacyjne twarzy 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 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:

  1. Sklonuj repozytorium Git za pomocą tego polecenia:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Opcjonalnie skonfiguruj instancję git, aby używać rzadkiego sprawdzania, dzięki czemu będziesz mieć tylko pliki przykładowej aplikacji Face Landmarker:

    cd mediapipe-samples
    git sparse-checkout init --cone
    git sparse-checkout set examples/face_landmarker/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 Face Landmarker:

  • FaceLandmarkerService.swift: Inicjowanie usługi wyszukiwania punktów orientacyjnych twarzy, obsługa wyboru modelu i wykonywanie wnioskowania na podstawie danych wejściowych.
  • CameraViewController.swift: implementuje interfejs użytkownika w trybie wejścia z obrazu na żywo z kamery i wizualizuje wyniki.
  • MediaLibraryViewController.swift implementuje interfejs użytkownika dla trybów wprowadzania plików graficznych i wideo oraz wizualizuje wyniki.

Konfiguracja

W tej sekcji opisaliśmy kluczowe kroki konfigurowania środowiska programistycznego i projektów kodu na potrzeby korzystania z 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 dla iOS.

Zależności

Face Landmarker 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 komputerze Mac znajdziesz w przewodniku instalacji CocoaPods. Instrukcje tworzenia Podfile z podstawowymi komponentami potrzebnymi do działania aplikacji znajdziesz w artykule Korzystanie z CocoaPods.

Dodaj podelement MediaPipeTasksVision do elementu Podfile za pomocą tego kodu:

target 'MyFaceLandmarkerApp' do
  use_frameworks!
  pod 'MediaPipeTasksVision'
end

Jeśli Twoja aplikacja zawiera cele testów jednostkowych, dodatkowe informacje o konfigurowaniu Podfile znajdziesz w przewodniku po konfigurowaniu na iOS.

Model

Zadanie MediaPipe Face Landmarker wymaga przetestowanego zbioru modeli, który jest zgodny 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 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

Zadanie wykrywania punktów orientacyjnych twarzy możesz utworzyć, wywołując jedną z jego funkcji inicjujących. Inicjalizator FaceLandmarker(options:) może przyjmować wartości opcji konfiguracji.

Jeśli nie potrzebujesz usługi rozpoznawania punktów orientacyjnych twarzy zainicjowanej za pomocą niestandardowych opcji konfiguracji, możesz użyć funkcji inicjalizującej FaceLandmarker(modelPath:), aby utworzyć usługę rozpoznawania punktów orientacyjnych twarzy z opcjami domyślnymi. Więcej informacji o opcjach konfiguracji znajdziesz w artykule Omówienie konfiguracji.

Zadanie polegające na wyznaczaniu punktów orientacyjnych twarzy obsługuje 3 typy danych wejściowych: zdjęcia, pliki wideo i transmisje wideo na żywo. Domyślnie FaceLandmarker(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 FaceLandmarker(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 faceLandmarkerLiveStreamDelegate, która umożliwia narzędziu Face Landmarker asynchroniczne przesyłanie wyników wykrywania punktów orientacyjnych 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: "face_landmarker",
  ofType: "task")

let options = FaceLandmarkerOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .image
options.minFaceDetectionConfidence = minFaceDetectionConfidence
options.minFacePresenceConfidence = minFacePresenceConfidence
options.minTrackingConfidence = minTrackingConfidence
options.numFaces = numFaces

let faceLandmarker = try FaceLandmarker(options: options)
    

Wideo

import MediaPipeTasksVision

let modelPath = Bundle.main.path(
  forResource: "face_landmarker",
  ofType: "task")

let options = FaceLandmarkerOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .video
options.minFaceDetectionConfidence = minFaceDetectionConfidence
options.minFacePresenceConfidence = minFacePresenceConfidence
options.minTrackingConfidence = minTrackingConfidence
options.numFaces = numFaces

let faceLandmarker = try FaceLandmarker(options: options)
    

Transmisja na żywo

import MediaPipeTasksVision

// Class that conforms to the `FaceLandmarkerLiveStreamDelegate` protocol and
// implements the method that the face landmarker calls once it finishes
// performing face landmark detection in each input frame.
class FaceLandmarkerResultProcessor: NSObject, FaceLandmarkerLiveStreamDelegate {

  func faceLandmarker(
    _ faceLandmarker: FaceLandmarker,
    didFinishDetection result: FaceLandmarkerResult?,
    timestampInMilliseconds: Int,
    error: Error?) {

    // Process the face landmarker result or errors here.

  }
}

let modelPath = Bundle.main.path(
  forResource: "face_landmarker",
  ofType: "task")

let options = FaceLandmarkerOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .liveStream
options.minFaceDetectionConfidence = minFaceDetectionConfidence
options.minFacePresenceConfidence = minFacePresenceConfidence
options.minTrackingConfidence = minTrackingConfidence
options.numFaces = numFaces

// Assign an object of the class to the `faceLandmarkerLiveStreamDelegate`
// property.
let processor = FaceLandmarkerResultProcessor()
options.faceLandmarkerLiveStreamDelegate = processor

let faceLandmarker = try FaceLandmarker(options: options)
    

Objective-C

Obraz

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"face_landmarker"
                                                      ofType:@"task"];

MPPFaceLandmarkerOptions *options = [[MPPFaceLandmarkerOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeImage;
options.minFaceDetectionConfidence = minFaceDetectionConfidence;
options.minFacePresenceConfidence = minFacePresenceConfidence;
options.minTrackingConfidence = minTrackingConfidence;
options.numFaces = numFaces;

MPPFaceLandmarker *faceLandmarker =
  [[MPPFaceLandmarker alloc] initWithOptions:options error:nil];
    

Wideo

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"face_landmarker"
                                                      ofType:@"task"];

MPPFaceLandmarkerOptions *options = [[MPPFaceLandmarkerOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeVideo;
options.minFaceDetectionConfidence = minFaceDetectionConfidence;
options.minFacePresenceConfidence = minFacePresenceConfidence;
options.minTrackingConfidence = minTrackingConfidence;
options.numFaces = numFaces;

MPPFaceLandmarker *faceLandmarker =
  [[MPPFaceLandmarker alloc] initWithOptions:options error:nil];
    

Transmisja na żywo

@import MediaPipeTasksVision;

// Class that conforms to the `MPPFaceLandmarkerLiveStreamDelegate` protocol
// and implements the method that the face landmarker calls once it finishes
// performing face landmark detection in each input frame.
@interface APPFaceLandmarkerResultProcessor : NSObject 

@end

@implementation APPFaceLandmarkerResultProcessor

-   (void)faceLandmarker:(MPPFaceLandmarker *)faceLandmarker
    didFinishDetectionWithResult:(MPPFaceLandmarkerResult *)faceLandmarkerResult
         timestampInMilliseconds:(NSInteger)timestampInMilliseconds
                           error:(NSError *)error {

    // Process the face landmarker result or errors here.

}

@end

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"face_landmarker"
                                                      ofType:@"task"];

MPPFaceLandmarkerOptions *options = [[MPPFaceLandmarkerOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeLiveStream;
options.minFaceDetectionConfidence = minFaceDetectionConfidence;
options.minFacePresenceConfidence = minFacePresenceConfidence;
options.minTrackingConfidence = minTrackingConfidence;
options.numFaces = numFaces;

// Assign an object of the class to the `faceLandmarkerLiveStreamDelegate`
// property.
APPFaceLandmarkerResultProcessor *processor = [APPFaceLandmarkerResultProcessor new];
options.faceLandmarkerLiveStreamDelegate = processor;

MPPFaceLandmarker *faceLandmarker =
  [[MPPFaceLandmarker alloc] initWithOptions:options error:nil];
    

Uwaga: jeśli używasz trybu wideo lub transmisji na żywo, funkcja Face Landmarker korzysta ze ś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. Narzędzie do wykrywania punktów orientacyjnych twarzy ma 3 tryby:

IMAGE (Obraz): tryb do obsługi pojedynczych obrazów wejściowych.

VIDEO: tryb dekodowanych klatek filmu.

LIVE_STREAM: tryb transmisji na żywo danych wejściowych, np. z kamery. W tym trybie parametr `faceLandmarkerLiveStreamDelegate` musi być ustawiony jako instancja klasy, która implementuje interfejs `FaceLandmarkerLiveStreamDelegate`. Pozwoli to na asynchroniczne otrzymywanie wyników wykrywania punktów orientacyjnych twarzy.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} {RunningMode.image}
numFaces Maksymalna liczba twarzy, które może wykryć narzędzie Face Landmarker. Wygładzanie jest stosowane tylko wtedy, gdy parametr numFaces ma wartość 1. Liczba całkowita > 0 1
minFaceDetectionConfidence Minimalny wynik ufności wykrywania twarzy, który jest uznawany za pozytywny. Liczba zmiennoprzecinkowa [0,0–1,0] 0,5
minFacePresenceConfidence Minimalny wynik ufności wyniku obecności twarzy w detekcji punktów orientacyjnych twarzy. Liczba zmiennoprzecinkowa [0,0,1,0] 0,5
minTrackingConfidence Minimalny wynik ufności śledzenia twarzy, który jest uznawany za pozytywny. Liczba zmiennoprzecinkowa [0,0–1,0] 0,5
outputFaceBlendshapes Określa, czy FaceLandmarker wyprowadza blendshape’y twarzy. Blendshape’y twarzy są używane do renderowania modelu 3D twarzy. Wartość logiczna fałsz
outputFacialTransformationMatrixes Określa, czy FaceLandmarker ma zwrócić macierz przekształcenia twarzy. Funkcja FaceLandmarker używa macierzy do przekształcenia punktów orientacyjnych twarzy z kanonicznego modelu twarzy na wykrywaną twarz, aby użytkownicy mogli stosować efekty na wykrytych punktach orientacyjnych. Wartość logiczna fałsz

Gdy tryb działania jest ustawiony na LIVE_STREAM, narzędzie Face Landmarker wymaga dodatkowej opcji konfiguracji faceLandmarkerLiveStreamDelegate, która umożliwia asynchroniczne dostarczanie wyników wykrywania punktów orientacyjnych twarzy. Delegat musi zaimplementować metodę faceLandmarker(_:didFinishDetection:timestampInMilliseconds:error:), którą wywołuje funkcja Face Landmarker po przetworzeniu wyników wykrywania punktów orientacyjnych twarzy w każdej klatce.

Nazwa opcji Opis Zakres wartości Wartość domyślna
faceLandmarkerLiveStreamDelegate Umożliwia narzędziu Face Landmarker asynchroniczne otrzymywanie wyników wykrywania punktów orientacyjnych twarzy w trybie transmisji na żywo. Klasa, której instancja jest ustawiona w tej właściwości, musi implementować metodę faceLandmarker(_:didFinishDetection:timestampInMilliseconds:error:). Nie dotyczy Nie ustawiono

Przygotuj dane

Przed przekazaniem do usługi Face Landmarker musisz przekonwertować podany 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, CVPixelBufferCMSampleBuffer.

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 obiekt MPImage.

  • 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. Narzędzie Face Landmarker 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 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 CVPixelBuffer po przetworzeniu ich za pomocą interfejsu CoreImage w iOS, mogą wysyłać je do usługi Face Landmarker w trybie uruchamiania obrazu.

  • Filmy: ramki wideo można przekształcić w format CVPixelBuffer do przetwarzania, a następnie wysłać do usługi Face Landmarker w trybie wideo.

  • transmisja na żywo: aplikacje korzystające z aparatu iOS do generowania klatek mogą być konwertowane do formatu CVPixelBuffer na potrzeby przetwarzania, zanim zostaną wysłane do usługi Face Landmarker 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ć narzędzie do wykrywania punktów orientacyjnych twarzy, użyj metody detect() odpowiedniej dla przypisanego trybu działania:

  • Statyczny obraz: detect(image:)
  • Film: detect(videoFrame:timestampInMilliseconds:)
  • Transmisja na żywo: detectAsync(image:timestampInMilliseconds:)

Poniższe przykładowe fragmenty kodu pokazują podstawowe przykłady uruchamiania usługi Face Landmarker w tych trybach:

Swift

Obraz

let result = try faceLandmarker.detect(image: image)
    

Wideo

let result = try faceLandmarker.detect(
  videoFrame: image,
  timestampInMilliseconds: timestamp)
    

Transmisja na żywo

try faceLandmarker.detectAsync(
  image: image,
  timestampInMilliseconds: timestamp)
    

Objective-C

Obraz

MPPFaceLandmarkerResult *result =
  [faceLandmarker detectImage:image error:nil];
    

Wideo

MPPFaceLandmarkerResult *result =
  [faceLandmarker detectVideoFrame:image
           timestampInMilliseconds:timestamp
                             error:nil];
    

Transmisja na żywo

BOOL success =
  [faceLandmarker detectAsyncImage:image
           timestampInMilliseconds:timestamp
                             error:nil];
    

Przykład kodu usługi Face Landmarker pokazuje szczegółowo implementację każdego z tych trybów: detect(image:), detect(videoFrame:timestampInMilliseconds:)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 punktowania twarzy 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 wejściowego 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. Jeśli aplikacja została utworzona w Swift, możesz też użyć makro Swifta do obsługi równoległości do wykonywania wątków w tle.

  • W trybie transmisji na żywo zadanie wykrywania punktów orientacyjnych twarzy zwraca wyniki natychmiast i nie blokuje bieżącego wątku. Po przetworzeniu każdej klatki wejściowej wywołuje metodę faceLandmarker(_:didFinishDetection:timestampInMilliseconds:error:) z wynikiem wykrywania punktów orientacyjnych twarzy. Moduł Face Landmarker wywołuje tę metodę asynchronicznie w ramach dedykowanej kolejki wysyłania sekwencyjnego. Aby wyświetlić wyniki w interfejsie, prześlij je do kolejki głównej po przetworzeniu.

Obsługa i wyświetlanie wyników

Po przeprowadzeniu wnioskowania usługa Face Landmarker zwraca obiekt FaceLandmarkerResult, który zawiera siatkę twarzy dla każdej wykrytej twarzy wraz z współrzędnymi każdego punktu orientacyjnego twarzy. Opcjonalnie obiekt wyników może też zawierać blendshape’y, które oznaczają wyrazy twarzy, oraz macierze transformacji twarzy, które umożliwiają stosowanie efektów twarzy do wykrytych punktów 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:

Mężczyzna z geometrią twarzy, która wskazuje jej kształt i wymiary

Przykładowy kod funkcji Face Landmarker pokazuje, jak wyświetlać wyniki zwrócone przez to zadanie. Więcej informacji znajdziesz w pliku FaceOverlay.swift.