iOS'te ML Kiti ile pozları algılama

ML Kit, poz algılama için iki optimize edilmiş SDK sağlar.

SDK AdıPoseDetectionPoseDetectionAccurate
UygulamaTemel algılayıcıya ait öğeler, derleme sırasında uygulamanıza statik olarak bağlanır.Doğru algılayıcı için öğeler, derleme sırasında uygulamanıza statik olarak bağlanır.
Uygulama boyutuEn fazla 29,6 MBEn fazla 33,2 MB
PerformansiPhone X: ~45FPSiPhone X: ~29FPS

Deneyin

Başlamadan önce

  1. Podfile'ınıza aşağıdaki ML Kit kapsüllerini ekleyin:

    # If you want to use the base implementation:
    pod 'GoogleMLKit/PoseDetection', '8.0.0'
    
    # If you want to use the accurate implementation:
    pod 'GoogleMLKit/PoseDetectionAccurate', '8.0.0'
    
  2. Projenizin pod'larını yükledikten veya güncelledikten sonra, xcworkspace kullanarak Xcode projenizi açın. ML Kit, Xcode 13.2.1 veya sonraki sürümlerde desteklenir.

1. PoseDetector örneği oluşturma

Bir resimde poz algılamak için önce PoseDetector örneği oluşturun ve isteğe bağlı olarak algılayıcı ayarlarını belirtin.

PoseDetector seçenek

Algılama Modu

PoseDetector iki algılama modunda çalışır. Kullanım alanınıza uygun olanı seçtiğinizden emin olun.

stream (varsayılan)
Poz algılayıcı, önce resimdeki en belirgin kişiyi algılar, ardından poz algılama işlemini çalıştırır. Sonraki karelerde, kişi bulanıklaşmadığı veya yüksek güvenle algılanmadığı sürece kişi algılama adımı uygulanmaz. Poz algılayıcı, en belirgin kişiyi takip etmeye çalışır ve her çıkarımda bu kişinin pozunu döndürür. Bu, gecikmeyi azaltır ve algılamayı kolaylaştırır. Bir video akışında pozu algılamak istediğinizde bu modu kullanın.
singleImage
Poz algılayıcı, bir kişiyi algılayıp poz algılama işlemini çalıştırır. Kişi algılama adımı her resim için çalışır. Bu nedenle gecikme daha yüksek olur ve kişi takibi yapılmaz. Poz algılamayı statik resimlerde kullanırken veya izleme istenmediğinde bu modu kullanın.

Poz algılayıcı seçeneklerini belirtin:

Swift

// Base pose detector with streaming, when depending on the PoseDetection SDK
let options = PoseDetectorOptions()
options.detectorMode = .stream

// Accurate pose detector on static images, when depending on the
// PoseDetectionAccurate SDK
let options = AccuratePoseDetectorOptions()
options.detectorMode = .singleImage

Objective-C

// Base pose detector with streaming, when depending on the PoseDetection SDK
MLKPoseDetectorOptions *options = [[MLKPoseDetectorOptions alloc] init];
options.detectorMode = MLKPoseDetectorModeStream;

// Accurate pose detector on static images, when depending on the
// PoseDetectionAccurate SDK
MLKAccuratePoseDetectorOptions *options =
    [[MLKAccuratePoseDetectorOptions alloc] init];
options.detectorMode = MLKPoseDetectorModeSingleImage;

Son olarak, PoseDetector örneğini alın. Belirttiğiniz seçenekleri iletin:

Swift

let poseDetector = PoseDetector.poseDetector(options: options)

Objective-C

MLKPoseDetector *poseDetector =
    [MLKPoseDetector poseDetectorWithOptions:options];

2. Giriş resmini hazırlama

Pozları algılamak için her resim veya video karesi için aşağıdakileri yapın. Akış modunu etkinleştirdiyseniz CMSampleBuffer öğelerinden VisionImage nesneleri oluşturmanız gerekir.

UIImage veya CMSampleBuffer kullanarak VisionImage nesnesi oluşturun.

UIImage kullanıyorsanız şu adımları uygulayın:

  • UIImage ile VisionImage nesnesi oluşturun. Doğru .orientation 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 içinde yer alan resim verilerinin yönünü belirtin.

    Resim yönünü almak 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ünü kullanarak 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. Resmi işleme

VisionImage değerini poz algılayıcının görüntü işleme yöntemlerinden birine iletin. Eşzamansız process(image:) yöntemini veya eşzamanlı results() yöntemini kullanabilirsiniz.

Nesneleri senkron olarak algılamak için:

Swift

var results: [Pose]
do {
  results = try poseDetector.results(in: image)
} catch let error {
  print("Failed to detect pose with error: \(error.localizedDescription).")
  return
}
guard let detectedPoses = results, !detectedPoses.isEmpty else {
  print("Pose detector returned no results.")
  return
}

// Success. Get pose landmarks here.

Objective-C

NSError *error;
NSArray *poses = [poseDetector resultsInImage:image error:&error];
if (error != nil) {
  // Error.
  return;
}
if (poses.count == 0) {
  // No pose detected.
  return;
}

// Success. Get pose landmarks here.

Nesneleri eşzamansız olarak algılamak için:

Swift

poseDetector.process(image) { detectedPoses, error in
  guard error == nil else {
    // Error.
    return
  }
  guard !detectedPoses.isEmpty else {
    // No pose detected.
    return
  }

  // Success. Get pose landmarks here.
}

Objective-C

[poseDetector processImage:image
                completion:^(NSArray * _Nullable poses,
                             NSError * _Nullable error) {
                    if (error != nil) {
                      // Error.
                      return;
                    }
                    if (poses.count == 0) {
                      // No pose detected.
                      return;
                    }

                    // Success. Get pose landmarks here.
                  }];

4. Algılanan poz hakkında bilgi edinme

Resimde bir kişi algılanırsa poz algılama API'si, tamamlanma işleyicisine bir Pose nesne dizisi iletir veya eşzamansız ya da eşzamanlı yöntemi çağırıp çağırmadığınıza bağlı olarak diziyi döndürür.

Kişi resmin içinde tamamen görünmüyorsa model, eksik önemli nokta koordinatlarını çerçevenin dışına atar ve bunlara düşük InFrameConfidence değerleri verir.

Kişi algılanmadıysa dizi boştur.

Swift

for pose in detectedPoses {
  let leftAnkleLandmark = pose.landmark(ofType: .leftAnkle)
  if leftAnkleLandmark.inFrameLikelihood > 0.5 {
    let position = leftAnkleLandmark.position
  }
}

Objective-C

for (MLKPose *pose in detectedPoses) {
  MLKPoseLandmark *leftAnkleLandmark =
      [pose landmarkOfType:MLKPoseLandmarkTypeLeftAnkle];
  if (leftAnkleLandmark.inFrameLikelihood > 0.5) {
    MLKVision3DPoint *position = leftAnkleLandmark.position;
  }
}

Performansı artırmaya yönelik ipuçları

Sonuçlarınızın kalitesi, giriş resminin kalitesine bağlıdır:

  • ML Kit'in pozu doğru şekilde algılayabilmesi için resimdeki kişinin yeterli piksel verisiyle temsil edilmesi gerekir. En iyi performans için özne en az 256x256 piksel olmalıdır.
  • Gerçek zamanlı bir uygulamada poz algılarsanız giriş resimlerinin genel boyutlarını da göz önünde bulundurmanız gerekebilir. Daha küçük resimler daha hızlı işlenebilir. Bu nedenle, gecikmeyi azaltmak için daha düşük çözünürlüklerde resim çekin ancak yukarıdaki çözünürlük şartlarını göz önünde bulundurun ve öznenin mümkün olduğunca fazla yer kapladığından emin olun.
  • Resmin iyi odaklanmaması da doğruluğu etkileyebilir. Kabul edilebilir sonuçlar almazsanız kullanıcıdan resmi yeniden çekmesini isteyin.

Poz algılamayı gerçek zamanlı bir uygulamada kullanmak istiyorsanız en iyi kare hızlarını elde etmek için aşağıdaki yönergeleri uygulayın:

  • Temel PoseDetection SDK'sını ve stream algılama modunu kullanın.
  • Görüntüleri daha düşük çözünürlükte çekmeyi deneyin. Ancak bu API'nin resim boyutu koşullarını da göz önünde bulundurun.
  • Video karelerini işlemek için algılayıcının results(in:) senkron API'sini kullanın. Bu yöntemi, AVCaptureVideoDataOutputSampleBufferDelegate'in captureOutput(_, didOutput:from:) işlevinden çağırarak belirtilen video karesinden sonuçları senkron olarak alın. Algılayıcıya yapılan çağrıları sınırlamak için AVCaptureVideoDataOutput'un alwaysDiscardsLateVideoFrames özelliğini true olarak tutun. Algılayıcı çalışırken yeni bir video karesi kullanılabilir hale gelirse bu kare bırakılır.
  • Giriş resmine grafik yerleştirmek için algılayıcının çıkışını kullanıyorsanız önce ML Kit'ten sonucu alın, ardından resmi ve yer paylaşımını tek adımda oluşturun. Bunu yaparak, işlenen her giriş karesi için yalnızca bir kez görüntüleme yüzeyine oluşturma işlemi yaparsınız. Örnek için tanıtım amaçlı örnek uygulamadaki previewOverlayView ve MLKDetectionOverlayView sınıflarına bakın.

Sonraki adımlar