ตรวจจับใบหน้าด้วย 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'
    
    หลังจากที่คุณติดตั้งหรืออัปเดต Pod ของโปรเจ็กต์แล้ว อย่าลืมเปิดโปรเจ็กต์ Xcode โดยใช้ .xcworkspace
  3. ในแอปของคุณ ให้นำเข้า Firebase:

    สวิฟท์

    import Firebase

    วัตถุประสงค์-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

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

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

ตัวอย่างเช่น สร้างออบเจ็กต์ VisionFaceDetectorOptions ตามตัวอย่างใดตัวอย่างหนึ่งต่อไปนี้:

สวิฟท์

// 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

วัตถุประสงค์-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:) :

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

    สวิฟท์

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

    วัตถุประสงค์-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

      สวิฟท์

      let image = VisionImage(image: uiImage)

      วัตถุประสงค์-C

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

    วิธีใช้ CMSampleBufferRef :

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

      เพื่อให้ได้การวางแนวของภาพ:

      สวิฟท์

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

      วัตถุประสงค์-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;
        }
      }

      จากนั้นสร้างวัตถุข้อมูลเมตา:

      สวิฟท์

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

      วัตถุประสงค์-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 และข้อมูลเมตาการหมุน:

      สวิฟท์

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

      วัตถุประสงค์-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. จากนั้นส่งภาพไปยังวิธี detect(in:) :

    สวิฟท์

    faceDetector.process(visionImage) { faces, error in
      guard error == nil, let faces = faces, !faces.isEmpty else {
        // ...
        return
      }
    
      // Faces detected
      // ...
    }
    

    วัตถุประสงค์-C

    [faceDetector detectInImage:image
                     completion:^(NSArray<FIRVisionFace *> *faces,
                                  NSError *error) {
      if (error != nil) {
        return;
      } else if (faces != nil) {
        // Recognized faces
      }
    }];
    

3. รับข้อมูลเกี่ยวกับใบหน้าที่ตรวจพบ

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

สวิฟท์

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

วัตถุประสงค์-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 ในแอปตัวอย่าง Showcase