iOS'te Makine Öğrenimi Kiti ile Yüzleri Algılama

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

Başlamadan önce

  1. Firebase'i uygulamanıza henüz eklemediyseniz başlangıç kılavuzundaki adımları uygulayın.
  2. ML Kit kitaplıklarını Podfile dosyanıza ekleyin:
    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'
    
    Projenizin kapsüllerini yükledikten veya güncelledikten sonra, Xcode projenizi .xcworkspace kullanarak açtığınızdan emin olun.
  3. Uygulamanızda Firebase'i içe aktarın:

    Swift

    import Firebase

    Objective-C

    @import Firebase;

Giriş resmi kuralları

ML Kiti'nin yüzleri doğru şekilde algılayabilmesi için giriş görüntülerinin yeterli piksel verisiyle temsil edilen yüzler içermesi gerekir. Genel olarak, bir resimde algılanmasını istediğiniz her yüz en az 100x100 piksel boyutunda olmalıdır. Yüzlerin konturlarını algılamak istiyorsanız Makine Öğrenimi Kiti daha yüksek çözünürlük girişi gerektirir: Her yüz en az 200x200 piksel boyutunda olmalıdır.

Gerçek zamanlı bir uygulamada yüzleri tespit ediyorsanız giriş görüntülerinin 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 düşük çözünürlüklerde yakalayın (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 bir kısmını kapladığından emin olun. Gerçek zamanlı performansı iyileştirmeye yönelik ipuçları konusunu da inceleyin.

Kötü bir resim odağı, doğruluğu azaltabilir. Kabul edilebilir sonuçlar alamıyorsanız kullanıcıdan resmi yeniden çekmesini isteyin.

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

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

Bir resme yüz algılama işlemi uygulamadan önce, yüz algılayıcının varsayılan ayarlarını değiştirmek isterseniz bu ayarları bir VisionFaceDetectorOptions 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üz "yerlerini" (gözler, kulaklar, burun, yanaklar, ağızlar) algılamaya çalışma.

contourMode none (varsayılan) | all

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

classificationMode none (varsayılan) | all

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

minFaceSize CGFloat (varsayılan: 0.1)

Algılanacak yüzlerin resme göre minimum boyutu.

isTrackingEnabled false (varsayılan) | true

Resimler genelinde yüzleri izlemek için kullanılabilen yüzlere kimlik atanıp atanmayacağı.

Kontür algılama etkinleştirildiğinde yalnızca bir yüz algılanır. Bu nedenle yüz izlemenin faydalı sonuçlar sunmadığını 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 birine benzer bir VisionFaceDetectorOptions nesnesi oluşturun:

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. Yüz algılayıcıyı çalıştırın

Bir görüntüdeki yüzleri algılamak için görüntüyü VisionFaceDetector ürününün detect(in:) yöntemine UIImage veya CMSampleBufferRef olarak iletin:

  1. VisionFaceDetector öğesinin bir örneğini alın:

    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. UIImage veya CMSampleBufferRef kullanarak VisionImage nesnesi oluşturun.

    UIImage kullanmak için:

    1. Gerekirse resmi, imageOrientation özelliği .up olacak şekilde döndürün.
    2. Doğru şekilde döndürülen UIImage öğesini kullanarak bir VisionImage nesnesi oluşturun. Herhangi bir rotasyon meta verisi belirtmeyin. Varsayılan değer (.topLeft) kullanılmalıdır.

      Swift

      let image = VisionImage(image: uiImage)

      Objective-C

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

    CMSampleBufferRef kullanmak için:

    1. CMSampleBufferRef arabelleğinde bulunan resim verilerinin yönünü belirten bir VisionImageMetadata nesnesi oluşturun.

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

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

      Ardından meta veri nesnesini oluşturun:

      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. CMSampleBufferRef nesnesini ve rotasyon meta verilerini kullanarak bir VisionImage nesnesi oluşturun:

      Swift

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

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. Ardından resmi detect(in:) yöntemine iletin:

    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. Algılanan yüzler hakkında bilgi al

Yüz algılama işlemi başarılı olursa yüz dedektörü, tamamlama işleyiciye bir dizi VisionFace nesne iletir. Her VisionFace nesnesi, resimde algılanan bir yüzü temsil eder. Her yüz için sınırlayıcı koordinatlarının yanı sıra yüz dedektörünün bulması için yapılandırdığınız diğer bilgileri de giriş görüntüsünden alabilirsiniz. Örnek:

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

Yüz kontur örneği

Yüz kontur algılama özelliğini etkinleştirdiğinizde, algılanan her yüz özelliği için noktaların bir listesini 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ına Genel Bakış konusuna bakın.

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

Gerçek zamanlı yüz algılama

Yüz algılamayı gerçek zamanlı bir uygulamada kullanmak istiyorsanız en iyi kare hızlarına ulaşmak için şu kuralları uygulayın:

  • Yüz dedektörünü, yüz kontur algılama veya sınıflandırma ve önemli nokta algılamayı kullanacak şekilde yapılandırın. Her 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ştir (varsayılan olarak etkindir).

  • Görüntüleri daha düşük çözünürlükte çekmeyi düşünün. Ancak bu API'nin resim boyutu şartlarını da göz önünde bulundurun.

  • Algılayıcıya yapılan çağrıları hızlandırın. Algılayıcı çalışırken yeni bir video karesi kullanılabilir hale gelirse kareyi bırakın.
  • Algılayıcının çıkışını giriş görüntüsüne grafik yerleştirmek için kullanıyorsanız önce ML Kit'ten sonucu alın, ardından görüntüyü oluşturun ve tek bir adımda bindirme yapın. Böylece, her giriş karesi için görüntü yüzeyinde yalnızca bir kez oluşturma yaparsınız. Örnek için vitrin örnek uygulamasındaki previewOverlayView ve FIRDetectionOverlayView sınıflarına göz atın.