您可以使用「臉孔偵測」工作,偵測圖片或影片中的臉孔。您可以使用這個任務,在影格內找出臉部和臉部特徵。這項工作會使用機器學習 (ML) 模型,該模型可搭配單張圖片或持續的圖片串流運作。這項工作會輸出臉部位置,以及下列臉部關鍵點:左眼、右眼、鼻尖、嘴巴、左眼內側及右眼內側。
您可以在 GitHub 上找到這些操作說明中所述的程式碼範例。您可以查看此網路示範,瞭解此工作的實際執行情況。如要進一步瞭解此任務的功能、模型和設定選項,請參閱總覽。
程式碼範例
MediaPipe Tasks 範例程式碼是 iOS 臉部偵測器應用程式的簡單實作方式。本範例會使用實體 Android 裝置的相機,在持續的影片串流中偵測臉孔。應用程式也可以偵測裝置相片庫中的圖片和影片中的臉孔。
您可以使用這個應用程式做為自有 iOS 應用程式的起點,或是在修改現有應用程式時參考這個應用程式。臉部偵測器範例程式碼託管於 GitHub。
下載程式碼
以下操作說明說明如何使用 git 指令列工具,建立範例程式碼的本機副本。
下載程式碼範例:
使用下列指令複製 git 存放區:
git clone https://github.com/google-ai-edge/mediapipe-samples
您可以選擇將 Git 例項設定為使用稀疏檢查,這樣您就只會取得 Face Detector 範例應用程式的檔案:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/face_detector/ios/
建立範例程式碼的本機版本後,您可以安裝 MediaPipe 工作程式庫,使用 Xcode 開啟專案,並執行應用程式。如需操作說明,請參閱 iOS 設定指南。
重要元件
以下檔案包含 Face Detector 範例應用程式的關鍵程式碼:
- FaceDetectorService.swift:初始化偵測器、處理模型選取作業,並對輸入資料執行推論。
- CameraViewController:實作即時鏡頭畫面輸入模式的 UI,並以視覺化方式呈現偵測結果。
- MediaLibraryViewController.swift:實作靜態圖片和影片檔案輸入模式的 UI,並以視覺化方式呈現偵測結果。
設定
本節將說明設定開發環境和程式碼專案以使用 Face Detector 的關鍵步驟。如要進一步瞭解如何設定開發環境,以便使用 MediaPipe 工作,包括平台版本需求,請參閱 iOS 專用設定指南。
依附元件
Face Detector 會使用 MediaPipeTasksVision
程式庫,必須使用 CocoaPods 安裝。這個程式庫與 Swift 和 Objective-C 應用程式相容,且不需要任何額外的語言專屬設定。
如需在 macOS 上安裝 CocoaPods 的操作說明,請參閱 CocoaPods 安裝指南。如需有關如何為應用程式建立包含必要 Pod 的 Podfile
的操作說明,請參閱「使用 CocoaPods」一文。
使用下列程式碼,在 Podfile
中新增 MediaPipeTasksVision pod:
target 'MyFaceDetectorApp' do
use_frameworks!
pod 'MediaPipeTasksVision'
end
如果您的應用程式包含單元測試目標,請參閱「iOS 設定指南」,進一步瞭解如何設定 Podfile
。
型號
MediaPipe 臉部偵測器工作需要訓練的模型與此工作相容。如要進一步瞭解 Face Detector 可用的訓練模型,請參閱任務總覽的「模型」一節。
選取並下載模型,然後使用 Xcode 將模型新增至專案目錄。如需在 Xcode 專案中新增檔案的操作說明,請參閱「管理 Xcode 專案中的檔案和資料夾」。
使用 BaseOptions.modelAssetPath
屬性指定應用程式套件中的模型路徑。如需程式碼範例,請參閱下一節。
建立工作
您可以呼叫其中一個初始化器,建立 Face Detector 工作。FaceDetector(options:)
初始化器會接受設定選項的值。
如果您不需要透過自訂設定選項初始化臉部偵測器,可以使用 FaceDetector(modelPath:)
初始化器透過預設選項建立臉部偵測器。如要進一步瞭解設定選項,請參閱「設定總覽」。
臉部偵測器工作支援 3 種輸入資料類型:靜態圖片、影片檔案和即時影像串流。根據預設,FaceDetector(modelPath:)
會初始化靜態圖片的工作。如要初始化工作以處理影片檔案或直播影片串流,請使用 FaceDetector(options:)
指定影片或即時串流執行模式。直播模式也需要額外的 faceDetectorLiveStreamDelegate
設定選項,讓臉部偵測器可將臉部偵測結果非同步傳送給委派函。
選擇執行模式對應的分頁,瞭解如何建立工作並執行推論。
Swift
圖片
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)
影片
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)
直播
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
圖片
@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];
影片
@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];
直播
@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];
注意:如果您使用影片模式或直播模式,臉部偵測器就會使用追蹤功能,避免在每個影格上觸發偵測模型,協助縮短延遲時間。
設定選項
此工作包含下列 iOS 應用程式的設定選項:
選項名稱 | 說明 | 值範圍 | 預設值 |
---|---|---|---|
runningMode |
設定任務的執行模式。共有三種模式: IMAGE:單一圖片輸入模式。 VIDEO:影片解碼影格模式。 LIVE_STREAM:輸入資料 (例如來自攝影機的資料) 的直播模式。在這個模式中,必須呼叫 resultListener,才能設定事件監聽器,以非同步方式接收結果。 |
{RunningMode.image, RunningMode.video, RunningMode.liveStream } |
RunningMode.image |
minDetectionConfidence |
臉部偵測必須達到的最低可信度分數,才能視為成功。 | Float [0,1] |
0.5 |
minSuppressionThreshold |
臉部偵測系統判定為重疊的非最大抑制門檻下限。 | Float [0,1] |
0.3 |
直播設定
當執行模式設為即時串流時,臉部偵測器需要額外的 faceDetectorLiveStreamDelegate
設定選項,才能讓臉部偵測工具以非同步方式傳送偵測結果。委派函實作 faceDetector(_:didFinishDetection:timestampInMilliseconds:error:)
方法,Face Detector 會在處理每個影格臉部偵測結果後呼叫此方法。
選項名稱 | 說明 | 值範圍 | 預設值 |
---|---|---|---|
faceDetectorLiveStreamDelegate |
讓臉部偵測器在直播模式下以非同步方式接收臉部偵測結果。將例項設為此屬性的類別必須實作 faceDetector(_:didFinishDetection:timestampInMilliseconds:error:) 方法。 |
不適用 | 未設定 |
準備資料
您必須先將輸入圖片或影格轉換為 MPImage
物件,才能將其傳送至臉部偵測器。MPImage
支援不同類型的 iOS 圖片格式,並可在任何執行模式下用於推論。如要進一步瞭解 MPImage
,請參閱 MPImage API。
根據您的用途和應用程式所需的執行模式,選擇 iOS 圖片格式。MPImage
接受 UIImage
、CVPixelBuffer
和 CMSampleBuffer
iOS 圖片格式。
UIImage
UIImage
格式非常適合下列執行模式:
圖片:應用程式套件、使用者相片庫或檔案系統中的圖片,如果以
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];
這個範例會使用預設的 UIImage.Orientation.Up 方向初始化 MPImage
。您可以使用任何支援的 UIImage.Orientation 值初始化 MPImage
。臉部偵測器不支援鏡像螢幕方向,例如 .upMirrored
、.downMirrored
、.leftMirrored
、.rightMirrored
。
如要進一步瞭解 UIImage
,請參閱 UIImage Apple 開發人員說明文件。
CVPixelBuffer
CVPixelBuffer
格式非常適合用於產生影格,並使用 iOS CoreImage 架構進行處理的應用程式。
CVPixelBuffer
格式非常適合下列執行模式:
圖片:在使用 iOS 的
CoreImage
架構處理過後,產生CVPixelBuffer
圖片的應用程式,可以在圖片執行模式中傳送至臉部偵測器。影片:可將影片影格轉換為
CVPixelBuffer
格式進行處理,然後以影片模式傳送至 Face Detector。直播:使用 iOS 相機產生影格時,應用程式可能會先將影格轉換為
CVPixelBuffer
格式進行處理,再以直播模式傳送至臉部偵測器。
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
,請參閱 CVPixelBuffer Apple 開發人員說明文件。
CMSampleBuffer
CMSampleBuffer
格式會儲存統一媒體類型的媒體範例,非常適合直播執行模式。iOS 相機的即時影格會透過 iOS AVCaptureVideoDataOutput 以 CMSampleBuffer
格式傳送。
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
,請參閱 CMSampleBuffer Apple 開發人員說明文件。
執行工作
如要執行臉部偵測器,請使用已指派的執行模式專用的 detect()
方法:
- 靜態圖片:
detect(image:)
- 影片:
detect(videoFrame:timestampInMilliseconds:)
- 直播:
detectAsync(image:timestampInMilliseconds:)
Face Detector 會傳回輸入圖片或影格內偵測到的臉孔。
以下程式碼範例提供簡單的範例,說明如何在這些不同的執行模式下執行 Face Detector:
Swift
圖片
let result = try faceDetector.detect(image: image)
影片
let result = try faceDetector.detect( videoFrame: image, timestampInMilliseconds: timestamp)
直播
try faceDetector.detectAsync( image: image, timestampInMilliseconds: timestamp)
Objective-C
圖片
MPPFaceDetectorResult *result = [faceDetector detectInImage:image error:nil];
影片
MPPFaceDetectorResult *result = [faceDetector detectInVideoFrame:image timestampInMilliseconds:timestamp error:nil];
直播
BOOL success = [faceDetector detectAsyncInImage:image timestampInMilliseconds:timestamp error:nil];
臉部偵測器程式碼範例會更詳細地說明這些模式的實作方式,包括 detect(image:)
、detect(videoFrame:timestampInMilliseconds:)
和 detectAsync(image:timestampInMilliseconds:)
。程式碼範例可讓使用者在處理模式之間切換,但這可能不是您使用情境所需的功能。
注意事項:
在影片模式或直播模式中執行時,您也必須向臉部偵測器工作提供輸入影格的時間戳記。
在圖片或影片模式中執行時,臉部偵測工作會封鎖目前的執行緒,直到處理輸入圖片或影格為止。為避免阻斷目前執行緒,請使用 iOS Dispatch 或 NSOperation 架構,在背景執行緒中執行處理作業。
在直播模式下執行時,臉部偵測器工作會立即傳回,且不會封鎖目前的執行緒。在處理每個輸入影格後,會使用臉部偵測結果呼叫
faceDetector(_:didFinishDetection:timestampInMilliseconds:error:)
方法。臉部偵測器會在專屬的序列調度佇列,以非同步方式叫用這個方法。如要在使用者介面上顯示結果,請在處理結果後將結果調度至主佇列。如果在 Face Detector 工作忙於處理其他影格時呼叫detectAsync
函式,Face Detector 會忽略新的輸入影格。
處理及顯示結果
執行推論後,臉部偵測器工作會傳回 FaceDetectorResult
物件,其中包含偵測到的臉部定界框,以及每個偵測到的臉部可信度分數。
以下範例顯示這項工作的輸出資料範例:
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)
下圖是工作輸出內容的視覺化呈現:
如需不含定界框的圖片,請參閱原始圖片。
臉部偵測器範例程式碼示範如何顯示結果。詳情請參閱程式碼範例。