ตรวจจับใบหน้าด้วย 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

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

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

เช่น สร้างออบเจ็กต์ 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;
  }
}

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

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

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

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

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

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

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

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

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

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