在iOS上使用ML Kit识别人脸

你可以在iOS上使用ML Kit来在图像和视频中识别人脸。

请参阅GitHub上的ML Kit快速入门示例,了解正在使用的此API的示例。

在开始之前

  1. 如果您还没有将Firebase添加到您的程序当中,那您可以从开始指南来开始您的工作。

  2. 将ML kit库放进您的Podfile中:

    1. pod 'Firebase/Core'
    2. pod 'Firebase/MLVision'
    3. pod 'Firebase/MLVisionFaceModel'

​ 而后每次您要安装或者升级您的Pods的时候,请确保使用您的Xcode项目的.xcworkspace来打开它。

  1. 在您的程序中,引入Firebase:

    Swift:

    1. import Firebase

    Objective-C:

    1. @import Firebase;
  2. 从项目设置的Build Settings > Build Options 部分禁用项目的Bitcode生成。

在设备上识别人脸

设置人脸识别器

在您对图像进行人脸识别以前,如果您想要修改任何关于人脸识别的默认设定,请通过VisionFaceDetectorOptions 对象来指定这些设定。您可以修改以下设定:

设置 参数 参数2 解释
识别模式 fast (默认“快速”) accurate 取决于您在人脸识别中是喜欢速度或准确性。
识别特征点 none (默认“无”) all 是否尝试识别面部“特征点”:眼睛,耳朵,鼻子,脸颊,嘴巴。
辨认脸部 none (默认“无”) all 是否将人脸分类为“微笑”和“睁眼”等类别。
脸部最小识别 CGFloat (默认: 0.1) 要检测的脸部相对于图像的最小尺寸。
允许人脸追踪 false (默认) true 是否分配人脸ID,可用于跟踪图像中的人脸。

例如,为了修改以上所有的默认设定,在下边的例子中构建一个 VisionFaceDetectorOptions 对象:

Swift:

  1. let options = VisionFaceDetectorOptions()
  2. options.modeType = .accurate
  3. options.landmarkType = .all
  4. options.classificationType = .all
  5. options.minFaceSize = CGFloat(0.1)
  6. options.isTrackingEnabled = true

Objective-C:

  1. FIRVisionFaceDetectorOptions *options = [[FIRVisionFaceDetectorOptions alloc] init];
  2. options.modeType = FIRVisionFaceDetectorModeAccurate;
  3. options.landmarkType = FIRVisionFaceDetectorLandmarkAll;
  4. options.classificationType = FIRVisionFaceDetectorClassificationAll;
  5. options.minFaceSize = (CGFloat) 0.2f;
  6. options.isTrackingEnabled = YES;

运行人脸识别器

为了在图片中识别人脸,需要将照片作为 UIImage 或者 CMSampleBufferRef 传递到 VisionFaceDetectordetect(in:)方法:

  1. VisionFaceDetector 的一个例子:

    Swift:

    1. lazy var vision = Vision.vision()
    2. let faceDetector = vision.faceDetector(options: options) // Check console for errors.
    3. // 或者使用以下默认设定:
    4. // let faceDetector = vision?.faceDetector()

    Objective-C:

    1. FIRVision *vision = [FIRVision vision];
    2. FIRVisionFaceDetector *detector = [vision faceDetector];
    3. // 或者为了修改默认设定:
    4. // FIRVisionFaceDetector *detector =
    5. // [vision faceDetectorWithOptions:options];
  2. 使用UIImage 或者 CMSampleBufferRef创建 VisionImage 对象。

    使用UIImage :

    1. 如果有必要,旋转图像,使得它的imageOrientation的属性是.up

    2. VisionImage使用正确旋转的对象创建一个对象 UIImage。不要指定任何旋转元数据 - 默认值.topLeft,必须使用。

      Swift:

      1. let image = VisionImage(image: uiImage)

      Objective-C:

      1. FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];

    使用CMSampleBufferRef

    1. 创建一个VisionImageMetadata对象,该对象指定包含在CMSampleBufferRef缓冲区中的图像数据的方向 。

      例如,如果图像数据必须顺时针旋转90度才能保持直立:

      Swift:

      1. let metadata = VisionImageMetadata()
      2. metadata.orientation = .rightTop // Row为0在右边,column为0则是在顶端

      Objective-C:

      1. // Row为0在右边,column为0则是在顶端
      2. FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init];
      3. metadata.orientation = FIRVisionDetectorImageOrientationRightTop;
    2. VisionImage使用CMSampleBufferRef对象和旋转元数据创建一个对象 :

      Swift:

      1. let image = VisionImage(buffer: bufferRef)
      2. image.metadata = metadata

      Objective-C:

      1. FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:buffer];
      2. image.metadata = metadata;
  3. 然后,将图像传递给该detect(in:)方法:

    Swift:

    1. faceDetector.detect(in: visionImage) { (faces, error) in
    2. guard error == nil, let faces = faces, !faces.isEmpty else {
    3. // 错误,您应该检查控制台。
    4. // ...
    5. return
    6. }
    7. // 脸部识别
    8. // ...
    9. }

    Objective-C:

    1. [detector detectInImage:image
    2. completion:^(NSArray<FIRVisionFace *> *faces,
    3. NSError *error) {
    4. if (error != nil) {
    5. return;
    6. } else if (faces != nil) {
    7. // 识别人脸
    8. }
    9. }];

获取检测到的面部有关信息

如果人脸检测操作成功,则人脸识别器将一组VisionFace对象传递给完成处理程序(completion handler)。每个 VisionFace对象代表在图像中检测到的脸部。对于每个人脸,您可以在输入图像中获得其边界坐标以及您配置人脸识别器查找的任何其他信息。例如:

Swift:

  1. for face in faces {
  2. let frame = face.frame
  3. if face.hasHeadEulerAngleY {
  4. let rotY = face.headEulerAngleY // 头部转向右rotY角
  5. }
  6. if face.hasHeadEulerAngleZ {
  7. let rotZ = face.headEulerAngleZ // 头部转向上rotZ角
  8. }
  9. // 如果特征点识别开启了(嘴,耳,眼,脸颊,还有鼻子可以检测):
  10. if let leftEye = face.landmark(ofType: .leftEye) {
  11. let leftEyePosition = leftEye.position
  12. }
  13. // 如果辨认开启了:
  14. if face.hasSmilingProbability {
  15. let smileProb = face.smilingProbability
  16. }
  17. if face.hasRightEyeOpenProbability {
  18. let rightEyeOpenProb = face.rightEyeOpenProbability
  19. }
  20. // 如果脸部追踪开启了:
  21. if face.hasTrackingID {
  22. let trackingId = face.trackingID
  23. }
  24. }

Objective-C:

  1. for (FIRVisionFace *face in faces) {
  2. // 图像中脸的边界
  3. CGRect frame = face.frame;
  4. if (face.hasHeadEulerAngleY) {
  5. CGFloat rotY = face.headEulerAngleY; // 头部转向右rotY角
  6. }
  7. if (face.hasHeadEulerAngleZ) {
  8. CGFloat rotZ = face.headEulerAngleZ; // 头部转向上rotZ角
  9. }
  10. // 如果特征点识别开启了(嘴,耳,眼,脸颊,还有鼻子可以检测)
  11. FIRVisionFaceLandmark *leftEar = [face landmarkOfType:FIRFaceLandmarkTypeLeftEar];
  12. if (leftEar != nil) {
  13. FIRVisionPoint *leftEarPosition = leftEar.position;
  14. }
  15. // 如果辨认开启了
  16. if (face.hasSmilingProbability) {
  17. CGFloat smileProb = face.smilingProbability;
  18. }
  19. if (face.hasRightEyeOpenProbability) {
  20. CGFloat rightEyeOpenProb = face.rightEyeOpenProbability;
  21. }
  22. // 如果脸部追踪开启了
  23. if (face.hasTrackingID) {
  24. NSInteger trackingID = face.trackingID;
  25. }
  26. }