iOS 臉部偵測指南

臉部偵測工作可讓你偵測圖片或影片中的臉孔。別擔心!您可以使用 這項工作能找出相框內的人臉和臉部特徵這項工作會使用 適用於單一圖片或連續串流的機器學習 (ML) 模型 生成的圖片這項工作會輸出臉孔位置資訊,以及下列臉部金鑰 點:左眼、右眼、鼻子、嘴巴、左眼視力和右眼

您可在 GitHub 取得本操作說明中所述的程式碼範例。 如要查看這項工作的實際運作情形,請參閱這個網頁 示範。如要 瞭解這項產品的功能、模型和設定選項 請參閱 總覽

程式碼範例

MediaPipe Tasks 範例程式碼是臉部偵測器的簡易實作方式 App Engine 應用程式這個範例會使用實體 Android 裝置上的相機來偵測 分別出現在連續影片串流中應用程式也可以偵測圖像中的臉孔, 觀看裝置圖片庫中的影片

你可以將這個應用程式做為起點,開始使用 iOS 應用程式,也可以參照這個應用程式 做出決定臉部偵測器範例程式碼 GitHub

下載程式碼

以下說明如何建立範例的本機副本 git 指令列工具編寫程式碼。

如要下載範例程式碼,請按照下列步驟操作:

  1. 使用下列指令複製 git 存放區:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. 您也可以設定 Git 執行個體來使用稀疏結帳功能, 只有臉部偵測器範例應用程式的檔案:

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

建立範例程式碼的本機版本後,您可以安裝 MediaPipe 工作程式庫,使用 Xcode 開啟專案,然後執行應用程式。適用對象 操作說明,請參閱 iOS 設定指南

重要元件

下列檔案包含臉部偵測器範例的重要程式碼 應用程式:

設定

本節說明設定開發環境的重要步驟,以及 程式碼專案才能使用 Face Detector如需設定 使用 MediaPipe 工作 (包括平台版本) 的開發環境 規定,請參閱 iOS 設定指南

依附元件

臉部偵測器會使用必須安裝的 MediaPipeTasksVision 程式庫 開發應用程式這個程式庫同時與 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 工作需要與 透過這項工作如要進一步瞭解 臉部偵測器,請參閱工作總覽:Models 專區

選取並下載模型,然後用 Xcode 將模型新增到專案目錄。 如需將檔案新增至 Xcode 專案的操作說明,請參閱管理 Xcode 中的檔案和資料夾 專案

使用 BaseOptions.modelAssetPath 屬性指定模型的路徑 。如需程式碼範例,請參閱下一節。

建立工作

您可以呼叫其中一項初始化器來建立臉部偵測工作。 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 設定任務的執行模式。在架構中 模式:

圖片:單一圖片輸入模式。

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:) 方法, 臉部偵測器處理完臉部偵測結果後 的每個影格

選項名稱 說明 值範圍 預設值
faceDetectorLiveStreamDelegate 啟用臉部偵測以非同步接收臉部偵測結果 。類別的執行個體必須設為此屬性 實作 faceDetector(_:didFinishDetection:timestampInMilliseconds:error:) 方法。 不適用 未設定

準備資料

您必須先將輸入圖片或影格轉換為 MPImage 物件。 然後把它傳給臉部偵測器MPImage 支援不同類型的 iOS 圖片 並且可在任何執行模式中使用,以便進行推論。如要 關於「MPImage」的資訊,請參閱 MPImage API

根據您的用途和執行模式,選擇 iOS 圖片格式 應用程式需要。MPImage 接受 UIImageCVPixelBufferCMSampleBuffer 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];
    

本範例使用預設值來初始化 MPImage UIImage.Orientation.Up 方向。您可以使用任一支援的任一種初始化 MPImage UIImage.Orientation 輕鬆分配獎金臉部偵測器不支援鏡像螢幕方向,例如 .upMirrored.downMirrored.leftMirrored.rightMirrored

如要進一步瞭解 UIImage,請參閱 UIImage Apple 開發人員 說明文件

CVPixelBuffer

CVPixelBuffer 格式非常適合會產生影格的應用程式 並使用 iOS CoreImage 處理流程

CVPixelBuffer 格式非常適合下列執行模式:

  • 圖片:應用程式在經過處理後產生 CVPixelBuffer 張圖片 也可將使用 iOS 的 CoreImage 架構傳送至 執行映像檔執行模式

  • 影片:您可以將影片影格轉換為 CVPixelBuffer 格式 並傳送到視訊模式的臉部偵測器

  • 直播:系統可能會轉換使用 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 以 CMSampleBuffer 格式非同步提供 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];
    

如要進一步瞭解 CMSampleBuffer,請參閱 CMSampleBuffer Apple 顯像組件 說明文件

執行工作

如要執行臉部偵測器,請使用已指派的 detect() 方法 執行模式:

  • 靜態圖片:detect(image:)
  • 影片:detect(videoFrame:timestampInMilliseconds:)
  • 直播:detectAsync(image:timestampInMilliseconds:)

臉部偵測器會在輸入圖片或影格中傳回偵測到的臉孔。

以下程式碼範例顯示如何在以下應用程式中執行臉部偵測器的簡單範例: 不同的跑步模式

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 的執行緒 調度NSOperation 架構。

  • 在直播模式下執行時,臉部偵測器工作會立即回傳 但不會封鎖目前的執行緒該函式會叫用 faceDetector(_:didFinishDetection:timestampInMilliseconds:error:) 種方式 每個輸入影格處理完成後,臉部偵測結果就會與臉部偵測結果相符 臉部偵測器會在專屬序列以非同步方式叫用這個方法 調度佇列。為了在使用者介面顯示結果,請調度 結果傳送到主要佇列。如果detectAsync 函式偵測器工作正忙著處理其他工作時 影格時,臉部偵測器會忽略新的輸入框。

處理及顯示結果

在執行推論時,臉部偵測器工作會傳回 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)

下圖是工作輸出內容的視覺化呈現:

如果是沒有定界框的圖片,請參閱原始圖片

臉部偵測器範例程式碼示範如何顯示結果。詳情請參閱 程式碼範例