מדריך לזיהוי נקודות ייחודיות בפנים ב-iOS

המשימה 'זיהוי ציוני דרך בפנים' ב-MediaPipe מאפשרת לזהות ציוני דרך בפנים והבעות פנים בתמונות ובסרטונים. אפשר להשתמש במשימה הזו כדי לזהות הבעות פנים אנושיות, להחיל פילטרים ואפקטים על הפנים וליצור דמויות וירטואליות. במשימה הזו נעשה שימוש במודלים של למידת מכונה (ML) שיכולים לפעול עם תמונות בודדות, סרטונים או מקור תמונות רציף. הפלט של המשימה כולל ציוני 'ציוני דרך' תלת-ממדיים של הפנים, ציונים של צורות מעורבות (מאפיינים שמייצגים הבעת פנים) כדי להסיק משטחי פנים מפורטים בזמן אמת ומטריצות טרנספורמציה כדי לבצע את הטרנספורמציות הנדרשות לעיבוד הגרפי של האפקטים.

דוגמת הקוד שמתוארת בהוראות האלו זמינה ב-GitHub. אתם יכולים לראות את המשימה הזו בפעולה בהדגמה הזו לאינטרנט. בסקירה הכללית תוכלו לקרוא מידע נוסף על היכולות, המודלים ואפשרויות ההגדרה של המשימה הזו.

קוד לדוגמה

קוד הדוגמה של MediaPipe Tasks הוא הטמעה בסיסית של אפליקציית Face Landmarker ל-iOS. בדוגמה הזו נעשה שימוש במצלמה במכשיר iOS פיזי כדי לזהות נקודות ציון בפנים בסטרימינג רציף של וידאו. האפליקציה יכולה גם לזהות ציוני דרך של פנים בתמונות ובסרטונים מגלריית המכשיר.

אפשר להשתמש באפליקציה כנקודת התחלה לאפליקציית iOS משלכם, או להיעזר בה כשמשנים אפליקציה קיימת. קוד הדוגמה של Face Landmarker מתארח ב-GitHub.

להורדת הקוד

בהוראות הבאות מוסבר איך ליצור עותק מקומי של קוד הדוגמה באמצעות הכלי של שורת הפקודה git.

כדי להוריד את הקוד לדוגמה:

  1. משכפלים את מאגר git באמצעות הפקודה הבאה:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. אפשר גם להגדיר את ה-Git למכונת ה-Git כך שתתבצע תשלום מצומצם, כך שיהיו לכם רק את הקבצים של האפליקציה לדוגמה של Face Placeer:

    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/face_landmarker/ios
    

אחרי שיוצרים גרסה מקומית של הקוד לדוגמה, אפשר להתקין את ספריית המשימות MediaPipe, לפתוח את הפרויקט באמצעות Xcode ולהריץ את האפליקציה. הוראות מופיעות במדריך ההגדרה ל-iOS.

רכיבים מרכזיים

הקבצים הבאים מכילים את הקוד החשוב לאפליקציית הדוגמה של Face Landmarker:

  • FaceLandmarkerService.swift: מאתחל את Face Placeer, מטפל בבחירת המודל ומריץ מסקנות על נתוני הקלט.
  • CameraViewController.swift: הקוד הזה מטמיע את ממשק המשתמש של מצב הקלט של פיד המצלמה בשידור חי ומציג את התוצאות באופן חזותי.
  • MediaLibraryViewController.swift: הקוד הזה מטמיע את ממשק המשתמש למצבי הקלט של קובצי תמונות וסרטונים, ומציג את התוצאות באופן חזותי.

הגדרה

בקטע הזה מתוארים השלבים העיקריים להגדרת סביבת הפיתוח ופרויקטים של הקוד כדי להשתמש ב-Face Placeerer. מידע כללי על הגדרת סביבת הפיתוח לשימוש במשימות של MediaPipe, כולל דרישות לגבי גרסאות הפלטפורמה, זמין במדריך ההגדרה ל-iOS.

יחסי תלות

Face Identityer משתמש בספרייה MediaPipeTasksVision, שאותה צריך להתקין באמצעות CocoaPods. הספרייה תואמת לאפליקציות Swift וגם לאפליקציות Objective-C, ולא נדרשת הגדרה נוספת ספציפית לשפה.

הוראות להתקנת CocoaPods ב-MacOS מפורטות במדריך ההתקנה של CocoaPods. במאמר שימוש ב-CocoaPods מוסבר איך ליצור Podfile עם ה-Pods שדרושים לאפליקציה.

מוסיפים את ה-pod של MediaPipeTasksVision ב-Podfile באמצעות הקוד הבא:

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

אם האפליקציה כוללת יעדי בדיקת יחידה, אפשר לעיין במדריך ההגדרה ל-iOS כדי לקבל מידע נוסף על הגדרת Podfile.

דגם

כדי לבצע את המשימה 'זיהוי נקודות ציון בפנים' ב-MediaPipe, נדרש חבילת מודל מאומנת שתואמת למשימה הזו. מידע נוסף על המודלים המאומנים הזמינים ל-Face Landmarker זמין בקטע 'מודלים' שבסקירה הכללית של המשימה.

בוחרים מודל ומורידים אותו, ומוסיפים אותו לספריית הפרויקט באמצעות Xcode. הוראות להוספת קבצים לפרויקט ב-Xcode מפורטות במאמר ניהול קבצים ותיקיות בפרויקט ב-Xcode.

השתמשו במאפיין BaseOptions.modelAssetPath כדי לציין את הנתיב למודל בקובץ האפליקציה. דוגמה לקוד מופיעה בקטע הבא.

יצירת המשימה

אפשר ליצור את המשימה Face Landmarker על ידי קריאה לאחד מהמפעילים שלה. המאתחל FaceLandmarker(options:) מקבל ערכים של אפשרויות ההגדרה.

אם אתם לא צריכים לאתחל את Face Landmarker עם אפשרויות תצורה בהתאמה אישית, תוכלו להשתמש במחולל FaceLandmarker(modelPath:) כדי ליצור Face Landmarker עם אפשרויות ברירת המחדל. מידע נוסף על אפשרויות ההגדרה זמין במאמר סקירה כללית על הגדרות.

המשימה 'זיהוי נקודות ציון בפנים' תומכת ב-3 סוגי נתוני קלט: תמונות סטילס, קובצי וידאו ושידורי וידאו חיים. כברירת מחדל, FaceLandmarker(modelPath:) מאתחלת משימה לתמונות סטילס. אם רוצים שהמשימה תאופס לעיבוד קובצי וידאו או סטרימינג של וידאו בשידור חי, צריך להשתמש ב-FaceLandmarker(options:) כדי לציין את מצב ההפעלה של הסרטון או השידור החי. כדי להשתמש במצב של שידור חי, צריך גם להגדיר את האפשרות הנוספת faceLandmarkerLiveStreamDelegate, שמאפשרת ל-Face Landmarker לשלוח את התוצאות של זיהוי נקודות הפנים למשתתף המורשה באופן אסינכרוני.

בוחרים את הכרטיסייה שמתאימה למצב ההפעלה כדי לראות איך יוצרים את המשימה ומפעילים את ההסקה.

Swift

תמונה

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)
    

וידאו

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)
    

שידור חי

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

תמונה

@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];
    

וידאו

@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];
    

שידור חי

@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];
    

הערה: אם משתמשים במצב וידאו או במצב שידור חי, התכונה Face Landmarker משתמשת במעקב כדי למנוע הפעלה של מודל הזיהוי בכל פריים, וכך מפחיתה את זמן האחזור.

אפשרויות הגדרה

למשימה הזו יש את אפשרויות התצורה הבאות לאפליקציות ל-iOS:

שם האפשרות תיאור טווח ערכים ערך ברירת מחדל
runningMode הגדרת מצב ההפעלה של המשימה. Face Lawer כולל שלושה מצבים:

תמונה: המצב לקלט של תמונה יחידה.

סרטון: המצב של פריימים מפוענחים בסרטון.

LIVE_STREAM: המצב של שידור חי של נתוני קלט, למשל ממצלמה. במצב הזה, צריך להגדיר את 'faceLandmarkerLiveStreamDelegate' כמופע של מחלקה שמיישם את 'FaceLandmarkerLiveStreamDelegate' כדי לקבל את התוצאות של ביצוע זיהוי של ציוני דרך של פנים באופן אסינכרוני.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} {RunningMode.image}
numFaces המספר המקסימלי של קבוצות פנים שה-Face Placeer יכול לזהות. החלקה מיושמת רק אם הערך של numFaces הוא 1. מספר שלם > 0 1
minFaceDetectionConfidence ציון הסמך המינימלי כדי שזיהוי הפנים ייחשב כמוצלח. מספר ממשי (float) ‏[0.0,1.0] 0.5
minFacePresenceConfidence דירוג הוודאות המינימלי של דירוג נוכחות הפנים בזיהוי של נקודות ציון בפנים. מספר ממשי (float) ‏[0.0,1.0] 0.5
minTrackingConfidence דירוג האמון המינימלי שדרוש כדי שמערכת מעקב הפנים תחשב כהצלחה. מספר ממשי (float) ‏[0.0,1.0] 0.5
outputFaceBlendshapes אם הפונקציה FaceLandmarker תפיק צורות פנים משולבות. תבניות עיבוד של פנים משמשות ליצירת עיבוד (רנדרינג) של מודל הפנים התלת-ממדי. בוליאני false
outputFacialTransformationMatrixes האם FaceLandmarker יפיק את מטריצת הטרנספורמציה של הפנים. הפונקציה FaceLandmarker משתמשת במטריצה כדי להמיר את נקודות הציון בפנים ממודל פנים קנוני לפנים שזוהה, כדי שמשתמשים יוכלו להחיל אפקטים על נקודות הציון שזוהו. בוליאני false

כשמצב ההפעלה מוגדר כ-LIVE_STREAM, נדרש ל-Face Landmarker את אפשרות התצורה הנוספת faceLandmarkerLiveStreamDelegate, שמאפשרת ל-Face Landmarker לספק תוצאות של זיהוי נקודות ציון בפנים באופן אסינכרוני. הנציג צריך להטמיע את השיטה faceLandmarker(_:didFinishDetection:timestampInMilliseconds:error:), שנקראת על ידי Face Landmarker אחרי עיבוד התוצאות של זיהוי נקודות ציון בפנים בכל פריים.

שם האפשרות תיאור טווח ערכים ערך ברירת מחדל
faceLandmarkerLiveStreamDelegate ההגדרה הזו מאפשרת ל-Face Landmarker לקבל את התוצאות של זיהוי נקודות ציון בפנים באופן אסינכרוני במצב של שידור חי. המחלקה שהמכונה שלה מוגדרת לנכס הזה צריכה להטמיע את ה-method faceLandmarker(_:didFinishDetection:timestampInMilliseconds:error:). לא רלוונטי לא מוגדר

הכנת הנתונים

צריך להמיר את תמונת הקלט או את המסגרת לאובייקט MPImage לפני ההעברה ל-Face Scoreer. MPImage תומך בסוגים שונים של פורמטים של תמונות ב-iOS, וניתן להשתמש בהם בכל מצב ריצה לצורך הסקת מסקנות. למידע נוסף על MPImage, אפשר לעיין במאמר MPImage API.

בוחרים את פורמט התמונה ל-iOS בהתאם לתרחיש לדוגמה ולמצב ההפעלה שנדרש לאפליקציה. MPImage תומך בפורמטים של תמונות ל-iOS‏ UIImage,‏ CVPixelBuffer ו-CMSampleBuffer.

UIImage

הפורמט UIImage מתאים במיוחד למצבי ההפעלה הבאים:

  • תמונות: אפשר להמיר תמונות מ-App Bundle, מגלריית משתמשים או ממערכת קבצים בפורמט UIImage לאובייקט MPImage.

  • סרטונים: משתמשים ב-AVAssetImageGenerator כדי לחלץ פריימים של סרטונים לפורמט CGImage, ולאחר מכן ממירים אותם לתמונות 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];
    

בדוגמה מתבצעת אתחול של MPImage עם כיוון ברירת המחדל UIImage.Orientation.Up. אפשר לאתחל MPImage עם כל אחד מהערכים הנתמכים של UIImage.Orientation. התכונה 'זיהוי פנים' לא תומכת בכיוונים מוחזרים כמו .upMirrored,‏ .downMirrored,‏ .leftMirrored,‏ .rightMirrored.

מידע נוסף על UIImage זמין במסמכי התיעוד למפתחים של Apple בנושא UIImage.

CVPixelBuffer

הפורמט CVPixelBuffer מתאים לאפליקציות שיוצרות פריימים ומשתמשות במסגרת CoreImage של iOS לעיבוד.

הפורמט CVPixelBuffer מתאים במיוחד למצבי ההפעלה הבאים:

  • תמונות: אפליקציות שיוצרות תמונות CVPixelBuffer אחרי עיבוד מסוים באמצעות מסגרת CoreImage של iOS יכולות לשלוח את התמונות ל-Face Landmarker במצב 'הפעלת תמונה'.

  • סרטונים: אפשר להמיר פריימים של וידאו לפורמט CVPixelBuffer לצורך עיבוד, ולאחר מכן לשלוח אותם ל-Face Markuper במצב וידאו.

  • שידור חי: יכול להיות שאפליקציות שמשתמשות במצלמת iOS כדי ליצור פריימים יומרו לפורמט CVPixelBuffer לצורך עיבוד לפני שהן יישלחו ל-Face Landmarker במצב שידור חי.

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];
    

מידע נוסף על CVPixelBuffer זמין במסמכי התיעוד למפתחים של Apple בנושא CVPixelBuffer.

CMSampleBuffer

בפורמט CMSampleBuffer מאוחסנות דגימות מדיה מסוג מדיה אחיד, והוא מתאים במיוחד למצב ההפעלה של שידור חי. פריימים בשידור חי ממצלמות iOS מועברים באופן אסינכרוני בפורמט CMSampleBuffer על ידי AVCaptureVideoDataOutput של iOS.

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];
    

מידע נוסף על CMSampleBuffer זמין במסמכי העזרה למפתחים של Apple בנושא CMSampleBuffer.

הרצת המשימה

כדי להריץ את Face Landmarker, משתמשים בשיטה detect() הספציפית למצב ההפעלה שהוקצה:

  • תמונת סטילס: detect(image:)
  • סרטון: detect(videoFrame:timestampInMilliseconds:)
  • צפייה בשידור חי: detectAsync(image:timestampInMilliseconds:)

בדוגמאות הקוד הבאות מפורטות דוגמאות בסיסיות להרצת Face Landmarker במצבי ההפעלה השונים:

Swift

תמונה

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

וידאו

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

שידור חי

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

Objective-C

תמונה

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

וידאו

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

שידור חי

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

בדוגמה לקוד של Face Landmarker מפורטות ההטמעות של כל אחד מהמצבים האלה detect(image:),‏ detect(videoFrame:timestampInMilliseconds:) ו-detectAsync(image:timestampInMilliseconds:). הקוד לדוגמה מאפשר למשתמש לעבור בין מצבי עיבוד, שיכול להיות שלא נדרשים לתרחיש לדוגמה.

שימו לב לנקודות הבאות:

  • כשמריצים את הקוד במצב וידאו או במצב של שידור חי, צריך לספק גם את חותמת הזמן של פריים הקלט למשימה של Face Landmarker.

  • כשעובדים במצב תמונה או וידאו, המשימה Face Valueer חוסמת את השרשור הנוכחי עד לסיום העיבוד של תמונת הקלט או הפריים. כדי למנוע חסימה של השרשור הנוכחי, צריך להריץ את העיבוד בשרשור רקע באמצעות מסגרות ה-iOS Dispatch או NSOperation. אם האפליקציה נוצרה באמצעות Swift, אפשר להשתמש גם ב-Swift בו-זמניות כדי לבצע שרשורים ברקע.

  • כשהיא פועלת במצב של שידור חי, המשימה של זיהוי נקודות ציון בפנים חוזרת מיד ולא חוסמת את השרשור הנוכחי. הוא מפעיל את השיטה faceLandmarker(_:didFinishDetection:timestampInMilliseconds:error:) עם תוצאת זיהוי נקודות ציון בפנים אחרי עיבוד כל פריים של הקלט. ה-Face Landmarker מפעיל את השיטה הזו באופן אסינכרוני בתור ייעודי לניתוב טורית. כדי להציג את התוצאות בממשק המשתמש, שולחים את התוצאות לתור הראשי אחרי העיבוד שלהן.

טיפול בתוצאות והצגתן

כשמריצים את ההשערה, התכונה Face Courter מחזירה FaceLandmarkerResult שמכיל רשת לזיהוי פנים לכל אחת מהפנים שזוהו, עם קואורדינטות לכל זיהוי פנים. אפשר גם לכלול באובייקט התוצאה צורות מיזוג (blendshapes) שמציינות הבעות פנים ומטריצות טרנספורמציה של פנים כדי להחיל אפקטים על הנקודות החשובות שזוהו.

בהמשך מוצגת דוגמה לנתוני הפלט של המשימה הזו:

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]
    ...

בתמונה הבאה מוצגת תצוגה חזותית של הפלט של המשימה:

הקוד לדוגמה של Face Labeler מדגים איך להציג את התוצאות שהוחזרו מהמשימה. למידע נוסף, ראו FaceOverlay.swift.