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

Koleksiyonlar ile düzeninizi koruyun İçeriği tercihlerinize göre kaydedin ve kategorilere ayırın.

Resimler ve videolardaki yüzleri algılamak için ML Kit'i kullanabilirsiniz.

Başlamadan önce

  1. Aşağıdaki ML Kit kapsüllerini Podfile'ınıza dahil edin:
    pod 'GoogleMLKit/FaceDetection', '3.2.0'
    
  2. Projenizin Pod'larını yükledikten veya güncelledikten sonra Xcode projenizi .xcworkspace kullanarak açın. ML Kit, Xcode'un 12.4 veya sonraki sürümlerinde desteklenir.

Giriş resmi yönergeleri

Yüz tanıma için en az 480x360 piksel boyutunda bir resim kullanmanız gerekir. ML Kit'in yüzleri doğru şekilde algılayabilmesi için giriş resimleri, yeterli piksel verileriyle temsil edilen yüzler içermelidir. Genel olarak, bir görüntüde algılamak istediğiniz her yüz en az 100x100 piksel olmalıdır. Yüzlerin kıvrımlarını tespit etmek isterseniz ML Kit daha yüksek çözünürlük gerektirir: her yüz en az 200x200 piksel olmalıdır.

Yüzleri gerçek zamanlı bir uygulamada tespit ederseniz giriş resimlerinin genel boyutlarını da dikkate almak isteyebilirsiniz. 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 koşullarını göz önünde bulundurun ve öznenin yüzünün resmin mümkün olduğunca büyük kısmını kaplamasını sağlayın. Ayrıca gerçek zamanlı performansı iyileştirme ipuçları konusuna bakın.

Resim odağının kötü olması da doğruluğu etkileyebilir. Kabul edilebilir sonuçlar elde etmezseniz kullanıcıdan resmi yeniden yakalamasını isteyin.

Yüzün kameraya göre yönü de ML Kit'in algıladığı yüz özelliklerini etkileyebilir. Yüz Algılama Kavramları başlıklı makaleyi inceleyin.

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

Bir resme yüz algılamayı 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 koruyun.

landmarkMode none (varsayılan) | all

Algılanan tüm yüzlerin (köprüler) (gözler, kulaklar, burnu, yanaklar, ağız) yüz algılama özelliğini algılamaya çalışıp çalışmayacağı.

contourMode none (varsayılan) | all

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

classificationMode none (varsayılan) | all

Yüzlerin "gülücük" ve "gözler açık" gibi kategorilerde sınıflandırılıp sınıflandırılmadığı.

minFaceSize CGFloat (varsayılan: 0.1)

Kafa genişliğinin resmin genişliğine oranı olarak tanımlanan, en küçük yüz boyutunu ayarlar.

isTrackingEnabled false (varsayılan) | true

Yüzlere, kimlikler atayıp atamayacağını belirleyin. Bu işlem, yüzleri resimler genelinde izlemek için kullanılabilir.

Kontur algılama etkinleştirildiğinde yalnızca bir yüz algılandığı için yüz izleme yararlı sonuçlar sağlamaz. 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ş resmini hazırlama

Bir görüntüdeki yüzleri tespit etmek için resmi, process(_:completion:) veya results(in:) yöntemini kullanarak UIImage ya da CMSampleBufferRef olarak FaceDetector olarak iletin:

UIImage veya CMSampleBuffer kullanarak bir VisionImage nesnesi oluşturun.

UIImage kullanıyorsanız şu 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 şu adımları uygulayın:

  • CMSampleBuffer öğesinde bulunan resim verilerinin yönünü belirtin.

    Resmin yönünü görmek 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ü 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ğini alma

Bir FaceDetector örneği alın:

Swift

let faceDetector = FaceDetector.faceDetector(options: options)

Objective-C

MLKFaceDetector *faceDetector = [MLKFaceDetector faceDetectorWithOptions:options];
      

4. Resmi işleyin

Ardından, resmi process() yöntemine geçirin:

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 edinme

Yüz algılama işlemi başarılı olursa yüz algılayıcı, tamamlanma işleyicisine bir dizi Face nesnesi iletir. Her Face nesnesi, resimde algılanan bir yüzü temsil eder. Her bir yüz için sınırlayıcı koordinatlarını giriş resminde ve yüz algılayıcıyı yapılandıracak şekilde yapılandırdığınız diğer bilgileri alabilirsiniz. Örnek:

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 konturu örneği

Yüz konturu algılamayı etkinleştirdiğinizde, algılanan her yüz özelliği için bir puan listesi görürsünüz. Bu noktalar özelliğin şeklini temsil eder. Konturların nasıl temsil edildiğiyle ilgili ayrıntılar 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şlendiği gösterilmektedir, büyütmek için resmi tıklayın:

algılanan yüz kontur ağı

Gerçek zamanlı yüz algılama

Yüz algılama özelliğini gerçek zamanlı bir uygulamada 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ılama veya sınıflandırma ve önemli nokta algılamayı kullanacak şekilde yapılandırın, ancak ikisini birden kullanmayın:

    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 görüntüler yakalamayı düşünebilirsiniz. Ancak bu API'nin görüntü boyutu şartlarını da göz önünde bulundurun.

  • Video çerçevelerini işlemek için algılayıcının results(in:) eşzamanlı API'sını kullanın. Belirtilen video çerçevesinden eşzamanlı olarak sonuç almak için bu yöntemi AVCaptureVideoDataOutputSampleBufferDelegate& captureOutput(_, didOutput:from:) işlevinden çağırın. Algılayıcının çağrılarını kısmak için AVCaptureVideoDataOutput alwaysDiscardsLateVideoFrames true olarak bırak. Algılayıcı çalışırken yeni bir video çerçevesi kullanılabilir hale gelirse atlanır.
  • Algılayıcının çıkışını giriş resmine bindirmek için kullanırsanız önce ML Kit'ten sonucu alın, ardından resmi ve yer paylaşımını tek adımda oluşturun. Bunu yaptığınızda, işlenen her bir giriş çerçevesi için görüntüleme yüzeyini yalnızca bir kez oluşturursunuz. Örnek için ML Kit hızlı başlangıç örneğindeki updatepreviewLayoutViewWithLastFrame bölümüne bakın.