Guida alla classificazione delle immagini per iOS

L'attività Classificatore di immagini consente di eseguire la classificazione sulle immagini. Puoi utilizzare questa attività per identificare ciò che un'immagine rappresenta in un insieme di categorie definite durante l'addestramento. Queste istruzioni mostrano come utilizzare il classificatore di immagini nelle app per 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 relativo alle attività di MediaPipe è un'implementazione di base di un'app di classificazione di immagini per iOS. L'esempio utilizza la fotocamera di un dispositivo iOS fisico per classificare continuamente gli oggetti e può anche utilizzare immagini e video della galleria dei dispositivi per classificare gli 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 classificatore di immagini è 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 comando seguente:

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

    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_classification/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 le istruzioni, consulta la Guida alla configurazione per iOS.

Componenti chiave

I seguenti file contengono il codice fondamentale per l'applicazione di esempio Image Classifier:

  • ImageClassifierService.swift: inizializza il classificatore di immagini, 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.
  • MediaLibraryViewController.swift Implementa l'interfaccia utente per la modalità di input di file di immagini statiche e video e visualizza i risultati.

Imposta

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

Dipendenze

Il classificatore di immagini 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 elemento Podfile con i pod necessari per la tua app, consulta Utilizzare CocoaPods.

Aggiungi il pod MediaPipeTasksVision in Podfile utilizzando il seguente codice:

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

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

Modello

L'attività classificatore di immagini MediaPipe richiede un modello addestrato che sia compatibile con questa attività. Per saperne di più sui modelli addestrati disponibili per il classificatore di immagini, consulta la sezione Modelli della panoramica delle attività.

Seleziona e scarica un modello, quindi aggiungilo alla directory del progetto utilizzando Xcode. Per istruzioni su come aggiungere file al progetto Xcode, consulta la sezione Gestire i file e le cartelle nel progetto Xcode.

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

Crea l'attività

Puoi creare l'attività Classificatore di immagini chiamando uno dei suoi inizializzatori. L'inizializzatore ImageClassifier(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 ti occorre un classificatore di immagini inizializzato con opzioni di configurazione personalizzate, puoi utilizzare l'inizializzatore ImageClassifier(modelPath:) per creare un classificatore di immagini con le opzioni predefinite. Per ulteriori informazioni sulle opzioni di configurazione, consulta Panoramica della configurazione.

L'attività Classificatore di immagini supporta tre tipi di dati di input: immagini fisse, file video e stream video in diretta. Per impostazione predefinita, ImageClassifier(modelPath:) inizializza un'attività per le immagini statiche. Se vuoi che l'attività venga inizializzata per elaborare file video o stream video in diretta, utilizza ImageClassifier(options:) per specificare la modalità di esecuzione video o live streaming. La modalità live streaming richiede anche l'opzione di configurazione imageClassifierLiveStreamDelegate aggiuntiva, che consente al classificatore di immagini di fornire al delegato i risultati di classificazione delle immagini in modo asincrono.

Scegli la scheda corrispondente alla tua modalità di esecuzione 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 = ImageClassifierOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .image
options.maxResults = 5

let imageClassifier = try ImageClassifier(options: options)
    

Video

import MediaPipeTasksVision

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

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

let imageClassifier = try ImageClassifier(options: options)
    

Live streaming

import MediaPipeTasksVision

// Class that conforms to the `ImageClassifierLiveStreamDelegate` protocol and
// implements the method that the image classifier calls once it
// finishes performing classification on each input frame.
class ImageClassifierResultProcessor: NSObject, ImageClassifierLiveStreamDelegate {

   func imageClassifier(
    _ imageClassifier: ImageClassifier,
    didFinishClassification result: ImageClassifierResult?,
    timestampInMilliseconds: Int,
    error: Error?) {

    // Process the image classifier result or errors here.

  }
}

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

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

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

let imageClassifier = try ImageClassifier(options: options)
    

Objective-C

Immagine

@import MediaPipeTasksVision;

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

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

MPPImageClassifier *imageClassifier =
      [[MPPImageClassifier alloc] initWithOptions:options error:nil];
    

Video

@import MediaPipeTasksVision;

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

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

MPPImageClassifier *imageClassifier =
      [[MPPImageClassifier alloc] initWithOptions:options error:nil];
    

Live streaming

@import MediaPipeTasksVision;

// Class that conforms to the `MPPImageClassifierLiveStreamDelegate` protocol
// and implements the method that the image classifier calls once it finishes
// performing classification on each input frame.

@interface APPImageClassifierResultProcessor : NSObject 

@end

@implementation APPImageClassifierResultProcessor

-   (void)imageClassifier:(MPPImageClassifier *)imageClassifier
    didFinishClassificationWithResult:(MPPImageClassifierResult *)imageClassifierResult
              timestampInMilliseconds:(NSInteger)timestampInMilliseconds
                                error:(NSError *)error {

    // Process the image classifier result or errors here.

}

@end

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

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

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

MPPImageClassifier *imageClassifier =
      [[MPPImageClassifier alloc] initWithOptions:options error:nil];
    

Opzioni di configurazione

Questa attività include 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 immagini singole.

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 impostare un listener in modo da ricevere i risultati in modo asincrono.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} RunningMode.image
displayNamesLocale 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 TensorFlow Metadata Writer Codice impostazioni internazionali it
maxResults Imposta il numero massimo facoltativo di risultati della classificazione con il punteggio più alto da restituire. Se < 0, vengono restituiti tutti i risultati disponibili. Qualsiasi numero positivo -1
scoreThreshold Imposta la soglia del punteggio della previsione che sostituisce quella fornita nei metadati del modello (se presente). I risultati al di sotto di questo valore vengono rifiutati. Qualsiasi numero in virgola mobile Non impostata
categoryAllowlist Consente di impostare l'elenco facoltativo di nomi di categorie consentiti. Se non è vuoto, i risultati della classificazione il cui nome della categoria non è incluso in questo set verranno filtrati. I nomi di categorie duplicati o sconosciuti vengono ignorati. Questa opzione si esclude a vicenda con categoryDenylist e utilizza entrambi i risultati in un errore. Qualsiasi stringa Non impostata
categoryDenylist Consente di impostare un elenco facoltativo di nomi di categorie non consentiti. Se il campo non è vuoto, i risultati della classificazione con nome della categoria incluso in questo set verranno filtrati. I nomi di categorie duplicati o sconosciuti vengono ignorati. Questa opzione si esclude a vicenda con categoryAllowlist e utilizza entrambi i risultati in un errore. Qualsiasi stringa Non impostata
resultListener Imposta il listener dei risultati in modo che riceva i risultati della classificazione in modo asincrono quando il classificatore di immagini è in modalità live streaming. Può essere utilizzato solo quando la modalità di corsa è impostata su LIVE_STREAM N/A Non impostata

Configurazione del live streaming

Quando la modalità di corsa è impostata su live streaming, il classificatore di immagini richiede l'opzione di configurazione imageClassifierLiveStreamDelegate aggiuntiva, che consente al classificatore di fornire i risultati della classificazione in modo asincrono. Il delegato implementa il metodo imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:), che il classificatore di immagini chiama dopo l'elaborazione dei risultati della classificazione per ogni frame.

Nome opzione Descrizione Intervallo di valori Valore predefinito
imageClassifierLiveStreamDelegate Consente al classificatore di immagini di ricevere i risultati della classificazione in modo asincrono in modalità live streaming. La classe la cui istanza è impostata su questa proprietà deve implementare il metodo imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:). Non applicabile Non impostata

preparazione dei dati

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

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

UIImage

Il formato UIImage è adatto alle seguenti modalità di corsa:

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

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

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 MPImage con l'orientamento predefinito UIImage.Orientation.Up. Puoi inizializzare MPImage con uno qualsiasi dei valori supportati per UIImage.Orientation. Il classificatore di immagini non supporta orientamenti speculari come .upMirrored, .downMirrored, .leftMirrored e .rightMirrored.

Per ulteriori informazioni su UIImage, consulta la Documentazione per sviluppatori Apple UIImage.

CVPixelBuffer

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

Il formato CVPixelBuffer è adatto alle seguenti modalità di corsa:

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

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

  • live streaming: le app che utilizzano una fotocamera iOS per generare fotogrammi possono essere convertite nel formato CVPixelBuffer per l'elaborazione prima di essere inviate al classificatore di immagini 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 maggiori informazioni su CVPixelBuffer, consulta la documentazione per sviluppatori Apple di CVPixelBuffer.

CMSampleBuffer

Il formato CMSampleBuffer archivia campioni multimediali di un tipo di media uniforme ed è adatto per la modalità di esecuzione in live streaming. I fotogrammi in diretta delle fotocamere iOS vengono trasmessi in modo asincrono nel formato CMSampleBuffer da 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 ulteriori informazioni su CMSampleBuffer, consulta la documentazione per sviluppatori Apple CMSampleBuffer.

Esegui l'attività

Per eseguire il classificatore di immagini, utilizza il metodo classify() specifico per la modalità di esecuzione assegnata:

  • Immagine statica: classify(image:)
  • Video: classify(videoFrame:timestampInMilliseconds:)
  • live streaming: classifyAsync(image:timestampInMilliseconds:)

Il classificatore di immagini restituisce le possibili categorie per l'oggetto all'interno dell'immagine o del frame di input.

I seguenti esempi di codice mostrano esempi di base di come eseguire il classificatore di immagini in queste diverse modalità di esecuzione:

Swift

Immagine

let result = try imageClassifier.classify(image: image)
    

Video

let result = try imageClassifier.classify(
  videoFrame: image,
  timestampInMilliseconds: timestamp)
    

Live streaming

try imageClassifier.classifyAsync(
  image: image,
  timestampInMilliseconds: timestamp)
    

Objective-C

Immagine

MPPImageClassifierResult *result = [imageClassifier classifyImage:image
                                                            error:nil];
    

Video

MPPImageClassifierResult *result = [imageClassifier classifyVideoFrame:image
                                               timestampInMilliseconds:timestamp
                                                                 error:nil];
    

Live streaming

BOOL success = [imageClassifier classifyAsyncImage:image
                          timestampInMilliseconds:timestamp
                                            error:nil];
    

L'esempio di codice del classificatore di immagini mostra le implementazioni di ciascuna di queste modalità in modo più dettagliato classify(image:), classify(videoFrame:timestampInMilliseconds:) e classifyAsync(image:timestampInMilliseconds:). Il codice di esempio consente all'utente di passare da una modalità di elaborazione all'altra che potrebbe non essere necessaria per il tuo caso d'uso.

Tieni presente quanto riportato di seguito:

  • Quando utilizzi la modalità video o live streaming, devi anche fornire il timestamp del fotogramma di input all'attività Classificatore di immagini.

  • Quando è in esecuzione in modalità immagine o video, l'attività Classificatore di immagini blocca il thread corrente finché non termina 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 Dispatch o NSOperation di iOS.

  • Quando viene eseguita in modalità live streaming, l'attività Classificatore di immagini restituisce immediatamente e non blocca il thread corrente. Chiama il metodo imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:) con il risultato della classificazione dopo l'elaborazione di ogni frame di input. Il classificatore di immagini richiama questo metodo in modo asincrono su una coda di invio seriale dedicata. Per visualizzare i risultati nell'interfaccia utente, inviali alla coda principale dopo averli elaborati. Se la funzione classifyAsync viene chiamata quando l'attività Classificatore di immagini è impegnata a elaborare un altro frame, il classificatore di immagini ignora il nuovo frame di input.

Gestire e visualizzare i risultati

Dopo l'esecuzione dell'inferenza, l'attività Classificatore di immagini restituisce un oggetto ImageClassifierResult che contiene l'elenco di possibili categorie per gli oggetti all'interno dell'immagine o del frame di input.

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

ImageClassifierResult:
 Classifications #0 (single classification head):
  head index: 0
  category #0:
   category name: "/m/01bwb9"
   display name: "Passer domesticus"
   score: 0.91406
   index: 671
  category #1:
   category name: "/m/01bwbt"
   display name: "Passer montanus"
   score: 0.00391
   index: 670

Questo risultato è stato ottenuto eseguendo la classe Bird Classifier su:

Il codice di esempio del classificatore di immagini mostra come visualizzare i risultati della classificazione restituiti dall'attività. Per i dettagli, consulta l'esempio di codice.