iOS'ta ML Kiti ile Yüzleri Algılama

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

Sen başlamadan önce

  1. Firebase'i uygulamanıza henüz 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:

    Süratli

    import Firebase

    Amaç-C

    @import Firebase;

Giriş görseli yönergeleri

ML Kit'in yüzleri doğru şekilde algılaması için giriş görüntülerinin yeterli piksel verileriyle temsil edilen yüzler içermesi gerekir. Genel olarak bir görselde algılamak istediğiniz her yüz en az 100x100 piksel boyutunda olmalıdır. Yüzlerin hatlarını algılamak istiyorsanız ML Kiti 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 tespit ediyorsanız giriş görüntülerinin genel boyutlarını da dikkate almak 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ükte çekin (yukarıdaki doğruluk gerekliliklerini akılda tutarak) ve nesnenin yüzünün görüntünün mümkün olduğunca büyük bir kısmını kaplamasını sağlayın. Ayrıca bkz . Gerçek zamanlı performansı artırmaya yönelik ipuçları .

Zayıf görüntü odağı doğruluğu olumsuz etkileyebilir. Kabul edilebilir sonuçlar alamıyorsanız kullanıcıdan görüntüyü yeniden yakalamasını istemeyi deneyin.

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 algılayıcıyı yapılandırın

Bir görüntüye yüz algılamayı 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 "yer işaretlerinin" (gözler, kulaklar, burun, yanaklar, ağız) algılanmaya çalışılıp çalışılmayacağı.

contourMode none (varsayılan) | all

Yüz özelliklerinin dış hatları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üzleri "gülen" ve "gözler açık" gibi kategorilere ayırıp sınıflandırmayacağınız.

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ülerdeki yüzleri izlemek için kullanılabilecek bir kimlik atanıp atanmayacağı.

Kontur algılama etkinleştirildiğinde yalnızca bir yüzün algılandığını, dolayısıyla yüz izlemenin yararlı sonuçlar vermediğini unutmayın. Bu nedenle 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 birine benzer bir VisionFaceDetectorOptions nesnesi oluşturun:

Süratli

// 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ü bir UIImage veya CMSampleBufferRef olarak VisionFaceDetector detect(in:) yöntemine iletin:

  1. VisionFaceDetector örneğini alın:

    Süratli

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

    Bir UIImage kullanmak için:

    1. Gerekirse görüntüyü imageOrientation özelliği .up olacak şekilde döndürün.
    2. Doğru şekilde 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.

      Süratli

      let image = VisionImage(image: uiImage)

      Amaç-C

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

    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ü elde etmek için:

      Süratli

      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:

      Süratli

      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:

      Süratli

      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:

    Süratli

    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 iletir. Her VisionFace nesnesi, görüntüde tespit edilen bir yüzü temsil eder. Her yüzün sınırlayıcı koordinatlarını ve ayrıca yüz algılayıcıyı bulması için yapılandırdığınız diğer bilgileri giriş görüntüsünden alabilirsiniz. Örneğin:

Süratli

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 çevresi algılamayı etkinleştirdiğinizde, algılanan her yüz özelliği için noktaların bir listesini alırsınız. Bu noktalar özelliğin şeklini temsil eder. Konturların nasıl temsil edildiğine ilişkin ayrıntılar için Yüz Algılama Kavramlarına Genel Bakış'a 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 resme 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 yönergeleri izleyin:

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

    Kontur algılama
    Önemli nokta tespiti
    sınıflandırma
    Yer işareti tespiti ve sınıflandırma
    Kontur algılama ve yer işareti algılama
    Kontur tespiti ve sınıflandırma
    Kontur tespiti, yer işareti tespiti ve sınıflandırma

  • fast modu etkinleştirin (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 gereksinimlerini de unutmayın.

  • Gaz kelebeği dedektöre çağrı yapar. Dedektör çalışırken yeni bir video karesi kullanılabilir hale gelirse kareyi bırakın.
  • Giriş görüntüsü üzerine grafikleri yerleştirmek için dedektörün çıkışını kullanıyorsanız, önce ML Kit'ten sonucu alın, ardından tek adımda görüntüyü işleyin ve üst üste koyun. Bunu yaparak, her giriş karesi için ekran yüzeyini yalnızca bir kez görüntüleyebilirsiniz. Örnek için vitrin örnek uygulamasındaki önizlemeOverlayView ve FIRDetectionOverlayView sınıflarına bakın.