Guida all'incorporamento delle immagini per Android

L'attività Incorporatore di immagini MediaPipe consente di convertire i dati immagine in una rappresentazione numerica per svolgere attività di elaborazione delle immagini correlate all'ML, come il confronto la somiglianza tra due immagini. Queste istruzioni mostrano come utilizzare Incorporatore di immagini con app per Android.

Per ulteriori informazioni su funzionalità, modelli e opzioni di configurazione di questa attività, consulta la Panoramica.

Esempio di codice

Il codice di esempio relativo alle attività di MediaPipe è una semplice implementazione di un incorporamento di immagini per Android. L'esempio utilizza la fotocamera di un dispositivo Android fisico per incorporare continuamente immagini ed eseguire l'incorporamento sui file immagine archiviati sul dispositivo.

Puoi utilizzare l'app come punto di partenza per la tua app per Android o fare riferimento all'app quando modifichi un'app esistente. Il codice di esempio di Image Embedder è ospitato su GitHub.

Scarica il codice

Le seguenti istruzioni mostrano come creare una copia locale dell'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 la tua istanza Git per l'utilizzo di un pagamento sparso, in modo da avere solo i file dell'app di esempio Image Embedder:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_embedder/android
    

Dopo aver creato una versione locale del codice di esempio, puoi importare il progetto in Android Studio ed eseguire l'app. Per istruzioni, consulta la Guida alla configurazione per Android.

Componenti chiave

I seguenti file contengono il codice fondamentale per questo esempio di incorporamento di immagini applicazione:

  • ImageEmbedderHelper.kt: inizializza l'incorporamento dell'immagine e gestisce il modello e il delegato selezione.
  • MainActivity.kt: implementa l'applicazione e assembla i componenti dell'interfaccia utente.

Configurazione

Questa sezione descrive i passaggi chiave per configurare l'ambiente di sviluppo e per l'uso di Image Embedder. Per informazioni generali sulla configurazione dell'ambiente di sviluppo per l'uso di attività MediaPipe, inclusa la versione della piattaforma consulta la Guida alla configurazione per Android.

Dipendenze

L'incorporamento di immagini usa la libreria com.google.mediapipe:tasks-vision. Aggiungi questo al file build.gradle del progetto di sviluppo di app per Android. Importa le dipendenze richieste con il seguente codice:

dependencies {
    ...
    implementation 'com.google.mediapipe:tasks-vision:latest.release'
}

Modello

L'attività Embedder di immagini MediaPipe richiede un modello addestrato che sia compatibile con dell'attività. Per ulteriori informazioni sui modelli addestrati disponibili per l'incorporamento di immagini, consulta la panoramica delle attività nella sezione Modelli.

Seleziona e scarica il modello, quindi archivialo nella directory del progetto:

<dev-project-root>/src/main/assets

Specifica il percorso del modello all'interno del parametro ModelAssetPath. Nella di codice di esempio, il modello è definito nella funzione setupImageEmbedder() in ImageEmbedderHelper.kt file:

Utilizza il metodo BaseOptions.Builder.setModelAssetPath() per specificare il percorso usato dal modello. Questo metodo è indicato nell'esempio di codice della .

Crea l'attività

Puoi utilizzare la funzione createFromOptions per creare l'attività. La La funzione createFromOptions accetta le opzioni di configurazione per impostare l'incorporamento le opzioni di CPU e memoria disponibili. Per ulteriori informazioni sulle opzioni di configurazione, vedi Configurazione Panoramica.

L'attività Incorporatore di immagini supporta tre tipi di dati di input: immagini fisse, file video e video stream in diretta. Devi specificare la modalità di esecuzione corrispondente il tipo di dati di input durante la creazione dell'attività. Scegli la scheda corrispondente a il tipo di dati di input per vedere come creare l'attività ed eseguire l'inferenza.

Immagine

ImageEmbedderOptions options =
  ImageEmbedderOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setQuantize(true)
    .setRunningMode(RunningMode.IMAGE)
    .build();
imageEmbedder = ImageEmbedder.createFromOptions(context, options);
    

Video

ImageEmbedderOptions options =
  ImageEmbedderOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setQuantize(true)
    .setRunningMode(RunningMode.VIDEO)
    .build();
imageEmbedder = ImageEmbedder.createFromOptions(context, options);
    

Live streaming

ImageEmbedderOptions options =
  ImageEmbedderOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setQuantize(true)
    .setRunningMode(RunningMode.LIVE_STREAM)
    .setResultListener((result, inputImage) -> {
         // Process the embedding result here.
    })
    .build();
imageEmbedder = ImageEmbedder.createFromOptions(context, options);
    

L'implementazione del codice di esempio consente all'utente di passare da un'elaborazione all'altra diverse. L'approccio rende il codice di creazione delle attività più complicato e potrebbe non essere appropriati per il tuo caso d'uso. Puoi trovare questo codice nel nella funzione setupImageEmbedder() ImageEmbedderHelper.kt .

Opzioni di configurazione

Questa attività include le seguenti opzioni di configurazione per le app per Android:

Nome opzione Descrizione Intervallo di valori Valore predefinito
runningMode Imposta la modalità di esecuzione per l'attività. Esistono tre tipi di 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 input dati, ad esempio quelli di una videocamera. In questa modalità, resultListener deve essere per impostare un listener in modo che riceva risultati in modo asincrono.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
l2_normalize Indica se normalizzare il vettore di caratteristiche restituito con la norma L2. Utilizza questa opzione solo se il modello non contiene già un L2_NORMALIZZAZIONE TFLite Op. Nella maggior parte dei casi, questo è già il caso. La normalizzazione L2 viene quindi ottenuta attraverso l'inferenza TFLite senza necessità per questa opzione. Boolean False
quantize Indica se l'incorporamento restituito deve essere quantizzato in byte tramite quantizzazione scalare. Gli incorporamenti sono implicitamente considerati come norma unitaria. pertanto è garantito che qualsiasi dimensione abbia un valore pari a [-1,0, 1,0]. Utilizza le funzionalità di in caso contrario l'opzione l2_normalize. Boolean False
resultListener Imposta il listener dei risultati in modo che riceva i risultati dell'incorporamento in modo asincrono quando l'incorporamento di immagini è nel live streaming . Può essere utilizzato solo quando la modalità di corsa è impostata su LIVE_STREAM N/D Non impostato
errorListener Imposta un listener di errori facoltativo. N/D Non impostato

Preparazione dei dati

Image Embedder funziona con immagini, file video e video in live streaming. L'attività gestisce la pre-elaborazione dell'input di dati, tra cui il ridimensionamento, la rotazione e il valore della normalizzazione.

Devi convertire l'immagine o il frame di input in un com.google.mediapipe.framework.image.MPImage prima di passarlo all'oggetto Attività Incorporatore di immagini.

Immagine

import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Load an image on the user’s device as a Bitmap object using BitmapFactory.

// Convert an Android’s Bitmap object to a MediaPipe’s Image object.
Image mpImage = new BitmapImageBuilder(bitmap).build();
    

Video

import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Load a video file on the user's device using MediaMetadataRetriever

// From the video’s metadata, load the METADATA_KEY_DURATION and
// METADATA_KEY_VIDEO_FRAME_COUNT value. You’ll need them
// to calculate the timestamp of each frame later.

// Loop through the video and load each frame as a Bitmap object.

// Convert the Android’s Bitmap object to a MediaPipe’s Image object.
Image mpImage = new BitmapImageBuilder(frame).build();
    

Live streaming

import com.google.mediapipe.framework.image.MediaImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Create a CameraX’s ImageAnalysis to continuously receive frames
// from the device’s camera. Configure it to output frames in RGBA_8888
// format to match with what is required by the model.

// For each Android’s ImageProxy object received from the ImageAnalysis,
// extract the encapsulated Android’s Image object and convert it to
// a MediaPipe’s Image object.
android.media.Image mediaImage = imageProxy.getImage()
Image mpImage = new MediaImageBuilder(mediaImage).build();
    

Nel codice di esempio, la preparazione dei dati viene gestita ImageEmbedderHelper.kt .

Esegui l'attività

Puoi chiamare la funzione embed corrispondente alla tua modalità di corsa per attivare le inferenze. L'API Image Embedder restituisce i vettori di incorporamento per l'input un'immagine o un frame.

Immagine

ImageEmbedderResult embedderResult = imageEmbedder.embed(image);
    

Video

// Calculate the timestamp in milliseconds of the current frame.
long frame_timestamp_ms = 1000 * video_duration * frame_index / frame_count;

// Run inference on the frame.
ImageEmbedderResult embedderResult =
    imageEmbedder.embedForVideo(image, frameTimestampMs);
    

Live streaming


// Run inference on the frame. The embedding results will be available
// via the `resultListener` provided in the `ImageEmbedderOptions` when
// the image embedder was created.
imageEmbedder.embedAsync(image, frameTimestampMs);
    

Tieni presente quanto segue:

  • Quando è attiva la modalità video o live streaming, devi anche fornisce il timestamp del frame di input all'attività Embedder di immagini.
  • Quando viene eseguita in modalità immagine o video, l'attività Incorporatore di immagini bloccare il thread corrente finché non termina di elaborare l'immagine di input o frame. Per evitare di bloccare il thread corrente, esegui l'elaborazione in un in background.
  • Quando viene eseguita in modalità live streaming, l'attività Incorporatore di immagini non blocca il thread corrente, ma restituisce immediatamente. Richiamerà il suo risultato con il risultato del rilevamento ogni volta che termina l'elaborazione di un frame di input. Se la funzione embedAsync viene chiamata quando l'incorporamento di immagini l'attività è impegnata a elaborare un altro frame, ignora il nuovo frame di input.

Nel codice di esempio, la funzione embed è definita nel ImageEmbedderHelper.kt .

Gestire e visualizzare i risultati

Durante l'esecuzione dell'inferenza, l'attività Incorporatore di immagini restituisce un ImageEmbedderResult contenente un elenco di incorporamenti (a rappresentazione in virgola mobile quantizzato scalare) 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 tra due incorporamenti utilizzando Funzione ImageEmbedder.cosineSimilarity. Consulta il seguente codice per esempio.

// Compute cosine similarity.
double similarity = ImageEmbedder.cosineSimilarity(
  result.embeddingResult().embeddings().get(0),
  otherResult.embeddingResult().embeddings().get(0));