iOS'ta ML Kit ile Nesneleri Algılama ve Takip Etme

-yer tutucu30 l10n-yer

Video karelerindeki nesneleri algılamak ve izlemek için ML Kit'i kullanabilirsiniz.

ML Kit görüntülerini ilettiğinizde, ML Kit, her görüntü için en fazla beş algılanan nesnenin listesini ve görüntüdeki konumlarını döndürür. Video akışlarında nesneleri algılarken, her nesnenin, nesneyi görüntüler arasında izlemek için kullanabileceğiniz bir kimliği vardır. Ayrıca, nesneleri geniş kategori açıklamalarıyla etiketleyen kaba nesne sınıflandırmasını da isteğe bağlı olarak etkinleştirebilirsiniz.

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

1. Nesne algılayıcıyı yapılandırın

Nesneleri algılamaya ve izlemeye başlamak için, önce isteğe bağlı olarak varsayılandan değiştirmek istediğiniz dedektör ayarlarını belirterek bir VisionObjectDetector örneği oluşturun.

  1. Kullanım durumunuz için nesne algılayıcıyı 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 dedektör, nesneleri çerçeveler arasında izlemek için kullanabileceğiniz izleme kimliklerini nesnelere atar. Nesneleri izlemek istediğinizde veya video akışlarını gerçek zamanlı olarak işlerken olduğu gibi düşük gecikmenin önemli olduğu durumlarda bu modu kullanın.

    Tek görüntü modunda, nesne algılayıcı, bir sonuç döndürmeden önce algılanan nesnenin sınırlayıcı kutusu ve (sınıflandırmayı etkinleştirdiyseniz) kategorisi kullanılabilir olana kadar bekler. Sonuç olarak, algılama gecikmesi potansiyel olarak daha yüksektir. Ayrıca, tek görüntü 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ılayın ve izleyin false (varsayılan) | true

    En fazla beş nesnenin mi yoksa yalnızca en belirgin nesnenin mi (varsayılan) algılanıp izleneceği.

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

    Algılanan nesnelerin kaba kategoriler halinde 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, yiyecekler, ev eşyaları, yerler, bitkiler ve bilinmeyen.

    Nesne algılama ve izleme API'si şu iki temel kullanım durumu için optimize edilmiştir:

    • Kamera vizöründe en belirgin nesnenin canlı tespiti ve takibi
    • Statik bir görüntüde birden çok nesnenin algılanması

    API'yi bu kullanım durumları için yapılandırmak için:

    Süratli

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

    Amaç-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ğini alın:

    Süratli

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

    Amaç-C

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

2. Nesne dedektörünü çalıştırın

Nesneleri algılamak ve izlemek için her görüntü veya video karesi için aşağıdakileri yapın. Akış modunu etkinleştirdiyseniz, CMSampleBufferRef s'den VisionImage nesneleri oluşturmalısınız.

  1. Bir UIImage veya bir 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 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];

    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:

      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;
  2. VisionImage 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:

    Süratli

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

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

    Süratli

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

    Amaç-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şlemcisine yapılan çağrı başarılı olursa, asenkron veya senkronize yöntemi çağırmanıza bağlı olarak, tamamlama işleyicisine bir VisionObject s listesini iletir veya listeyi döndürür.

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

    frame Görüntüdeki nesnenin konumunu gösteren bir CGRect .
    trackingID Görüntüler arasında nesneyi tanımlayan bir tam sayı. Tek görüntü modunda sıfır.
    classificationCategory Nesnenin kaba kategorisi. Nesne algılayıcıda sınıflandırma etkinleştirilmemişse, bu her zaman .unknown .
    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 nil .

    Süratli

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

    Amaç-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 şu yönergeleri izleyin:

  • Başarılı nesne algılama, nesnenin görsel karmaşıklığına bağlıdır. Az sayıda görsel özelliği olan nesnelerin algılanması için görüntünün daha büyük bir bölümünü kaplaması gerekebilir. Algılamak istediğiniz nesne türleriyle iyi çalışan girdi yakalama konusunda kullanıcılara rehberlik sağlamalısınız.
  • Sınıflandırmayı kullanırken, desteklenen kategorilere tam olarak girmeyen nesneleri algılamak istiyorsanız, bilinmeyen nesneler için özel işleme uygulayın.

Ayrıca, [ML Kit Material Design vitrin uygulaması][showcase-link]{: .external } ve makine öğrenimi destekli özellikler koleksiyonu için Materyal Tasarım Modelleri'ne göz atın.

Gerçek zamanlı bir uygulamada akış modunu kullanırken, en iyi kare hızlarını elde etmek için şu yönergeleri izleyin:

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

  • İhtiyacınız yoksa sınıflandırmayı devre dışı bırakı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.