Guida al rilevamento di oggetti per iOS

L'attività Rilevamento di oggetti consente di rilevare la presenza e la posizione di più classi di oggetti. Ad esempio, un rilevatore di oggetti può individuare dei cani all'interno di un'immagine. Queste istruzioni mostrano come utilizzare l'attività Rilevamento di oggetti in iOS. L'esempio di codice descritto in queste istruzioni è disponibile su GitHub.

Puoi vedere questa attività in azione visualizzando questa demo web. Per ulteriori informazioni sulle funzionalità, sui modelli e sulle opzioni di configurazione di questa attività, consulta la Panoramica.

Esempio di codice

Il codice di esempio di MediaPipe Tasks è un'implementazione di base di un'app Object Detector per iOS. L'esempio utilizza la fotocamera di un dispositivo iOS fisico per rilevare in modo continuo gli oggetti e può anche utilizzare immagini e video della galleria dei dispositivi per rilevare oggetti in modo statico.

Puoi utilizzare l'app come punto di partenza per la tua app per iOS o farvi riferimento quando modifichi un'app esistente. Il codice di esempio del rilevatore di oggetti è ospitato su GitHub.

Scarica il codice

Le seguenti istruzioni mostrano come creare una copia locale del codice di esempio utilizzando lo strumento a riga di comando git.

Per scaricare il codice di esempio:

  1. Clona il repository git utilizzando il seguente comando:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Facoltativamente, configura la tua istanza Git in modo da utilizzare il pagamento sparse, in modo da avere solo i file per l'app di esempio di Rilevamento di oggetti:

    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/object_detection/ios/
    

Dopo aver creato una versione locale del codice di esempio, puoi installare la libreria di attività MediaPipe, aprire il progetto utilizzando Xcode ed eseguire l'app. Per istruzioni, consulta la Guida alla configurazione per iOS.

Componenti chiave

I seguenti file contengono il codice fondamentale per l'applicazione di esempio di rilevamento di oggetti:

  • ObjectDetectorService.swift: inizializza il rilevatore, gestisce la selezione del modello ed esegue l'inferenza sui dati di input.
  • CameraViewController.swift: implementa l'UI per la modalità di immissione del feed della videocamera in diretta e visualizza i risultati del rilevamento.
  • MediaLibraryViewController.swift: implementa l'interfaccia utente per la modalità di input di immagini fisse e video e visualizza i risultati del rilevamento.

Configurazione

Questa sezione descrive i passaggi chiave per configurare l'ambiente di sviluppo e i progetti di codice per l'utilizzo di Rilevamento di oggetti. Per informazioni generali sulla configurazione dell'ambiente di sviluppo per l'utilizzo delle attività MediaPipe, inclusi i requisiti di versione della piattaforma, consulta la Guida alla configurazione per iOS.

Dipendenze

Il rilevatore di oggetti utilizza la libreria MediaPipeTasksVision, che deve essere installata utilizzando CocoaPods. La libreria è compatibile con le app Swift e Objective-C e non richiede alcuna configurazione aggiuntiva specifica per la lingua.

Per istruzioni su come installare CocoaPods su macOS, consulta la guida all'installazione di CocoaPods. Per istruzioni su come creare un Podfile con i pod necessari per la tua app, consulta la sezione Utilizzare CocoaPods.

Aggiungi il pod MediaPipeTasksVision in Podfile utilizzando il seguente codice:

target 'MyObjectDetectorApp' do
  use_frameworks!
  pod 'MediaPipeTasksVision'
end

Se la tua app include target per il test delle unità, consulta la Guida alla configurazione per iOS per ulteriori informazioni sulla configurazione di Podfile.

Modello

L'attività Rilevamento di oggetti MediaPipe richiede un modello addestrato compatibile con questa attività. Per ulteriori informazioni sui modelli addestrati disponibili per il rilevatore di oggetti, consulta la sezione Modelli della panoramica dell'attività.

Seleziona e scarica un modello, quindi aggiungilo alla directory del progetto utilizzando Xcode. Per istruzioni su come aggiungere file al progetto Xcode, consulta Gestione di file e cartelle nel progetto Xcode.

Utilizza la proprietà BaseOptions.modelAssetPath per specificare il percorso del modello nel tuo app bundle. Per un esempio di codice, consulta la sezione successiva.

Creare l'attività

Puoi creare l'attività Rilevamento di oggetti chiamando uno dei suoi inizializzatori. L'inizializzazione ObjectDetector(options:) imposta i valori per le opzioni di configurazione, tra cui modalità di esecuzione, impostazioni internazionali dei nomi visualizzati, numero massimo di risultati, soglia di confidenza, lista consentita di categorie e lista bloccata.

Se non hai bisogno di un rilevatore di oggetti inizializzato con opzioni di configurazione personalizzate, puoi utilizzare l'inizializzazione ObjectDetector(modelPath:) per creare un rilevatore di oggetti con le opzioni predefinite. Per ulteriori informazioni sulle opzioni di configurazione, consulta Panoramica della configurazione.

L'attività Rilevamento di oggetti supporta tre tipi di dati di input: immagini fisse, file video e stream video in diretta. Per impostazione predefinita, ObjectDetector(modelPath:) inizializza un'attività per le immagini statiche. Se vuoi che l'attività venga inizializzata allo scopo di elaborare file video o stream video in diretta, usa ObjectDetector(options:) per specificare la modalità di esecuzione del video o del live streaming. La modalità live streaming richiede anche l'opzione di configurazione objectDetectorLiveStreamDelegate aggiuntiva, che consente al rilevatore di oggetti di fornire i risultati di rilevamento al delegato in modo asincrono.

Scegli la scheda corrispondente alla modalità di corsa per vedere come creare l'attività ed eseguire l'inferenza.

Swift

Immagine

import MediaPipeTasksVision

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "tflite")

let options = ObjectDetectorOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .image
options.maxResults = 5

let objectDetector = try ObjectDetector(options: options)
    

Video

import MediaPipeTasksVision

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "tflite")

let options = ObjectDetectorOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .video
options.maxResults = 5

let objectDetector = try ObjectDetector(options: options)
    

live streaming

import MediaPipeTasksVision

// Class that conforms to the `ObjectDetectorLiveStreamDelegate` protocol and
// implements the method that the object detector calls once it
// finishes performing detection on each input frame.
class ObjectDetectorResultProcessor: NSObject, ObjectDetectorLiveStreamDelegate {

  func objectDetector(
    _ objectDetector: ObjectDetector,
    didFinishDetection objectDetectionResult: ObjectDetectorResult?,
    timestampInMilliseconds: Int,
    error: Error?) {
    // Process the detection result or errors here.
  }
}

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "tflite")

let options = ObjectDetectorOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .liveStream
options.maxResults = 5

// Assign an object of the class to the `objectDetectorLiveStreamDelegate`
// property.
let processor = ObjectDetectorResultProcessor()
options.objectDetectorLiveStreamDelegate = processor

let objectDetector = try ObjectDetector(options: options)
    

Objective-C

Immagine

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPObjectDetectorOptions *options = [[MPPObjectDetectorOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeImage;
options.maxResults = 5;

MPPObjectDetector *objectDetector =
      [[MPPObjectDetector alloc] initWithOptions:options error:nil];
    

Video

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPObjectDetectorOptions *options = [[MPPObjectDetectorOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeVideo;
options.maxResults = 5;

MPPObjectDetector *objectDetector =
      [[MPPObjectDetector alloc] initWithOptions:options error:nil];
    

live streaming

@import MediaPipeTasksVision;

// Class that conforms to the `ObjectDetectorLiveStreamDelegate` protocol and
// implements the method that the object detector calls once it
// finishes performing detection on each input frame.

@interface APPObjectDetectorResultProcessor : NSObject 

@end

@implementation MPPObjectDetectorResultProcessor

-   (void)objectDetector:(MPPObjectDetector *)objectDetector
    didFinishDetectionWithResult:(MPPObjectDetectorResult *)ObjectDetectorResult
         timestampInMilliseconds:(NSInteger)timestampInMilliseconds
                           error:(NSError *)error {

    // Process the detection result or errors here.

}

@end

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPObjectDetectorOptions *options = [[MPPObjectDetectorOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeLiveStream;
options.maxResults = 5;

// Assign an object of the class to the `objectDetectorLiveStreamDelegate`
// property.
APPObjectDetectorResultProcessor *processor = [APPObjectDetectorResultProcessor new];
options.objectDetectorLiveStreamDelegate = processor;

MPPObjectDetector *objectDetector =
      [[MPPObjectDetector alloc] initWithOptions:options error:nil];
    

Opzioni di configurazione

Questa attività prevede le seguenti opzioni di configurazione per le app per iOS:

Nome opzione Descrizione Intervallo di valori Valore predefinito
runningMode Imposta la modalità di esecuzione per l'attività. Esistono tre modalità:

IMAGE: la modalità per gli input di singole immagini.

VIDEO: la modalità per i fotogrammi decodificati di un video.

LIVE_STREAM: la modalità per un live streaming di dati di input, ad esempio da una videocamera. In questa modalità, resultListener deve essere chiamato per configurare un listener per ricevere i risultati in modo asincrono.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} RunningMode.image
displayNamesLocales Imposta la lingua delle etichette da utilizzare per i nomi visualizzati forniti nei metadati del modello dell'attività, se disponibili. Il valore predefinito è en per l'inglese. Puoi aggiungere etichette localizzate ai metadati di un modello personalizzato utilizzando l'API Metadata Writer di TensorFlow Lite Codice impostazioni internazionali it
maxResults Imposta il numero massimo facoltativo di risultati di rilevamento con il punteggio più alto da restituire. Eventuali numeri positivi -1 (vengono restituiti tutti i risultati)
scoreThreshold Imposta la soglia del punteggio di previsione che sostituisce quella fornita nei metadati del modello (se presenti). I risultati inferiori a questo valore vengono rifiutati. Qualsiasi elemento in virgola mobile Non impostata
categoryAllowlist Consente di impostare l'elenco facoltativo di nomi di categorie consentite. Se il campo non è vuoto, i risultati del rilevamento il cui nome di categoria non è in questo set verranno filtrati. I nomi di categoria duplicati o sconosciuti vengono ignorati. Questa opzione si esclude a vicenda con categoryDenylist e l'utilizzo di entrambe genera un errore. Qualsiasi stringa Non impostata
categoryDenylist Consente di impostare l'elenco facoltativo di nomi di categorie non consentiti. Se il campo non è vuoto, i risultati del rilevamento il cui nome di categoria è presente in questo set verranno filtrati. I nomi di categoria duplicati o sconosciuti vengono ignorati. Questa opzione si esclude a vicenda con categoryAllowlist e l'uso di entrambe genera un errore. Qualsiasi stringa Non impostata

Configurazione del live streaming

Quando la modalità di esecuzione è impostata su live streaming, il rilevatore di oggetti richiede l'opzione di configurazione objectDetectorLiveStreamDelegate aggiuntiva, che consente al rilevatore di fornire i risultati del rilevamento in modo asincrono. Il delegato implementa il metodo objectDetector(_objectDetector:didFinishDetection:timestampInMilliseconds:error:), che il rilevatore di oggetti chiama dopo l'elaborazione del risultato del rilevamento per ogni frame.

Nome opzione Descrizione Intervallo di valori Valore predefinito
objectDetectorLiveStreamDelegate Consente al rilevatore di oggetti di ricevere i risultati del rilevamento in modo asincrono in modalità live streaming. La classe la cui istanza è impostata su questa proprietà deve implementare il metodo objectDetector(_:didFinishDetection:timestampInMilliseconds:error:). Non applicabile Non impostata

Preparazione dei dati

Devi convertire l'immagine o il frame di input in un oggetto MPImage prima di passarlo al rilevatore di oggetti. MPImage supporta diversi tipi di formati delle immagini per iOS e può utilizzarli in qualsiasi modalità di esecuzione per l'inferenza. Per ulteriori informazioni su MPImage, consulta la pagina relativa all'API MPImage

Scegli il formato dell'immagine per iOS in base al tuo caso d'uso e alla modalità di esecuzione richiesta dalla tua applicazione.MPImage accetta i formati di immagine per iOS UIImage, CVPixelBuffer e CMSampleBuffer.

UIImage

Il formato UIImage è adatto per le seguenti modalità di corsa:

  • Immagini: le immagini di un app bundle, di una galleria utente o di un file system formattate come UIImage immagini possono essere convertite in un oggetto MPImage.

  • Video: utilizza AVAssetImageGenerator per estrarre fotogrammi video nel formato CGImage, quindi convertili in UIImage immagini.

Swift

// Load an image on the user's device as an iOS `UIImage` object.

// Convert the `UIImage` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(uiImage: image)
    

Objective-C

// Load an image on the user's device as an iOS `UIImage` object.

// Convert the `UIImage` object to a MediaPipe's Image object having the default
// orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
    

L'esempio inizializza un elemento MPImage con l'orientamento predefinito UIImage.Orientation.Up. Puoi inizializzare un elemento MPImage con uno qualsiasi dei valori supportati per UIImage.Orientation. Il rilevatore di oggetti non supporta gli orientamenti speculari come .upMirrored, .downMirrored, .leftMirrored, .rightMirrored.

Per ulteriori informazioni su UIImage, consulta la documentazione per gli sviluppatori di Apple nell'interfaccia UI.

CVPixelBuffer

Il formato CVPixelBuffer è ideale per le applicazioni che generano frame e utilizzano il framework CoreImage di iOS per l'elaborazione.

Il formato CVPixelBuffer è adatto per le seguenti modalità di corsa:

  • Immagini: le app che generano immagini CVPixelBuffer dopo un'elaborazione utilizzando il framework CoreImage di iOS possono essere inviate al rilevatore di oggetti in modalità di esecuzione delle immagini.

  • Video: i fotogrammi video possono essere convertiti nel formato CVPixelBuffer per l'elaborazione e poi inviati al rilevatore di oggetti in modalità video.

  • live streaming: le app che utilizzano una fotocamera iOS per generare frame possono essere convertite nel formato CVPixelBuffer per l'elaborazione prima di essere inviate al rilevatore di oggetti in modalità live streaming.

Swift

// Obtain a CVPixelBuffer.

// Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(pixelBuffer: pixelBuffer)
    

Objective-C

// Obtain a CVPixelBuffer.

// Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the
// default orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
    

Per ulteriori informazioni su CVPixelBuffer, consulta la documentazione per gli sviluppatori di Apple CVPixelBuffer.

CMSampleBuffer

Il formato CMSampleBuffer archivia esempi di contenuti multimediali di un tipo di media uniforme ed è adatto per la modalità di esecuzione live streaming. I fotogrammi in tempo reale delle fotocamere iOS vengono inviati in modo asincrono nel formato CMSampleBuffer da iOS AVCaptureVideoDataOutput.

Swift

// Obtain a CMSampleBuffer.

// Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(sampleBuffer: sampleBuffer)
    

Objective-C

// Obtain a `CMSampleBuffer`.

// Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the
// default orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithSampleBuffer:sampleBuffer error:nil];
    

Per maggiori informazioni su CMSampleBuffer, consulta la documentazione per gli sviluppatori Apple CMSampleBuffer.

Esegui l'attività

Per eseguire il rilevatore di oggetti, utilizza il metodo detect() specifico per la modalità di esecuzione assegnata:

  • Immagine statica: detect(image:)
  • Video: detect(videoFrame:timestampInMilliseconds:)
  • live streaming: detectAsync(image:)

I seguenti esempi di codice mostrano esempi di base di come eseguire Rilevamento di oggetti in queste diverse modalità di esecuzione:

Swift

Immagine

let objectDetector.detect(image:image)
    

Video

let objectDetector.detect(videoFrame:image)
    

live streaming

let objectDetector.detectAsync(image:image)
    

Objective-C

Immagine

MPPObjectDetectorResult *result = [objectDetector detectInImage:image error:nil];
    

Video

MPPObjectDetectorResult *result = [objectDetector detectInVideoFrame:image          timestampInMilliseconds:timestamp error:nil];
    

live streaming

BOOL success = [objectDetector detectAsyncInImage:image
                          timestampInMilliseconds:timestamp
                                            error:nil];
    

L'esempio di codice del rilevatore di oggetti mostra le implementazioni di ciascuna di queste modalità in modo più dettagliato detect(image:), detect(videoFrame:) e detectAsync(image:). Il codice di esempio consente all'utente di passare da una modalità di elaborazione all'altra, che potrebbero non essere necessarie per il tuo caso d'uso.

Tieni presente quanto riportato di seguito:

  • Quando l'esecuzione è in modalità video o live streaming, devi anche fornire il timestamp del frame di input all'attività di rilevamento di oggetti.

  • Quando viene eseguita in modalità immagine o video, l'attività Rilevamento di oggetti blocca il thread corrente fino a quando non completa l'elaborazione dell'immagine o del frame di input. Per evitare di bloccare il thread corrente, esegui l'elaborazione in un thread in background utilizzando i framework per iOS Dispatch o NSOperation.

  • Quando è in esecuzione in modalità live streaming, l'attività Rilevamento oggetti restituisce immediatamente e non blocca il thread corrente. Richiama il metodo objectDetector(_objectDetector:didFinishDetection:timestampInMilliseconds:error:) con il risultato del rilevamento dopo l'elaborazione di ogni frame di input. Il rilevatore di oggetti richiama questo metodo in modo asincrono su una coda di invio seriale dedicata. Per visualizzare i risultati nell'interfaccia utente, invia i risultati alla coda principale dopo l'elaborazione dei risultati. Se la funzione detectAsync viene richiamata quando l'attività di rilevamento di oggetti è impegnata a elaborare un altro frame, il rilevatore di oggetti ignora il nuovo frame di input.

Gestire e visualizzare i risultati

Dopo aver eseguito l'inferenza, l'attività Rilevamento di oggetti restituisce un oggetto ObjectDetectorResult che descrive gli oggetti trovati nell'immagine di input.

Di seguito è riportato un esempio dei dati di output di questa attività:

ObjectDetectorResult:
 Detection #0:
  Box: (x: 355, y: 133, w: 190, h: 206)
  Categories:
   index       : 17
   score       : 0.73828
   class name  : dog
 Detection #1:
  Box: (x: 103, y: 15, w: 138, h: 369)
  Categories:
   index       : 17
   score       : 0.73047
   class name  : dog

L'immagine seguente mostra una visualizzazione dell'output dell'attività:

Il codice di esempio del rilevatore di oggetti mostra come visualizzare i risultati del rilevamento restituiti dall'attività. Per i dettagli, consulta l'esempio di codice.