iOS'te ML Kiti ile yüzleri algılama

Görüntü ve videodaki yüzleri algılamak için ML Kiti'ni kullanabilirsiniz.

Deneyin

Başlamadan önce

  1. Aşağıdaki ML Kiti kapsüllerini Podfile'ınıza ekleyin:
    pod 'GoogleMLKit/FaceDetection', '3.2.0'
    
  2. Projenizin Kapsüllerini yükledikten veya güncelledikten sonra Xcode projenizi, .xcworkspace ile açın. ML Kit, Xcode 12.4 veya üzeri sürümlerde desteklenir.

Resim kuralları girin

Yüz tanıma için en az 480x360 piksel boyutlarında bir resim kullanmanız gerekir. ML Kit'in yüzleri doğru şekilde algılayabilmesi için giriş görüntülerinin yeterli sayıda piksel verisiyle temsil edilen yüzler içermesi gerekir. Genel olarak, bir resimde algılamak istediğiniz her yüz en az 100x100 piksel olmalıdır. Yüzlerin dış hatlarını algılamak istiyorsanız ML Kit daha yüksek çözünürlüklü giriş gerektirir: her yüz en az 200x200 piksel olmalıdır.

Yüzleri gerçek zamanlı bir uygulamada algılarsanız giriş resimlerinin genel boyutlarını da dikkate almak isteyebilirsiniz. Daha küçük resimler daha hızlı işlenebilir. Bu nedenle gecikmeyi azaltmak için görüntüleri daha düşük çözünürlüklerde yakalayın ancak yukarıdaki doğruluk gereksinimlerini göz önünde bulundurarak öznenin yüzünün mümkün olduğunca çok alanını kapladığından emin olun. Ayrıca, gerçek zamanlı performansı iyileştirmeye yönelik ipuçlarını inceleyin.

Yetersiz resim odağı da doğruluğu etkileyebilir. Kabul edilebilir sonuçlar alamazsanız kullanıcıdan resmi yeniden yakalamasını isteyin.

Yüzün kameraya göre yönü, ML Kit'in algıladığı yüz özelliklerini de etkileyebilir. Yüz Algılama Kavramları bölümünü inceleyin.

1. Yüz algılayıcıyı yapılandırma

Bir görüntüye yüz algılama uygulamadan önce, yüz algılayıcının varsayılan ayarlarından herhangi birini değiştirmek isterseniz bu ayarları bir FaceDetectorOptions nesnesiyle belirtin. Aşağıdaki ayarları değiştirebilirsiniz:

Ayarlar
performanceMode fast (varsayılan) | accurate

Yüzleri algılarken hızı veya doğruluğu tercih edin.

landmarkMode none (varsayılan) | all

Algılanan tüm yüzlerin yüzdeki "yer lekeleri" (gözler, kulaklar, burun, yanaklar, ağızlar) algılanmaya çalışılıp çalıştırılmayacağı.

contourMode none (varsayılan) | all

Yüz özelliklerinin sınırlarının algılanıp algılanmayacağı. Konturlar, bir resimde yalnızca en belirgin yüz için algılanır.

classificationMode none (varsayılan) | all

Yüzlerin "gülümseme" ve "gözler açık" gibi kategorilere ayrılıp sınıflandırılmayacağı.

minFaceSize CGFloat (varsayılan: 0.1)

Başın genişliğinin resmin genişliğine oranı olarak ifade edilen, istenen en küçük yüz boyutunu ayarlar.

isTrackingEnabled false (varsayılan) | true

Yüzlere, resimler arasında yüzleri izlemek için kullanılabilecek bir kimlik atanıp atanmayacağı.

Kontur algılama etkinleştirildiğinde yalnızca bir yüz algılandığı için yüz izlemenin faydalı sonuçlar üretmediğini unutmayın. Bu nedenle algılama hızını iyileştirmek için hem kontur algılamayı hem de yüz izlemeyi etkinleştirmeyin.

Örneğin, aşağıdaki örneklerden biri gibi bir FaceDetectorOptions nesnesi oluşturun:

Swift

// High-accuracy landmark detection and face classification
let options = FaceDetectorOptions()
options.performanceMode = .accurate
options.landmarkMode = .all
options.classificationMode = .all

// Real-time contour detection of multiple faces
// options.contourMode = .all

Objective-C

// High-accuracy landmark detection and face classification
MLKFaceDetectorOptions *options = [[MLKFaceDetectorOptions alloc] init];
options.performanceMode = MLKFaceDetectorPerformanceModeAccurate;
options.landmarkMode = MLKFaceDetectorLandmarkModeAll;
options.classificationMode = MLKFaceDetectorClassificationModeAll;

// Real-time contour detection of multiple faces
// options.contourMode = MLKFaceDetectorContourModeAll;

2. Giriş görüntüsünü hazırlama

Bir resimdeki yüzleri algılamak için process(_:completion:) veya results(in:) yöntemini kullanarak resmi FaceDetector öğesine UIImage veya CMSampleBufferRef olarak iletin:

UIImage veya CMSampleBuffer kullanarak VisionImage nesnesi oluşturun.

UIImage kullanıyorsanız aşağıdaki adımları uygulayın:

  • UIImage ile bir VisionImage nesnesi oluşturun. Doğru .orientation değerini belirttiğinizden emin olun.

    Swift

    let image = VisionImage(image: UIImage)
    visionImage.orientation = image.imageOrientation

    Objective-C

    MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image];
    visionImage.orientation = image.imageOrientation;

CMSampleBuffer kullanıyorsanız aşağıdaki adımları uygulayın:

  • CMSampleBuffer içinde yer alan resim verilerinin yönünü belirtin.

    Resmin yönünü öğrenmek için:

    Swift

    func imageOrientation(
      deviceOrientation: UIDeviceOrientation,
      cameraPosition: AVCaptureDevice.Position
    ) -> UIImage.Orientation {
      switch deviceOrientation {
      case .portrait:
        return cameraPosition == .front ? .leftMirrored : .right
      case .landscapeLeft:
        return cameraPosition == .front ? .downMirrored : .up
      case .portraitUpsideDown:
        return cameraPosition == .front ? .rightMirrored : .left
      case .landscapeRight:
        return cameraPosition == .front ? .upMirrored : .down
      case .faceDown, .faceUp, .unknown:
        return .up
      }
    }
          

    Objective-C

    - (UIImageOrientation)
      imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation
                             cameraPosition:(AVCaptureDevicePosition)cameraPosition {
      switch (deviceOrientation) {
        case UIDeviceOrientationPortrait:
          return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored
                                                                : UIImageOrientationRight;
    
        case UIDeviceOrientationLandscapeLeft:
          return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored
                                                                : UIImageOrientationUp;
        case UIDeviceOrientationPortraitUpsideDown:
          return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored
                                                                : UIImageOrientationLeft;
        case UIDeviceOrientationLandscapeRight:
          return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored
                                                                : UIImageOrientationDown;
        case UIDeviceOrientationUnknown:
        case UIDeviceOrientationFaceUp:
        case UIDeviceOrientationFaceDown:
          return UIImageOrientationUp;
      }
    }
          
  • CMSampleBuffer nesnesini ve yönünü kullanarak bir VisionImage nesnesi oluşturun:

    Swift

    let image = VisionImage(buffer: sampleBuffer)
    image.orientation = imageOrientation(
      deviceOrientation: UIDevice.current.orientation,
      cameraPosition: cameraPosition)

    Objective-C

     MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer];
     image.orientation =
       [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
                                    cameraPosition:cameraPosition];

3. FaceDetector örneği alın

FaceDetector örneği alın:

Swift

let faceDetector = FaceDetector.faceDetector(options: options)

Objective-C

MLKFaceDetector *faceDetector = [MLKFaceDetector faceDetectorWithOptions:options];
      

4. Resmi işle

Ardından resmi process() yöntemine iletin:

Swift

weak var weakSelf = self
faceDetector.process(visionImage) { faces, error in
  guard let strongSelf = weakSelf else {
    print("Self is nil!")
    return
  }
  guard error == nil, let faces = faces, !faces.isEmpty else {
    // ...
    return
  }

  // Faces detected
  // ...
}

Objective-C

[faceDetector processImage:image
                completion:^(NSArray<MLKFace *> *faces,
                             NSError *error) {
  if (error != nil) {
    return;
  }
  if (faces.count > 0) {
    // Recognized faces
  }
}];

5. Algılanan yüzler hakkında bilgi alma

Yüz algılama işlemi başarılı olursa yüz algılayıcı, tamamlama işleyicisine bir Face nesne dizisi iletir. Her Face nesnesi, resimde algılanan bir yüzü temsil eder. Giriş görüntüsünden her bir yüz için sınırlayıcı koordinatları ve yüz algılayıcısını bulması için yapılandırdığınız diğer bilgileri alabilirsiniz. Örneğin:

Swift

for face in faces {
  let frame = face.frame
  if face.hasHeadEulerAngleX {
    let rotX = face.headEulerAngleX  // Head is rotated to the uptoward rotX degrees
  }
  if face.hasHeadEulerAngleY {
    let rotY = face.headEulerAngleY  // Head is rotated to the right rotY degrees
  }
  if face.hasHeadEulerAngleZ {
    let rotZ = face.headEulerAngleZ  // Head is tilted sideways 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 (MLKFace *face in faces) {
  // Boundaries of face in image
  CGRect frame = face.frame;
  if (face.hasHeadEulerAngleX) {
    CGFloat rotX = face.headEulerAngleX;  // Head is rotated to the upward rotX degrees
  }
  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):
  MLKFaceLandmark *leftEar = [face landmarkOfType:FIRFaceLandmarkTypeLeftEar];
  if (leftEar != nil) {
    MLKVisionPoint *leftEarPosition = leftEar.position;
  }

  // If contour detection was enabled:
  MLKFaceContour *upperLipBottomContour = [face contourOfType:FIRFaceContourTypeUpperLipBottom];
  if (upperLipBottomContour != nil) {
    NSArray<MLKVisionPoint *> *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;
  }
}

Yüz konturları örneği

Yüz kontur algılama özelliğini etkinleştirdiğinizde, algılanan her yüz özelliği için bir nokta listesi gösterilir. Bu noktalar özelliğin şeklini temsil eder. Konturların nasıl gösterildiğiyle ilgili ayrıntılı bilgi için Yüz Algılama Kavramları bölümüne bakın.

Aşağıdaki resimde bu noktaların bir yüzle nasıl eşleştirildiği gösterilmektedir. Büyütmek için resmi tıklayın:

örnek algılanan yüz kontur örgü

Gerçek zamanlı yüz algılama

Gerçek zamanlı bir uygulamada yüz algılama özelliğini kullanmak istiyorsanız en iyi kare hızlarına ulaşmak için aşağıdaki yönergeleri uygulayın:

  • Yüz algılayıcıyı, yüz kontur algılamayı veya sınıflandırma ve önemli nokta algılamayı birlikte kullanacak şekilde yapılandırın (ikisini birden değil):

    Kontur algılama
    Önemli nokta algılama
    Sınıflandırma
    Önemli nokta algılama ve sınıflandırma
    Kontur algılama ve önemli nokta algılama
    Kontur algılama ve sınıflandırma
    Kontur algılama, önemli nokta algılama ve sınıflandırma

  • fast modunu etkinleştirin (varsayılan olarak etkindir).

  • Daha düşük çözünürlükte resim çekmeyi deneyin. Ancak, bu API'nin resim boyutu gereksinimlerini de unutmayın.

  • Video karelerini işlemek için algılayıcının results(in:) eşzamanlı API'sini kullanın. Belirtilen video karesinden sonuçları eşzamanlı olarak almak için bu yöntemi AVCaptureVideoDataOutputSampleBufferDelegate captureOutput(_, didOutput:from:) işlevinden çağırın. Çağrıları algılayıcıya kısıtlamak için AVCaptureVideoDataOutput alwaysDiscardsLateVideoFrames özelliğini true olarak bırakın. Algılayıcı çalışırken yeni bir video karesi kullanılabilir hale gelirse atlanır.
  • Algılayıcının çıkışını giriş görüntüsünün üzerine grafik yerleştirmek için kullanırsanız önce sonucu ML Kit'ten alın, ardından görüntüyü tek bir adımda oluşturun ve yer paylaşımlı yapın. Bu şekilde, işlenen her giriş çerçevesi için görüntü yüzeyinde yalnızca bir kez görüntü oluşturursunuz. Örneği görmek için ML Kit hızlı başlangıç örneğindeki updatePreviewOverlayViewWithLastFrame) örneğine bakın.