Rileva e monitora gli oggetti con ML Kit su iOS

Puoi utilizzare ML Kit per rilevare e tracciare oggetti attraverso i fotogrammi del video.

Quando passi le immagini ML Kit, ML Kit restituisce per ogni immagine un elenco rilevati fino a cinque oggetti e la loro posizione nell'immagine. Quando vengono rilevati oggetti negli stream video, ogni oggetto ha un ID che puoi utilizzare per monitorarlo nelle immagini. Se vuoi, puoi anche attivare la classificazione approssimativa degli oggetti, che etichetta gli oggetti con descrizioni di categorie generali.

Prima di iniziare

  1. Se non hai già aggiunto Firebase alla tua app, puoi farlo seguendo le istruzioni riportate in passaggi nella Guida introduttiva.
  2. Includi le librerie del kit ML nel tuo podfile:
    pod 'Firebase/MLVision', '6.25.0'
    pod 'Firebase/MLVisionObjectDetection', '6.25.0'
    
    Dopo aver installato o aggiornato i pod del progetto, assicurati di aprire il progetto Xcode utilizzando il relativo .xcworkspace.
  3. Nell'app, importa Firebase:
    import Firebase
    @import Firebase;

1. configura il rilevatore di oggetti

Per iniziare a rilevare e monitorare gli oggetti, crea innanzitutto un'istanza di VisionObjectDetector, specificando facoltativamente le impostazioni del rilevatore che vuoi modificare quello predefinito.

  1. Configura il rilevatore di oggetti per il tuo caso d'uso con un VisionObjectDetectorOptions oggetto. Puoi modificare le seguenti opzioni: impostazioni:

    Impostazioni del rilevatore di oggetti
    Modalità di rilevamento .stream (valore predefinito) | .singleImage

    In modalità flusso (impostazione predefinita), il rilevatore di oggetti funziona con un ma potrebbe produrre risultati incompleti (ad esempio, riquadri di delimitazione o categoria) alle prime chiamate di il rilevatore. Inoltre, in modalità stream, il rilevatore assegna agli oggetti ID di monitoraggio che puoi utilizzare per monitorarli nei fotogrammi. Utilizza questa modalità quando vuoi monitorare oggetti o quando è importante una bassa latenza, ad esempio durante l'elaborazione di stream video in tempo reale.

    In modalità immagine singola, il rilevatore di oggetti attende che venga rilevato riquadro di delimitazione dell'oggetto e (se hai abilitato la classificazione) disponibili prima di restituire un risultato. Di conseguenza, la latenza del rilevamento è potenzialmente più elevata. Inoltre, in un'immagine singola , gli ID monitoraggio non vengono assegnati. Usa questa modalità in caso di latenza non è fondamentale e non vuoi gestire che consentono di analizzare i dati e visualizzare i risultati.

    Rilevamento e tracciamento di più oggetti false (predefinito) | true

    Indica se rilevare e tracciare fino a cinque oggetti o solo il più ben visibile (impostazione predefinita).

    Classificare gli oggetti false (valore predefinito) | true

    Indica se classificare o meno gli oggetti rilevati in categorie approssimative. Se abilitato, il rilevatore di oggetti classifica gli oggetti nell'intervallo seguenti categorie: articoli di moda, cibo, casalinghi, luoghi, piante e sconosciuti.

    L'API di rilevamento e monitoraggio degli oggetti è ottimizzata per questi due usi principali casi:

    • Rilevamento e tracciamento in tempo reale dell'oggetto più in evidenza nella videocamera mirino
    • Rilevamento di più oggetti in un'immagine statica

    Per configurare l'API per questi casi d'uso:

    // 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
    
    // 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. Ottieni un'istanza di FirebaseVisionObjectDetector:

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

2. Esegui il rilevatore di oggetti

Per rilevare e tracciare oggetti, procedi nel seguente modo per ogni immagine o fotogramma del video. Se hai abilitato la modalità flusso di dati, devi creare VisionImage oggetti da CMSampleBufferRef

  1. Crea un oggetto VisionImage utilizzando un UIImage o un CMSampleBufferRef.

    Per usare un UIImage:

    1. Se necessario, ruota l'immagine in modo che imageOrientation è .up.
    2. Crea un oggetto VisionImage utilizzando l'oggetto ruotato correttamente UIImage. Non specificare alcun metadato di rotazione (l'impostazione predefinita) è necessario utilizzare il valore .topLeft.
      let image = VisionImage(image: uiImage)
      FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];

    Per usare un CMSampleBufferRef:

    1. Crea un oggetto VisionImageMetadata che specifichi l'orientamento dei dati dell'immagine contenuti buffer CMSampleBufferRef.

      Per ottenere l'orientamento dell'immagine:

      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
          }
      }
      - (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;
        }
      }

      Quindi, crea l'oggetto dei metadati:

      let cameraPosition = AVCaptureDevice.Position.back  // Set to the capture device you used.
      let metadata = VisionImageMetadata()
      metadata.orientation = imageOrientation(
          deviceOrientation: UIDevice.current.orientation,
          cameraPosition: cameraPosition
      )
      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. Crea un oggetto VisionImage utilizzando il metodo Oggetto CMSampleBufferRef e metadati di rotazione:
      let image = VisionImage(buffer: sampleBuffer)
      image.metadata = metadata
      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  2. Passa VisionImage a uno dei sistemi di elaborazione delle immagini del rilevatore di oggetti di machine learning. Puoi utilizzare il metodo process(image:) asincrono oppure metodo results() sincrono.

    Per rilevare gli oggetti in modo asincrono:

    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.
      // ...
    }
    
    [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.
                        // ...
                      }];
    

    Per rilevare gli oggetti in modo sincrono:

    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
    }
    
    // ...
    
    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. Se la chiamata al processore di immagini ha esito positivo, passa un elenco di VisionObject al gestore del completamento o restituisce l'elenco, a seconda del a seconda che tu abbia chiamato il metodo asincrono o sincrono.

    Ogni VisionObject contiene le seguenti proprietà:

    frame Un elemento CGRect che indica la posizione dell'oggetto nell'intervallo dell'immagine.
    trackingID Un numero intero che identifica l'oggetto attraverso le immagini. Nil in modalità di immagine singola.
    classificationCategory La categoria approssimativa dell'oggetto. Se il rilevatore di oggetti non ha attivato la classificazione, questo valore è sempre .unknown.
    confidence Il valore di confidenza della classificazione dell'oggetto. Se il rilevatore di oggetti non ha la classificazione abilitata o se l'oggetto è classificato come sconosciuto, il valore è nil.
    // 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
    }
    
    // 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;
    }
    

Migliorare l'usabilità e le prestazioni

Per una migliore esperienza utente, segui queste linee guida nella tua app:

  • Il successo del rilevamento degli oggetti dipende dalla complessità visiva dell'oggetto. Oggetti con un numero ridotto di caratteristiche visive, potrebbe dover occupare una parte dell'immagine da rilevare. Devi fornire agli utenti indicazioni su come acquisire che funzioni bene con il tipo di oggetti che vuoi rilevare.
  • Quando usi la classificazione, se vuoi rilevare gli oggetti che non cadono nelle categorie supportate, implementare una gestione speciale per di oggetti strutturati.

Consulta anche [App vetrina ML Kit Material Design][showcase-link]{: .external } e i Material design Raccolta di pattern per le funzionalità basate sul machine learning.

Quando utilizzi la modalità flusso di dati in un'applicazione in tempo reale, segui queste linee guida per ottenere le migliori frequenze fotogrammi:

  • Non utilizzare il rilevamento di più oggetti in modalità flusso di dati, perché la maggior parte dei dispositivi non essere in grado di produrre frequenze fotogrammi adeguate.

  • Disabilita la classificazione se non ti serve.

  • Limita le chiamate al rilevatore. Se un nuovo fotogramma disponibili mentre il rilevatore è in esecuzione, abbandona il frame.
  • Se utilizzi l'output del rilevatore per sovrapporre gli elementi grafici l'immagine di input, occorre prima ottenere il risultato da ML Kit, quindi eseguire il rendering dell'immagine e la sovrapposizione in un solo passaggio. In questo modo, puoi visualizzare i contenuti solo una volta per ogni frame di input. Guarda previewOverlayView. e FIRDetectionOverlayView nell'app di esempio Showcase.

ML Kit for Firebase provided ready-to-use ML solutions for app developers. New apps should use the standalone ML Kit library for on-device ML and Firebase ML for cloud-based ML.

Aggiornamento: Feb 28, 2025

ML Kit for Firebase provided ready-to-use ML solutions for app developers. New apps should use the standalone ML Kit library for on-device ML and Firebase ML for cloud-based ML.

Aggiornamento: Feb 28, 2025

ML Kit for Firebase provided ready-to-use ML solutions for app developers. New apps should use the standalone ML Kit library for on-device ML and Firebase ML for cloud-based ML.

Aggiornamento: Feb 28, 2025