你可以使用 ML Kit 偵測圖片和影片中的臉孔。
事前準備
- 如果尚未將 Firebase 加入應用程式,請按照下列步驟操作: 入門指南中的步驟。
- 在 Podfile 中加入 ML Kit 程式庫:
  pod 'Firebase/MLVision', '6.25.0' # If you want to detect face contours (landmark detection and classification # don't require this additional model): pod 'Firebase/MLVisionFaceModel', '6.25.0' .xcworkspace。
- 在應用程式中匯入 Firebase:
  Swiftimport Firebase Objective-C@import Firebase; 
輸入圖片規範
為了讓 ML Kit 準確偵測臉孔,輸入圖片必須包含臉孔 以充足的像素資料表示基本上, 至少需要 100x100 像素如要偵測 臉部輪廓線,則 ML Kit 需要較高的解析度輸入: 至少應為 200 x 200 像素。
如果您在即時應用程式中偵測臉孔,您可能還需要 將輸入圖片的整體尺寸納入考量較小的圖片 加快處理速度,因此為了縮短延遲時間,擷取解析度較低的圖片 (請謹記上述準確率規定),並確保 拍攝主體的臉孔會盡量佔滿圖片。另請參閱 即時效能改善秘訣。
圖片焦點不佳可能會降低準確性。如果沒有可接受的結果 請試著要求使用者重新擷取圖片
臉部與相機相對的方向也會影響臉部表情 ML Kit 偵測到的特徵詳情請見 臉部偵測 概念。
1. 設定臉部偵測工具
為圖像套用臉部偵測功能之前,如果想變更 臉部偵測器的預設設定,請用VisionFaceDetectorOptions 物件。您可以
以下設定:
| 設定 | |
|---|---|
| performanceMode | fast(預設) |accurate改善偵測臉孔的速度或精確度。 | 
| landmarkMode | none(預設) |all是否要嘗試偵測臉部「地標」—對 偵測到的臉孔、鼻子、臉頰、嘴巴。 | 
| contourMode | none(預設) |all是否偵測臉部特徵的輪廓。輪廓線是 只會偵測到圖片中最醒目的臉孔。 | 
| classificationMode | none(預設) |all是否將臉孔分類 (例如「微笑」)、 和「睜開雙眼」 | 
| minFaceSize | CGFloat(預設:0.1)待偵測臉孔的最小尺寸 (相對於圖片)。 | 
| isTrackingEnabled | false(預設) |true是否要指派臉孔 ID,以用於追蹤 圖像中的人物臉孔。 請注意,啟用輪廓偵測功能後,只有一張臉孔 因此臉部追蹤功能無法產生實用的結果。為此 原因及加快偵測速度,請勿同時啟用兩個輪廓線 偵測及臉部追蹤 | 
例如,建構 VisionFaceDetectorOptions
物件,如下所示:
Swift
// High-accuracy landmark detection and face classification let options = VisionFaceDetectorOptions() options.performanceMode = .accurate options.landmarkMode = .all options.classificationMode = .all // Real-time contour detection of multiple faces let options = VisionFaceDetectorOptions() options.contourMode = .all
Objective-C
// High-accuracy landmark detection and face classification FIRVisionFaceDetectorOptions *options = [[FIRVisionFaceDetectorOptions alloc] init]; options.performanceMode = FIRVisionFaceDetectorPerformanceModeAccurate; options.landmarkMode = FIRVisionFaceDetectorLandmarkModeAll; options.classificationMode = FIRVisionFaceDetectorClassificationModeAll; // Real-time contour detection of multiple faces FIRVisionFaceDetectorOptions *options = [[FIRVisionFaceDetectorOptions alloc] init]; options.contourMode = FIRVisionFaceDetectorContourModeAll;
2. 執行臉部偵測工具
如要偵測圖片中的臉孔,請將圖片以UIImage 或
CMSampleBufferRef到VisionFaceDetector的detect(in:)
方法:
- 取得 VisionFaceDetector的執行個體:Swiftlazy var vision = Vision.vision() let faceDetector = vision.faceDetector(options: options) Objective-CFIRVision *vision = [FIRVision vision]; FIRVisionFaceDetector *faceDetector = [vision faceDetector]; // Or, to change the default settings: // FIRVisionFaceDetector *faceDetector = // [vision faceDetectorWithOptions:options]; 
- 
    使用 UIImage或VisionImageCMSampleBufferRef。如何使用 UIImage:- 視需要旋轉圖片,使其 imageOrientation屬性為.up。
- 使用正確旋轉的做法建立 VisionImage物件UIImage。請勿指定任何輪替中繼資料 (預設值) 值 (.topLeft),則必須使用。Swiftlet image = VisionImage(image: uiImage) Objective-CFIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage]; 
 如何使用 CMSampleBufferRef:- 
    建立 VisionImageMetadata物件,以指定 包含的圖片資料方向CMSampleBufferRef緩衝區。如何取得圖片方向: Swiftfunc imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> VisionDetectorImageOrientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftTop : .rightTop case .landscapeLeft: return cameraPosition == .front ? .bottomLeft : .topLeft case .portraitUpsideDown: return cameraPosition == .front ? .rightBottom : .leftBottom case .landscapeRight: return cameraPosition == .front ? .topRight : .bottomRight case .faceDown, .faceUp, .unknown: return .leftTop } } Objective-C- (FIRVisionDetectorImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationLeftTop; } else { return FIRVisionDetectorImageOrientationRightTop; } case UIDeviceOrientationLandscapeLeft: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationBottomLeft; } else { return FIRVisionDetectorImageOrientationTopLeft; } case UIDeviceOrientationPortraitUpsideDown: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationRightBottom; } else { return FIRVisionDetectorImageOrientationLeftBottom; } case UIDeviceOrientationLandscapeRight: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationTopRight; } else { return FIRVisionDetectorImageOrientationBottomRight; } default: return FIRVisionDetectorImageOrientationTopLeft; } } 然後,建立中繼資料物件: Swiftlet cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition ) Objective-CFIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init]; AVCaptureDevicePosition cameraPosition = AVCaptureDevicePositionBack; // Set to the capture device you used. metadata.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition]; 
- 請使用VisionImageCMSampleBufferRef物件和輪替中繼資料:Swiftlet image = VisionImage(buffer: sampleBuffer) image.metadata = metadata Objective-CFIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata; 
 
- 視需要旋轉圖片,使其 
- 
    接著,將圖片傳遞至 detect(in:)方法:SwiftfaceDetector.process(visionImage) { faces, error in guard error == nil, let faces = faces, !faces.isEmpty else { // ... return } // Faces detected // ... } Objective-C[faceDetector detectInImage:image completion:^(NSArray<FIRVisionFace *> *faces, NSError *error) { if (error != nil) { return; } else if (faces != nil) { // Recognized faces } }]; 
3. 取得系統偵測到的臉孔資訊
如果臉部偵測功能成功執行,臉部偵測工具會傳送陣列VisionFace 物件至完成處理常式。每項
VisionFace 物件代表在圖片中偵測到的臉孔。適用對象
您可以在輸入圖像中找到其邊界座標,也可以取得
你設定臉部偵測工具尋找的任何其他資訊。例如:
Swift
for face in faces { let frame = face.frame if face.hasHeadEulerAngleY { let rotY = face.headEulerAngleY // Head is rotated to the right rotY degrees } if face.hasHeadEulerAngleZ { let rotZ = face.headEulerAngleZ // Head is rotated upward rotZ degrees } // If landmark detection was enabled (mouth, ears, eyes, cheeks, and // nose available): if let leftEye = face.landmark(ofType: .leftEye) { let leftEyePosition = leftEye.position } // If contour detection was enabled: if let leftEyeContour = face.contour(ofType: .leftEye) { let leftEyePoints = leftEyeContour.points } if let upperLipBottomContour = face.contour(ofType: .upperLipBottom) { let upperLipBottomPoints = upperLipBottomContour.points } // If classification was enabled: if face.hasSmilingProbability { let smileProb = face.smilingProbability } if face.hasRightEyeOpenProbability { let rightEyeOpenProb = face.rightEyeOpenProbability } // If face tracking was enabled: if face.hasTrackingID { let trackingId = face.trackingID } }
Objective-C
for (FIRVisionFace *face in faces) { // Boundaries of face in image CGRect frame = face.frame; if (face.hasHeadEulerAngleY) { CGFloat rotY = face.headEulerAngleY; // Head is rotated to the right rotY degrees } if (face.hasHeadEulerAngleZ) { CGFloat rotZ = face.headEulerAngleZ; // Head is tilted sideways rotZ degrees } // If landmark detection was enabled (mouth, ears, eyes, cheeks, and // nose available): FIRVisionFaceLandmark *leftEar = [face landmarkOfType:FIRFaceLandmarkTypeLeftEar]; if (leftEar != nil) { FIRVisionPoint *leftEarPosition = leftEar.position; } // If contour detection was enabled: FIRVisionFaceContour *upperLipBottomContour = [face contourOfType:FIRFaceContourTypeUpperLipBottom]; if (upperLipBottomContour != nil) { NSArray<FIRVisionPoint *> *upperLipBottomPoints = upperLipBottomContour.points; if (upperLipBottomPoints.count > 0) { NSLog("Detected the bottom contour of the subject's upper lip.") } } // If classification was enabled: if (face.hasSmilingProbability) { CGFloat smileProb = face.smilingProbability; } if (face.hasRightEyeOpenProbability) { CGFloat rightEyeOpenProb = face.rightEyeOpenProbability; } // If face tracking was enabled: if (face.hasTrackingID) { NSInteger trackingID = face.trackingID; } }
臉部輪廓範例
啟用臉部輪廓偵測功能後,畫面上會列出 偵測到的臉部特徵這些點代表 而不是每個特徵的分數查看臉孔 偵測概念總覽,進一步瞭解輪廓如何 。
下圖說明這些點如何對應到表面 (按一下 可放大的圖片):
即時臉部偵測
如要在即時應用程式中使用臉部偵測功能,請按照下列步驟操作: 實現最佳影格速率:
- 設定臉部偵測工具, 臉部輪廓偵測或分類及地標偵測,但兩者只能擇一: - 輪廓偵測 
 地標偵測
 分類
 地標偵測與分類
 模型偵測和地標偵測
 模型偵測與分類
 輪廓偵測、地標偵測與分類
- 啟用 - fast模式 (預設為啟用)。
- 建議以較低的解析度拍攝圖片。請特別注意 這個 API 的圖片尺寸規定 
- 限制對偵測工具的呼叫。如果新的影片影格 因此請在偵測器執行時捨棄影格。
- 使用偵測工具的輸出內容將圖像重疊 先從 ML Kit 取得結果,然後算繪圖片 並疊加單一步驟這麼一來,您的應用程式就會算繪到顯示途徑 每個輸入影格只能建立一次請參閱 previewOverlayView 和 FIRDetectionOverlayView 例如,在展示範例應用程式中使用類別。