Check out what’s new from Firebase@ Google I/O 2021, and join our alpha program for early access to the new Remote Config personalization feature. Learn more

iOS'ta ML Kit ile Yüzleri Algıla

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

Sen başlamadan önce

  1. Henüz uygulamanıza Firebase'i eklemediyseniz, başlangıç kılavuzundaki adımları izleyerek bunu yapın.
  2. ML Kit kitaplıklarını Pod 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 Pod'larını 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:

    hızlı

    import Firebase

    Amaç-C

    @import Firebase;

Giriş resmi yönergeleri

ML Kit'in yüzleri doğru bir şekilde algılaması için giriş görüntülerinin yeterli piksel verisi ile temsil edilen yüzleri içermesi gerekir. Genel olarak, bir görüntüde algılamak istediğiniz her yüz en az 100x100 piksel olmalıdır. Yüzlerin konturları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.

Gerçek zamanlı bir uygulamada yüzleri algılıyorsanız, giriş görüntülerinin genel boyutlarını da göz önünde bulundurmak isteyebilirsiniz. Daha küçük görüntüler daha hızlı işlenebilir, bu nedenle gecikmeyi azaltmak için görüntüleri daha düşük çözünürlüklerde yakalayın (yukarıdaki doğruluk gerekliliklerini göz önünde bulundurarak) ve öznenin yüzünün görüntünün mümkün olduğu kadar çok yer kaplamasını sağlayın. Ayrıca, gerçek zamanlı performansı iyileştirmeye yönelik İpuçları'na bakın.

Kötü görüntü odaklama doğruluğuna zarar verebilir. Kabul edilebilir sonuçlar almıyorsanız, kullanıcıdan resmi yeniden çekmesini istemeyi deneyin.

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

1. Yüz dedektörünü yapılandırın

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 istiyorsanız, bu ayarları bir VisionFaceDetectorOptions nesnesiyle belirtin. Aşağıdaki ayarları değiştirebilirsiniz:

Ayarlar
performanceMode fast (varsayılan) | accurate

Yüzleri tespit ederken hızı veya doğruluğu tercih edin.

landmarkMode none (varsayılan) | all

Algılanan tüm yüzlerin yüz "belirgin noktalarının" (gözler, kulaklar, burun, yanaklar, ağız) tespit edilip edilmeyeceği.

contourMode none (varsayılan) | all

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

classificationMode none (varsayılan) | all

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

minFaceSize CGFloat (varsayılan: 0.1 )

Algılanacak yüzlerin görüntüye göre minimum boyutu.

isTrackingEnabled false (varsayılan) | true

Yüzlere, görüntüler 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ığından, yüz izlemenin yararlı sonuçlar üretmediğini unutmayın. Bu nedenle ve algılama hızını artırmak için hem kontur algılamayı hem de yüz izlemeyi etkinleştirmeyin.

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

hızlı

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

Amaç-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 dedektörünü çalıştırın

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

  1. VisionFaceDetector örneğini alın:

    hızlı

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

    Amaç-C

    FIRVision *vision = [FIRVision vision];
    FIRVisionFaceDetector *faceDetector = [vision faceDetector];
    // Or, to change the default settings:
    // FIRVisionFaceDetector *faceDetector =
    //     [vision faceDetectorWithOptions:options];
    
  2. Bir UIImage veya bir CMSampleBufferRef kullanarak bir VisionImage nesnesi oluşturun.

    Bir UIImage kullanmak için:

    1. Gerekirse onun böylece görüntüyü döndürmek imageOrientation özelliktir .up .
    2. Doğru döndürülmüş UIImage kullanarak bir VisionImage nesnesi oluşturun. Herhangi bir döndürme meta verisi belirtmeyin; varsayılan değer olan .topLeft kullanılmalıdır.

      hızlı

      let image = VisionImage(image: uiImage)

      Amaç-C

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

    Bir CMSampleBufferRef kullanmak için:

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

      Görüntü yönünü almak için:

      hızlı

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

      Amaç-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:

      hızlı

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

      Amaç-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 döndürme meta verilerini kullanarak bir VisionImage nesnesi oluşturun:

      hızlı

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

      Amaç-C

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

    hızlı

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

    Amaç-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ın

Yüz algılama işlemi başarılı olursa, yüz algılayıcı bir dizi VisionFace nesnesini tamamlama işleyicisine VisionFace . Her VisionFace nesnesi, görüntüde algılanan bir yüzü temsil eder. Her yüz için, giriş görüntüsündeki sınırlayıcı koordinatlarını ve yüz dedektörünü bulması için yapılandırdığınız diğer bilgileri alabilirsiniz. Örneğin:

hızlı

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

Amaç-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 hatlarına örnek

Yüz konturu algılamayı etkinleştirdiğinizde, algılanan her yüz özelliği için bir nokta listesi alı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ış'a bakın.

Aşağıdaki resim, bu noktaların bir yüze nasıl eşlendiğini göstermektedir (büyütmek için resme tıklayın):

Gerçek zamanlı yüz algılama

Gerçek zamanlı bir uygulamada yüz algılamayı kullanmak istiyorsanız, en iyi kare hızlarını elde etmek için şu yönergeleri izleyin:

  • Yüz algılayıcıyı , yüz konturu algılama veya sınıflandırma ve yer işareti algılamayı kullanacak şekilde yapılandırın , ancak ikisini birden kullanmayın:

    Kontur algılama
    Yer işareti algılama
    sınıflandırma
    Landmark tespiti ve sınıflandırması
    Kontur algılama ve dönüm noktası algılama
    Kontur algılama ve sınıflandırma
    Kontur algılama, dönüm noktası algılama ve sınıflandırma

  • fast modu etkinleştir (varsayılan olarak etkindir).

  • Görüntüleri daha düşük bir çözünürlükte yakalamayı düşünün. Ancak, bu API'nin resim boyutu gereksinimlerini de unutmayın.

  • Gaz kelebeği dedektörü çağırır. Dedektör çalışırken yeni bir video karesi mevcutsa, kareyi bırakın.
  • Giriş görüntüsü üzerine grafik bindirmek için dedektörün çıkışını kullanıyorsanız, önce ML Kit'ten sonucu alın, ardından görüntüyü oluşturun ve tek adımda bindirin. Bunu yaparak, her bir giriş karesi için yalnızca bir kez görüntüleme yüzeyini oluşturursunuz. Bir örnek için vitrin örnek uygulamasında önizlemeOverlayView ve FIRDetectionOverlayView sınıflarına bakın.