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

Görüntü ve videolardaki yüzleri algılamak için ML Kit'i kullanabilirsiniz.

Deneyin

Başlamadan önce

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

Giriş resmi kuralları

Yüz tanıma için en az 480x360 piksel boyutunda bir resim kullanmanız gerekir. ML Kit'in yüzleri doğru algılayabilmesi için giriş görüntülerinin yüzler içermesi gerekir temsil edilir. Genel olarak, görmek istediğiniz her yüz en az 100x100 piksel boyutunda olmalıdır. Belirli bir aktiviteyi Yüzlerin sınırları, makine öğrenimi kiti için daha yüksek çözünürlük girişi gerekir: her yüz en az 200x200 piksel olmalıdır.

Gerçek zamanlı bir uygulamada yüzler algılandığında ayrıca giriş resimlerinin genel boyutlarını göz önünde bulundurun. Daha küçük resimler daha hızlı işlenir. Bu nedenle, gecikmeyi azaltmak için görüntüleri düşük çözünürlüklerde yakalayın. yukarıdaki doğruluk şartlarını göz önünde bulundurun ve öznenin yüzü resmin olabildiğince büyük kısmını kaplar. Şunlara da bakabilirsiniz: Gerçek zamanlı performansı iyileştirmeye yönelik ipuçları.

Kötü bir resim odağı, doğruluğu da etkileyebilir. Ekibimiz kabul edilmezse kullanıcının resmi yeniden çekmesini isteyin.

Bir yüzün kameraya göre yönü hangi yüzün üzerinde etkili olabilir Makine Öğrenimi Kiti'nin algıladığı özellikler. Görüntüleyin Yüz Algılama Kavramları.

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

Bir resme yüz algılama özelliğini uygulamadan önce, yüz dedektörünün varsayılan ayarlarını seçtikten sonra, bu ayarları FaceDetectorOptions nesnesini tanımlayın. Şunları değiştirebilirsiniz: şu ayarlar:

Ayarlar
performanceMode fast (varsayılan) | accurate

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

landmarkMode none (varsayılan) | all

Yüzdeki "önemli noktaları" tespit etmeye çalışıp çalışmadığı kulak, burun, yanaklar, ağız.

contourMode none (varsayılan) | all

Yüz özelliklerinin konturlarının algılanıp algılanmayacağı. Kontürler bir görüntüdeki yalnızca en belirgin yüz için algılandı.

classificationMode none (varsayılan) | all

Yüzlerin "gülümseyen" gibi kategoriler halinde sınıflandırılıp sınıflandırılmayacağı ve "gözler açık" gibi.

minFaceSize CGFloat (varsayılan: 0.1)

İstenen en küçük yüz boyutunu, resmin genişliğine göre değişir.

isTrackingEnabled false (varsayılan) | true

Aşağıdakileri izlemek için kullanılabilecek bir kimlik atanıp atanmayacağı görüntüler.

Kontür algılama etkinleştirildiğinde yalnızca bir yüzün bu yüzden yüz izleme faydalı sonuçlar üretmez. Bunun için algılama hızını artırmak için iki konturu da etkinleştirmeyin ve özellikleri bulunuyor.

Örneğin, bir FaceDetectorOptions aşağıdaki örneklerden birine benzer:

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 resimdeki yüzleri algılamak için resmi UIImage veya CMSampleBufferRef FaceDetector process(_:completion:) veya results(in:) yöntemi:

Bir VisionImage nesnesi oluşturmak için UIImage veya CMSampleBuffer.

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:

  • Belgenin CMSampleBuffer

    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;
      }
    }
          
  • Şu komutu kullanarak bir VisionImage nesnesi oluşturun: CMSampleBuffer nesne ve yön:

    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 alma

FaceDetector öğesinin bir örneğini 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 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 al

Yüz algılama işlemi başarılı olursa yüz dedektörü bir diziyi iletir Tamamlama işleyiciye Face nesne. Her biri Face nesnesi, resimde algılanan bir yüzü temsil eder. Örneğin, her bir yüzeyin sınırlayıcı koordinatlarını giriş görüntüsünde alabilirsiniz. Ayrıca, yüz dedektörünü bulacağı şekilde yapılandırdığınız diğer tüm bilgiler. Ö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 kontur örneği

Yüz kontur algılamayı etkinleştirdiğinizde, yüz konturu algılamayı etkinleştirdiğinizde Algılanan her yüz özelliği. Bu noktalar, noktanın şeklini özelliğini kullanabilirsiniz. Bkz. Yüz Kontürlerin nasıl göründüğüyle ilgili ayrıntılar için Algılama Kavramları temsil edilir.

Aşağıdaki resimde bu noktaların bir yüzle nasıl eşlendiği gösterilmektedir. Daha sonra resmi büyütün:

algılanan yüz kontur örgüsü örneği

Gerçek zamanlı yüz algılama

Yüz algılamayı gerçek zamanlı bir uygulamada kullanmak istiyorsanız şuradaki talimatları uygulayın: talimatları uygulayın:

  • Yüz algılamayı aşağıdakilerden birini kullanacak şekilde yapılandırın: yalnızca yüz kontur algılama veya sınıflandırma ve önemli nokta algılama özellikleri kullanılabilir.

    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ştir (varsayılan olarak etkindir).

  • Görüntüleri daha düşük çözünürlükte çekmeyi düşünün. Ancak unutmayın, resim boyutu şartlarına tabidir.

  • Video karelerini işlemek için algılayıcının results(in:) eşzamanlı API'sini kullanın. Telefonla arama AVCaptureVideoDataOutputSampleBufferDelegate İlgili videodan eşzamanlı olarak sonuç almak için captureOutput(_, didOutput:from:) işlevi çerçeve. sakla AVCaptureVideoDataOutput adlı kullanıcının Algılayıcıya yapılan çağrıları kısmak için true olarak alwaysDiscardsLateVideoFrames. Yeni bir Video karesi, algılayıcı çalışırken kullanılabilir hale gelir ve algılanmaz.
  • Algılayıcının çıkışını, üzerine grafik yerleştirmek için giriş görüntüsünü kullanın, önce ML Kit'ten sonucu alın ve ardından görüntüyü oluşturun tek bir adımda yapabilirsiniz. Bu şekilde, öğeleri ekran yüzeyinde işlenen her giriş çerçevesi için yalnızca bir kez. Bkz. updatePreviewOverlayViewWithLastFrame ML Kit hızlı başlangıç örneğine göz atın.