iOS'te Makine Öğrenimi Kiti ile Nesneleri Tespit Etme ve İzleme

Video karelerindeki nesneleri tespit edip takip etmek için ML Kit'i kullanabilirsiniz.

Makine Öğrenimi Kiti görüntülerini ilettiğinizde, Makine Öğrenimi Kiti her görüntü için algılanan en fazla beş nesne ve bunların görüntüdeki konumlarını içeren bir liste döndürür. Video akışlarında nesneleri algılarken her nesnenin, nesneyi resimler arasında izlemek için kullanabileceğiniz bir kimliği vardır. İsterseniz nesneleri geniş kategori açıklamalarıyla etiketleyen genel nesne sınıflandırmasını da etkinleştirebilirsiniz.

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'
    pod 'Firebase/MLVisionObjectDetection', '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;

1. Nesne algılayıcıyı yapılandırma

Nesneleri tespit etmeye ve izlemeye başlamak için önce VisionObjectDetector örneği oluşturun. İsteğe bağlı olarak, varsayılandan değiştirmek istediğiniz algılayıcı ayarlarını belirtin.

  1. Kullanım alanınıza uygun nesne algılayıcısını bir VisionObjectDetectorOptions nesnesiyle yapılandırın. Aşağıdaki ayarları değiştirebilirsiniz:

    Nesne Algılayıcı Ayarları
    Algılama modu .stream (varsayılan) | .singleImage

    Akış modunda (varsayılan), nesne algılayıcı çok düşük gecikmeyle çalışır ancak algılayıcının ilk birkaç çağrısında eksik sonuçlar (belirtilmemiş sınırlayıcı kutular veya kategori gibi) üretebilir. Ayrıca, akış modunda algılayıcı nesnelere izleme kimlikleri atar. Bu kimlikleri, nesneleri çerçeveler arasında izlemek için kullanabilirsiniz. Nesneleri izlemek istediğinizde veya video akışlarını gerçek zamanlı olarak işleme gibi düşük gecikmenin önemli olduğu durumlarda bu modu kullanın.

    Tekli görüntü modunda, nesne algılayıcı, sonuç döndürmeden önce algılanan bir nesnenin sınırlayıcı kutusu ve (sınıflandırmayı etkinleştirdiyseniz) kategorisinin kullanılabilir hale gelmesini bekler. Sonuç olarak algılama gecikmesi potansiyel olarak daha yüksek olur. Ayrıca, tekli resim modunda izleme kimlikleri atanmaz. Gecikme kritik değilse ve kısmi sonuçlarla uğraşmak istemiyorsanız bu modu kullanın.

    Birden çok nesneyi algılama ve izleme false (varsayılan) | true

    Beşe kadar nesnenin mi yoksa yalnızca en belirgin nesnenin mi algılanıp takip edileceği (varsayılan).

    Nesneleri sınıflandırma false (varsayılan) | true

    Algılanan nesnelerin genel kategorilerde sınıflandırılıp sınıflandırılmayacağı. Etkinleştirildiğinde, nesne dedektörü nesneleri şu kategorilere ayırır: moda ürünleri, gıda, ev eşyaları, yerler, bitkiler ve bilinmiyor.

    Nesne algılama ve izleme API'si, aşağıdaki iki temel kullanım alanı için optimize edilmiştir:

    • Kamera vizöründeki en belirgin nesnenin canlı olarak algılanması ve takip edilmesi
    • Statik resimde birden fazla nesnenin algılanması

    API'yi bu kullanım alanlarına göre yapılandırmak için:

    Swift

    // Live detection and tracking
    let options = VisionObjectDetectorOptions()
    options.detectorMode = .stream
    options.shouldEnableMultipleObjects = false
    options.shouldEnableClassification = true  // Optional
    
    // Multiple object detection in static images
    let options = VisionObjectDetectorOptions()
    options.detectorMode = .singleImage
    options.shouldEnableMultipleObjects = true
    options.shouldEnableClassification = true  // Optional
    

    Objective-C

    // Live detection and tracking
    FIRVisionObjectDetectorOptions *options = [[FIRVisionObjectDetectorOptions alloc] init];
    options.detectorMode = FIRVisionObjectDetectorModeStream;
    options.shouldEnableMultipleObjects = NO;
    options.shouldEnableClassification = YES;  // Optional
    
    // Multiple object detection in static images
    FIRVisionObjectDetectorOptions *options = [[FIRVisionObjectDetectorOptions alloc] init];
    options.detectorMode = FIRVisionObjectDetectorModeSingleImage;
    options.shouldEnableMultipleObjects = YES;
    options.shouldEnableClassification = YES;  // Optional
    
  2. FirebaseVisionObjectDetector örneği alın:

    Swift

    let objectDetector = Vision.vision().objectDetector()
    
    // Or, to change the default settings:
    let objectDetector = Vision.vision().objectDetector(options: options)
    

    Objective-C

    FIRVisionObjectDetector *objectDetector = [[FIRVision vision] objectDetector];
    
    // Or, to change the default settings:
    FIRVisionObjectDetector *objectDetector = [[FIRVision vision] objectDetectorWithOptions:options];
    

2. Nesne algılayıcıyı çalıştırma

Nesneleri algılamak ve izlemek için her bir resim veya video karesi için aşağıdakileri yapın. Akış modunu etkinleştirdiyseniz CMSampleBufferRef saniyelerinden VisionImage nesne oluşturmanız gerekir.

  1. 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;
  2. VisionImage öğesini, nesne 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 eşzamansız olarak algılamak için:

    Swift

    objectDetector.process(image) { detectedObjects, error in
      guard error == nil else {
        // Error.
        return
      }
      guard let detectedObjects = detectedObjects, !detectedObjects.isEmpty else {
        // No objects detected.
        return
      }
    
      // Success. Get object info here.
      // ...
    }
    

    Objective-C

    [objectDetector processImage:image
                      completion:^(NSArray<FIRVisionObject *> * _Nullable objects,
                                   NSError * _Nullable error) {
                        if (error == nil) {
                          return;
                        }
                        if (objects == nil | objects.count == 0) {
                          // No objects detected.
                          return;
                        }
    
                        // Success. Get object info here.
                        // ...
                      }];
    

    Nesneleri eşzamanlı olarak algılamak için:

    Swift

    var results: [VisionObject]? = nil
    do {
      results = try objectDetector.results(in: image)
    } catch let error {
      print("Failed to detect object with error: \(error.localizedDescription).")
      return
    }
    guard let detectedObjects = results, !detectedObjects.isEmpty else {
      print("Object detector returned no results.")
      return
    }
    
    // ...
    

    Objective-C

    NSError *error;
    NSArray<FIRVisionObject *> *objects = [objectDetector resultsInImage:image
                                                                   error:&error];
    if (error == nil) {
      return;
    }
    if (objects == nil | objects.count == 0) {
      // No objects detected.
      return;
    }
    
    // Success. Get object info here.
    // ...
    
  3. Görüntü işlemciye yapılan çağrı başarılı olursa tamamlama işleyiciye bir VisionObject listesi iletir veya eşzamansız ya da eşzamanlı yöntemi çağırmanıza bağlı olarak listeyi döndürür.

    Her VisionObject aşağıdaki özellikleri içerir:

    frame Resimdeki nesnenin konumunu gösteren bir CGRect.
    trackingID Nesneyi resimler arasında tanımlayan bir tam sayı. Tek resim modunda Nil.
    classificationCategory Nesnenin genel kategorisi. Nesne algılayıcıda sınıflandırma etkinleştirilmediyse bu değer her zaman .unknown olur.
    confidence Nesne sınıflandırmasının güven değeri. Nesne algılayıcıda sınıflandırma etkinleştirilmemişse veya nesne bilinmeyen olarak sınıflandırılmışsa bu değer nil olur.

    Swift

    // detectedObjects contains one item if multiple object detection wasn't enabled.
    for obj in detectedObjects {
      let bounds = obj.frame
      let id = obj.trackingID
    
      // If classification was enabled:
      let category = obj.classificationCategory
      let confidence = obj.confidence
    }
    

    Objective-C

    // The list of detected objects contains one item if multiple
    // object detection wasn't enabled.
    for (FIRVisionObject *obj in objects) {
      CGRect bounds = obj.frame;
      if (obj.trackingID) {
        NSInteger id = obj.trackingID.integerValue;
      }
    
      // If classification was enabled:
      FIRVisionObjectCategory category = obj.classificationCategory;
      float confidence = obj.confidence.floatValue;
    }
    

Kullanılabilirliği ve performansı iyileştirme

En iyi kullanıcı deneyimi için uygulamanızda aşağıdaki yönergelere uyun:

  • Nesne algılama işleminin başarılı olması, nesnenin görsel karmaşıklığına bağlıdır. Az sayıda görsel özelliğe sahip nesnelerin algılanması için resmin daha büyük bir kısmını kaplaması gerekebilir. Kullanıcılara, algılamak istediğiniz nesne türleri için iyi sonuç veren girişi yakalama konusunda yol göstermelisiniz.
  • Sınıflandırma kullanırken, desteklenen kategorilere uygun olmayan nesneleri tespit etmek istiyorsanız bilinmeyen nesneler için özel işleme uygulayın.

Ayrıca [ML Kit Material Design vitrin uygulaması][showcase-link]{: .external } ve Materyal Tasarım Makine öğrenimi destekli özellikler için kalıplar koleksiyonuna da göz atın.

Akış modunu gerçek zamanlı bir uygulamada kullanırken en iyi kare hızlarına ulaşmak için şu yönergeleri uygulayın:

  • Çoğu cihaz yeterli kare hızı üretemediğinden akış modunda çoklu nesne algılamayı kullanmayın.

  • İhtiyacınız yoksa sınıflandırmayı devre dışı bırakın.

  • 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.