ตรวจจับใบหน้าด้วย ML Kit บน iOS

คุณใช้ ML Kit เพื่อตรวจหาใบหน้าในรูปภาพและวิดีโอได้

ก่อนเริ่มต้น

  1. หากยังไม่ได้เพิ่ม Firebase ลงในแอป ให้ดำเนินการดังนี้ ขั้นตอนในคู่มือเริ่มต้นใช้งาน
  2. รวมไลบรารี ML Kit ไว้ใน Podfile ดังนี้
    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'
    
    หลังจากติดตั้งหรืออัปเดตพ็อดของโปรเจ็กต์แล้ว อย่าลืมเปิด Xcode โดยใช้ .xcworkspace
  3. ในแอป ให้นำเข้า Firebase ดังนี้

    Swift

    import Firebase

    Objective-C

    @import Firebase;

หลักเกณฑ์เกี่ยวกับรูปภาพที่ป้อน

เพื่อให้ ML Kit ตรวจจับใบหน้าได้อย่างแม่นยำ รูปภาพที่ป้อนต้องมีใบหน้า ที่แสดงด้วยข้อมูลพิกเซลที่เพียงพอ โดยทั่วไป แต่ละใบหน้าที่คุณต้องการ รูปภาพควรมีความละเอียดอย่างน้อย 100x100 พิกเซล หากคุณต้องการตรวจจับ รูปทรงของด้าน ML Kit ต้องการอินพุตที่มีความละเอียดสูงขึ้น โดยแต่ละใบหน้า ควรมีขนาดอย่างน้อย 200x200 พิกเซล

ถ้ากำลังตรวจจับใบหน้าในแอปพลิเคชัน แบบเรียลไทม์ คุณอาจต้องการ เพื่อพิจารณาขนาดโดยรวมของรูปภาพที่ป้อน รูปภาพขนาดเล็กกว่าได้ ประมวลผลเร็วขึ้น ดังนั้นหากต้องการลดเวลาในการตอบสนอง ให้จับภาพด้วยความละเอียดที่ต่ำลง (คำนึงถึงข้อกำหนดเกี่ยวกับความถูกต้องข้างต้น) และตรวจสอบให้แน่ใจว่า ใบหน้าของวัตถุใช้พื้นที่ในรูปภาพมากที่สุด ดูนี่ด้วย เคล็ดลับในการปรับปรุงประสิทธิภาพแบบเรียลไทม์

การโฟกัสของรูปภาพไม่ดีอาจทำให้ความแม่นยำลดลง หากคุณไม่ได้รับผลลัพธ์ที่ยอมรับได้ ลองขอให้ผู้ใช้จับภาพอีกครั้ง

การวางแนวของใบหน้าที่สัมพันธ์กับกล้องอาจส่งผลต่อลักษณะของใบหน้าด้วย มีฟีเจอร์ที่ ML Kit ตรวจพบ โปรดดู การตรวจจับใบหน้า แนวคิด

1. กำหนดค่าตัวตรวจจับใบหน้า

ก่อนที่จะใช้การตรวจจับใบหน้ากับรูปภาพ ถ้าต้องการเปลี่ยน การตั้งค่าเริ่มต้นของเครื่องตรวจจับใบหน้า ให้ระบุการตั้งค่าเหล่านั้นด้วย VisionFaceDetectorOptions คุณสามารถเปลี่ยน การตั้งค่าต่อไปนี้

การตั้งค่า
performanceMode fast (ค่าเริ่มต้น) | วันที่ accurate

เลือกความเร็วหรือความแม่นยำในการตรวจจับใบหน้า

landmarkMode none (ค่าเริ่มต้น) | วันที่ all

ไม่ว่าจะพยายามตรวจจับ "จุดสังเกต" บนใบหน้า เช่น ดวงตา หู จมูก แก้ม ปาก ของทุกใบหน้าที่ตรวจพบ

contourMode none (ค่าเริ่มต้น) | วันที่ all

เลือกว่าจะตรวจหารูปร่างของใบหน้าหรือไม่ เส้นโครงร่าง ตรวจพบเฉพาะใบหน้าที่โดดเด่นที่สุดในรูปภาพ

classificationMode none (ค่าเริ่มต้น) | วันที่ all

ไม่ว่าจะจำแนกใบหน้าออกเป็นหมวดหมู่ต่างๆ เช่น "การยิ้ม" หรือไม่ และ "ลืมตา"

minFaceSize CGFloat (ค่าเริ่มต้น: 0.1)

ขนาดต่ำสุดซึ่งสัมพันธ์กับภาพของใบหน้าที่จะตรวจจับ

isTrackingEnabled false (ค่าเริ่มต้น) | วันที่ true

กำหนดรหัสใบหน้าหรือไม่ ซึ่งสามารถใช้เพื่อติดตาม ผ่านรูปภาพต่างๆ

โปรดทราบว่าเมื่อเปิดใช้การตรวจจับเส้นโครงร่าง จะมีเพียงใบหน้าเดียวเท่านั้น ดังนั้นการติดตามใบหน้าจึงไม่ได้ให้ผลลัพธ์ที่เป็นประโยชน์ สำหรับกรณีนี้ และหากต้องการปรับปรุงความเร็วในการตรวจจับ อย่าเปิดใช้ทั้งสองแบบ การตรวจจับและการติดตามใบหน้า

เช่น สร้าง 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 ไปยัง detect(in:) ของ VisionFaceDetector วิธีการ:

  1. รับอินสแตนซ์ของ VisionFaceDetector:

    Swift

    lazy var vision = Vision.vision()
    
    let faceDetector = vision.faceDetector(options: options)

    Objective-C

    FIRVision *vision = [FIRVision vision];
    FIRVisionFaceDetector *faceDetector = [vision faceDetector];
    // Or, to change the default settings:
    // FIRVisionFaceDetector *faceDetector =
    //     [vision faceDetectorWithOptions:options];
  2. สร้างออบเจ็กต์ VisionImage โดยใช้ UIImage หรือ CMSampleBufferRef

    วิธีใช้ UIImage

    1. หากจำเป็น ให้หมุนรูปภาพเพื่อให้imageOrientation พร็อพเพอร์ตี้คือ .up
    2. สร้างออบเจ็กต์ VisionImage โดยใช้การหมุนที่ถูกต้อง UIImage ไม่ระบุข้อมูลเมตาการหมุนเวียน ซึ่งเป็นค่าเริ่มต้น ต้องใช้ค่า .topLeft

      Swift

      let image = VisionImage(image: uiImage)

      Objective-C

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

    วิธีใช้ CMSampleBufferRef

    1. สร้างออบเจ็กต์ VisionImageMetadata ที่ระบุ การวางแนวของข้อมูลภาพที่มีอยู่ใน บัฟเฟอร์ CMSampleBufferRef

      วิธีดูการวางแนวรูปภาพ

      Swift

      func 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;
        }
      }

      จากนั้นสร้างออบเจ็กต์ข้อมูลเมตา ดังนี้

      Swift

      let cameraPosition = AVCaptureDevice.Position.back  // Set to the capture device you used.
      let metadata = VisionImageMetadata()
      metadata.orientation = imageOrientation(
          deviceOrientation: UIDevice.current.orientation,
          cameraPosition: cameraPosition
      )

      Objective-C

      FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init];
      AVCaptureDevicePosition cameraPosition =
          AVCaptureDevicePositionBack;  // Set to the capture device you used.
      metadata.orientation =
          [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
                                       cameraPosition:cameraPosition];
    2. สร้างออบเจ็กต์ VisionImage โดยใช้ ออบเจ็กต์ CMSampleBufferRef และข้อมูลเมตาการหมุน:

      Swift

      let image = VisionImage(buffer: sampleBuffer)
      image.metadata = metadata

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. จากนั้นส่งรูปภาพไปยังเมธอด detect(in:)

    Swift

    faceDetector.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;
  }
}

ตัวอย่างคอนทัวร์ของใบหน้า

เมื่อเปิดใช้การตรวจจับเส้นโครงร่างใบหน้า คุณจะได้รับรายการจุดสำหรับ ลักษณะใบหน้าแต่ละรายการที่ตรวจพบ จุดเหล่านี้แสดงรูปร่างของ ดู Face ภาพรวมแนวคิดการตรวจจับสำหรับรายละเอียดเกี่ยวกับรูปร่าง ที่มีตัวแทน

ภาพต่อไปนี้แสดงให้เห็นว่าจุดเหล่านี้แมปกับด้านอย่างไร (คลิก ภาพเพื่อขยาย):

การตรวจจับใบหน้าแบบเรียลไทม์

หากคุณต้องการใช้การตรวจจับใบหน้าในแอปพลิเคชันแบบเรียลไทม์ ให้ทำตามดังนี้ เพื่อให้ได้อัตราเฟรมที่ดีที่สุด

  • กำหนดค่าตัวตรวจจับใบหน้าเพื่อใช้ การตรวจจับเส้นโครงร่างใบหน้าหรือการแยกประเภทและการตรวจจับจุดสังเกต แต่ไม่ใช่ทั้ง 2 อย่าง

    การตรวจจับรูปร่าง
    การตรวจจับจุดสังเกต
    การจัดประเภท
    การตรวจหาและการแยกประเภทจุดสังเกต
    การตรวจจับเส้นโค้งและการตรวจจับจุดสังเกต
    การตรวจหาและการแยกประเภทรูปร่าง
    การตรวจจับเส้นโค้ง การตรวจหาจุดสังเกต และการแยกประเภท

  • เปิดใช้โหมด fast (เปิดใช้โดยค่าเริ่มต้น)

  • ลองจับภาพที่ความละเอียดต่ำลง แต่โปรดทราบว่า ข้อกำหนดขนาดรูปภาพของ API นี้

  • กดคันเร่งไปยังตัวตรวจจับ หากเฟรมวิดีโอใหม่กลายเป็น วางเฟรมได้ในขณะที่ตัวตรวจจับกำลังทำงานอยู่
  • หากคุณกำลังใช้เอาต์พุตของเครื่องมือตรวจสอบเพื่อวางซ้อนกราฟิก รูปภาพอินพุต รับผลลัพธ์จาก ML Kit ก่อน จากนั้นจึงแสดงผลรูปภาพ ซ้อนทับในขั้นตอนเดียว การทำเช่นนี้จะช่วยให้แสดงผลบนพื้นผิวจอแสดงผล เพียงครั้งเดียวสำหรับเฟรมอินพุตแต่ละเฟรม โปรดดู previewOverlayView และ FIRDetectionOverlayView ในตัวอย่างแอป Showcase