Guida all'inserimento di immagini per iOS

L'attività MediaPipe Image Embedder consente di convertire i dati delle immagini in una rappresentazione numerica per eseguire attività di elaborazione delle immagini correlate all'IA, ad esempio il confronto della somiglianza di due immagini.

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 di incorporamento di immagini per iOS. L'esempio utilizza la fotocamera su un dispositivo iOS fisico per incorporare continuamente le immagini e può anche eseguire l'incorporatore sui file immagine della galleria del dispositivo.

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 di Image Embedder è ospitato su GitHub.

Scarica il codice

Le istruzioni riportate di seguito 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 questo comando:

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

    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_embedder/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 di incorporamento di immagini:

  • ImageEmbedderService.swift: inizializza l'Inserzionista di immagini, gestisce la selezione del modello ed esegue l'inferenza sui dati di input.
  • CameraViewController.swift: implementa l'interfaccia utente per la modalità di inserimento del feed videocamera in diretta e visualizza i risultati.
  • MediaLibraryViewController.swift: implementa l'interfaccia utente per la modalità di inserimento di immagini fisse e visualizza i risultati.

Configurazione

In questa sezione vengono descritti i passaggi chiave per la configurazione dell'ambiente di sviluppo e dei progetti di codice per l'utilizzo di Image Embedder. 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

Image Embedder 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 il linguaggio.

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 Utilizzare CocoaPods.

Aggiungi il pod MediaPipeTasksVision in Podfile utilizzando il seguente codice:

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

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

Modello

L'attività MediaPipe Image Embedder richiede un modello addestrato compatibile con questa attività. Per saperne di più sui modelli addestrati disponibili per lo strumento di incorporamento delle immagini, consulta la sezione Modelli.

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

Utilizza la proprietà BaseOptions.modelAssetPath per specificare il percorso del modello nell'app bundle.

Crea l'attività

Puoi creare l'attività Image Embedder richiamando uno dei suoi inizializzatori. L'inizializzatore ImageEmbedder(options:) accetta i valori per le opzioni di configurazione.

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

L'attività di incorporamento di immagini supporta tre tipi di dati di input: immagini fisse, file video e stream video dal vivo. Per impostazione predefinita, ImageEmbedder(modelPath:) inizializza un compito per le immagini fisse. Se vuoi che l'attività venga inizializzata per elaborare file video o stream video in diretta, utilizza ImageEmbedder(options:) per specificare la modalità di esecuzione del video o del live streaming. La modalità live streaming richiede anche l'opzione di configurazione aggiuntivaimageEmbedderLiveStreamDelegate, che consente a Image Embedder di inviare i risultati dell'inserimento delle immagini al delegato in modo asincrono.

Scegli la scheda corrispondente alla modalità di esecuzione per scoprire come creare il compito e eseguire l'inferenza.

Swift

Immagine

import MediaPipeTasksVision

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

let options = ImageEmbedderOptions()
options.baseOptions.modelAssetPath = modelPath
options.quantize = true
options.l2Normalize = true

let imageEmbedder = try ImageEmbedder(options: options)
    

Video

import MediaPipeTasksVision

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

let options = ImageEmbedderOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .video
options.quantize = true
options.l2Normalize = true

let imageEmbedder = try ImageEmbedder(options: options)
    

Live streaming

import MediaPipeTasksVision

// Class that conforms to the `ImageEmbedderLiveStreamDelegate` protocol and
// implements the method that the image embedder calls once it finishes
// embedding each input frame.
class ImageEmbedderResultProcessor: NSObject, ImageEmbedderLiveStreamDelegate {

  func imageEmbedder(
    _ imageEmbedder: ImageEmbedder,
    didFinishEmbedding result: ImageEmbedderResult?,
    timestampInMilliseconds: Int,
    error: Error?) {

    // Process the image embedder result or errors here.

  }
}

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

let options = ImageEmbedderOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .liveStream
options.quantize = true
options.l2Normalize = true

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

let imageEmbedder = try ImageEmbedder(options: options)
    

Objective-C

Immagine

@import MediaPipeTasksVision;

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

MPPImageEmbedderOptions *options = [[MPPImageEmbedderOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeImage;
options.quantize = YES;
options.l2Normalize = YES;

MPPImageEmbedder *imageEmbedder =
  [[MPPImageEmbedder alloc] initWithOptions:options error:nil];
    

Video

@import MediaPipeTasksVision;

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

MPPImageEmbedderOptions *options = [[MPPImageEmbedderOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeVideo;
options.quantize = YES;
options.l2Normalize = YES;

MPPImageEmbedder *imageEmbedder =
  [[MPPImageEmbedder alloc] initWithOptions:options error:nil];
    

Live streaming

@import MediaPipeTasksVision;

// Class that conforms to the `MPPImageEmbedderLiveStreamDelegate` protocol
// and implements the method that the image embedder calls once it finishes
// embedding each input frame.
@interface APPImageEmbedderResultProcessor : NSObject 

@end

@implementation APPImageEmbedderResultProcessor

-   (void)imageEmbedder:(MPPImageEmbedder *)imageEmbedder
    didFinishEmbeddingWithResult:(MPPImageEmbedderResult *)imageEmbedderResult
         timestampInMilliseconds:(NSInteger)timestampInMilliseconds
                           error:(NSError *)error {

    // Process the image embedder result or errors here.

}

@end

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

MPPImageEmbedderOptions *options = [[MPPImageEmbedderOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeLiveStream;
options.quantize = YES;
options.l2Normalize = YES;

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

MPPImageEmbedder *imageEmbedder =
  [[MPPImageEmbedder alloc] initWithOptions:options error:nil];
    

Opzioni di configurazione

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

Nome opzione Descrizione Intervallo di valori Valore predefinito
runningMode Imposta la modalità di esecuzione dell'attività. Image Embedder ha tre modalità:

IMMAGINE: 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 dei dati di input, ad esempio da una videocamera. In questa modalità, imageEmbedderLiveStreamDelegate deve essere impostato su un'istanza di una classe che implementa ImageEmbedderLiveStreamDelegate per ricevere i risultati dell'incorporamento dei frame immagine in modo asincrono.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} {RunningMode.image}
l2Normalize Indica se normalizzare il vettore di caratteristiche restituito con la norma L2. Utilizza questa opzione solo se il modello non contiene già un'operazione L2_NORMALIZATION TFLite nativa. Nella maggior parte dei casi, è già così e la normalizzazione L2 viene quindi ottenuta tramite l'inferenza TFLite senza bisogno di questa opzione. Bool falso
quantize Indica se l'incorporamento restituito deve essere quantizzato in byte tramite la quantizzazione scalare. Si presume implicitamente che gli incorporamenti siano di norma unitaria e quindi qualsiasi dimensione ha un valore garantito compreso tra -1,0 e 1,0. Utilizza l'opzione l2Normalize se non è così. Bool falso

Quando la modalità di esecuzione è impostata su live streaming, lo strumento di incorporamento delle immagini richiede l'opzione di configurazione aggiuntiva imageEmbedderLiveStreamDelegate, che consente allo strumento di fornire i risultati di incorporamento delle immagini in modo asincrono. Il delegato deve implementare il metodo imageEmbedder(_:didFinishEmbedding:timestampInMilliseconds:error:), chiamato dall'Inserzionista di immagini dopo l'elaborazione dei risultati dell'inserimento di ogni frame dell'immagine di input.

Nome opzione Descrizione Intervallo di valori Valore predefinito
imageEmbedderLiveStreamDelegate Consente a Image Embedder di ricevere i risultati dell'inserimento di immagini in modo asincrono in modalità live streaming. La classe di cui l'istanza è impostata su questa proprietà deve implementare il metodo imageEmbedder(_:didFinishEmbedding:timestampInMilliseconds:error:). Non applicabile Non impostato

Preparazione dei dati

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

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

UIImage

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

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

  • Video: utilizza AVAssetImageGenerator per estrarre i frame video nel formato CGImage, quindi 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 un MPImage con uno dei valori supportati di UIImage.Orientation. Incorporatore di immagini non supporta orientamenti speculari come .upMirrored, .downMirrored, .leftMirrored e .rightMirrored.

Per ulteriori informazioni su UIImage, consulta la documentazione per sviluppatori Apple su 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 all'incorporamento di immagini in modalità di esecuzione delle immagini.

  • Video: i frame dei video possono essere convertiti in formato CVPixelBuffer per l'elaborazione e poi inviati a Image Embedder 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 all'incorporamento 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 ulteriori 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 frame in tempo reale delle videocamere iOS vengono caricati in modo asincrono nel formato CMSampleBuffer da AVCaptureVideoDataOutput di iOS.

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 su CMSampleBuffer.

Esegui l'attività

Per eseguire Image Embedder, utilizza il metodo embed() specifico per la modalità di esecuzione assegnata:

  • Immagine fissa: embed(image:)
  • Video: embed(videoFrame:timestampInMilliseconds:)
  • Live streaming: embedAsync(image:timestampInMilliseconds:)

I seguenti esempi di codice mostrano esempi di base su come eseguire Image Embedder in queste diverse modalità di esecuzione:

Swift

Immagine

let result = try imageEmbedder.embed(image: image)
    

Video

let result = try imageEmbedder.embed(
  videoFrame: image,
  timestampInMilliseconds: timestamp)
    

Live streaming

try imageEmbedder.embedAsync(
  image: image,
  timestampInMilliseconds: timestamp)
    

Objective-C

Immagine

MPPImageEmbedderResult *result =
  [imageEmbedder embedImage:image error:nil];
    

Video

MPPImageEmbedderResult *result =
  [imageEmbedder embedVideoFrame:image
           timestampInMilliseconds:timestamp
                             error:nil];
    

Live streaming

BOOL success =
  [imageEmbedder embedAsyncImage:image
           timestampInMilliseconds:timestamp
                             error:nil];
    

L'esempio di codice di Image Embedder mostra le implementazioni di ciascuna di queste modalità in modo più dettagliato embed(image:), embed(videoFrame:timestampInMilliseconds:), e embedAsync(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 segue:

  • Quando esegui l'operazione in modalità video o live streaming, devi fornire anche il timestamp del frame di input all'attività di incorporamento delle immagini.

  • Quando viene eseguita in modalità immagine o video, l'attività di incorporamento delle immagini blocca il thread corrente fino al termine dell'elaborazione dell'immagine o dell'inquadratura di input. Per evitare di bloccare il thread corrente, esegui l'elaborazione in un thread in background utilizzando i framework iOS Dispatch o NSOperation. Se l'app è stata creata utilizzando Swift, puoi anche utilizzare Swift Concurrency per l'esecuzione di thread in background.

  • Quando viene eseguito in modalità live streaming, il compito di incorporamento delle immagini ritorna immediatamente e non blocca il thread corrente. Dopo aver incorporato ogni frame di input, invoca il metodo imageEmbedder(_:didFinishEmbedding:timestampInMilliseconds:error:) con i risultati. L'elemento di incorporamento delle immagini invoca questo metodo in modo asincrono in una coda di invio seriale dedicata. Per visualizzare i risultati nell'interfaccia utente, inviali alla coda principale dopo l'elaborazione dei risultati. Se la funzione embedAsync viene richiamata quando l'attività Incorporatore di immagini è impegnata nell'elaborazione di un altro frame, l'incorporamento di immagini ignora il nuovo frame di input.

Gestire e visualizzare i risultati

Dopo l'esecuzione dell'inferenza, l'Inserzionista di immagini restituisce un oggetto ImageEmbedderResult che contiene un elenco di embedding (a virgola mobile o quantizzati scalari) per l'immagine di input.

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

ImageEmbedderResult:
  Embedding #0 (sole embedding head):
    float_embedding: {0.0, 0.0, ..., 0.0, 1.0, 0.0, 0.0, 2.0}
    head_index: 0

Questo risultato è stato ottenuto incorporando la seguente immagine:

Puoi confrontare la somiglianza di due embedding utilizzando la funzione ImageEmbedder.cosineSimilarity.

Swift

let similarity = try ImageEmbedder.cosineSimilarity(
  embedding1: result.embeddingResult.embeddings[0],
  embedding2: otherResult.embeddingResult.embeddings[0])
    

Objective-C

NSNumber *similarity = [MPPImageEmbedder
      cosineSimilarityBetweenEmbedding1:result.embeddingResult.embeddings[0]
                          andEmbedding2:otherResult.embeddingResult.embeddings[0]
                                  error:nil];