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

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 algılanan en fazla beş nesnenin ve bunların görüntüdeki konumlarının bir listesini döndürür. Video akışlarında nesneleri tespit ederken her nesnenin, nesneyi görüntüler arasında takip etmek için kullanabileceğiniz bir kimliği vardır. Ayrıca isteğe bağlı olarak nesneleri geniş kategori açıklamalarıyla etiketleyen kaba nesne sınıflandırmasını da etkinleştirebilirsiniz.

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'
    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 öncelikle bir VisionObjectDetector örneği oluşturun ve isteğe bağlı olarak varsayılandan değiştirmek istediğiniz dedektör ayarlarını belirtin.

  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 Dedektörü 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 kareler 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 dedektörü, bir sonuç döndürmeden önce algılanan nesnenin sınırlayıcı kutusunun ve (sınıflandırmayı etkinleştirdiyseniz) kategorisinin kullanılabilir olmasını 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 fazla nesneyi tespit edin ve izleyin false (varsayılan) | true

    Beş nesneye kadar mı yoksa yalnızca en belirgin nesneyi mi algılayıp izleyeceğiniz (varsayılan).

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

    Algılanan nesnelerin kaba kategorilere ayrılıp sınıflandırılmayacağı. Etkinleştirildiğinde, nesne dedektörü nesneleri şu kategorilere göre sınıflandırır: moda ürünleri, yiyecek, ev eşyaları, yerler, bitkiler ve bilinmeyenler.

    Nesne algılama ve izleme API'si bu 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 fazla nesnenin algılanması

    API'yi bu kullanım örneklerine göre 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şturmanız gerekir.

  1. 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;
  2. VisionImage nesne dedektörünün görüntü işleme yöntemlerinden birine aktarın. 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, eşzamansız veya eşzamanlı yöntemi çağırmanıza bağlı olarak ya VisionObject bir listesini tamamlama işleyicisine iletir ya da listeyi döndürür.

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

    frame Nesnenin görüntüdeki konumunu belirten bir CGRect .
    trackingID Görüntülerdeki nesneyi tanımlayan bir tamsayı. Tek görüntü modunda sıfır.
    classificationCategory Nesnenin kaba kategorisi. Nesne algılayıcının sınıflandırması etkin değilse bu her zaman .unknown olur.
    confidence Nesne sınıflandırmasının güven değeri. Nesne algılayıcının sınıflandırması etkin değilse 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 tespiti, nesnenin görsel karmaşıklığına bağlıdır. Az sayıda görsel özelliğe sahip nesnelerin tespit edilebilmesi 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 sonuç veren girdiyi yakalama konusunda kullanıcılara rehberlik sağlamalısınız.
  • Sınıflandırmayı kullanırken, desteklenen kategorilere tam olarak girmeyen nesneleri tespit etmek istiyorsanız, bilinmeyen nesneler için özel işleme uygulayın.

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

Gerçek zamanlı bir uygulamada akış modunu kullanırken en iyi kare hızlarına ulaşmak 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ö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.