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. Queste istruzioni mostrano come utilizzare lo strumento di incorporamento delle immagini con le app per Android.
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 è una semplice implementazione di un'app di incorporamento di immagini per Android. L'esempio utilizza la fotocamera di un dispositivo Android fisico per incorporare continuamente le immagini e può anche eseguire l'incorporatore sui file immagine archiviati sul dispositivo.
Puoi utilizzare l'app come punto di partenza per la tua app per Android 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:
- Clona il repository git utilizzando il seguente comando:
git clone https://github.com/google-ai-edge/mediapipe-samples
- Se vuoi, configura l'istanza Git in modo da utilizzare il controllo sparse, 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/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 questa applicazione di esempio di incorporamento di immagini:
- ImageEmbedderHelper.kt: inizializza l'embedder di immagini e gestisce la selezione del modello e del delegato.
- 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 i progetti di codice per utilizzare 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 Android.
Dipendenze
Image Embedder utilizza la libreria com.google.mediapipe:tasks-vision
. Aggiungi questa dipendenza al file build.gradle
del tuo 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à MediaPipe Image Embedder richiede un modello addestrato compatibile con questa attività. Per ulteriori informazioni sui modelli addestrati disponibili per Image Embedder, consulta la sezione Modelli della panoramica dell'attività.
Seleziona e scarica il modello, quindi memorizzalo nella directory del progetto:
<dev-project-root>/src/main/assets
Specifica il percorso del modello all'interno del parametro ModelAssetPath
. Nel codice di esempio, il modello è definito nella funzione setupImageEmbedder()
nel file ImageEmbedderHelper.kt:
Utilizza il metodo BaseOptions.Builder.setModelAssetPath()
per specificare il percorso utilizzato dal modello. A questo metodo viene fatto riferimento nell'esempio di codice nella sezione successiva.
Crea l'attività
Puoi utilizzare la funzione createFromOptions
per creare l'attività. La funzione createFromOptions
accetta opzioni di configurazione per impostare le opzioni di incorporamento. Per ulteriori informazioni sulle opzioni di configurazione, consulta la Panoramica della configurazione.
L'attività di incorporamento di immagini supporta tre tipi di dati di input: immagini, file video e streaming video dal vivo. Devi specificare la modalità di esecuzione corrispondente al tipo di dati di input quando crei l'attività. Scegli la scheda corrispondente al tipo di dati di input per scoprire 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 una modalità di elaborazione all'altra. L'approccio rende il codice di creazione delle attività più complicato e potrebbe non essere appropriato per il tuo caso d'uso. Puoi vedere questo codice nella funzione setupImageEmbedder()
nel file ImageEmbedderHelper.kt.
Opzioni di configurazione
Questa attività offre le seguenti opzioni di configurazione per le app per Android:
Nome opzione | Descrizione | Intervallo di valori | Valore predefinito |
---|---|---|---|
runningMode |
Imposta la modalità di esecuzione dell'attività. Esistono tre
modalità: IMMAGINE: la modalità per l'inserimento 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 ascoltatore per ricevere i 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'operazione L2_NORMALIZATION TFLite nativa. Nella maggior parte dei casi, è già così e la normalizzazione L2 viene quindi raggiunta tramite l'inferenza TFLite senza bisogno di questa opzione. | Boolean |
False |
quantize |
Indica se l'embedding restituito deve essere quantizzato in byte tramite la quantizzazione scalare. Si presume implicitamente che gli incorporamenti siano di norma unitaria e quindi qualsiasi dimensione abbia un valore garantito compreso tra -1,0 e 1,0. Utilizza l'opzione l2_normalize se non è così. | Boolean |
False |
resultListener |
Imposta l'ascoltatore dei risultati in modo da ricevere i risultati dell'inserimento
in modo asincrono quando lo strumento di inserimento di immagini è in modalità
live streaming. Può essere utilizzato solo quando la modalità di esecuzione è impostata su LIVE_STREAM |
N/D | Non impostato |
errorListener |
Imposta un listener di errore facoltativo. | N/D | Non impostato |
Preparazione dei dati
L'editor di incorporamento di immagini funziona con immagini, file video e video in live streaming. L'attività gestisce la preelaborazione dei dati di input, tra cui ridimensionamento, rotazione e normalizzazione dei valori.
Devi convertire l'immagine o l'inquadratura di input in un oggetto com.google.mediapipe.framework.image.MPImage
prima di trasmetterlo all'attività di incorporamento delle 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 nel file ImageEmbedderHelper.kt.
Esegui l'attività
Puoi chiamare la funzione embed
corrispondente alla modalità di esecuzione per attivare le inferenze. L'API Image Embedder restituisce i vettori di incorporamento per l'immagine o il frame di input.
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 esegui l'attività in modalità video o live streaming, devi anche fornire 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 del frame di input. Per evitare di bloccare il thread corrente, esegui l'elaborazione in un thread in background.
- Quando viene eseguito in modalità live streaming, il task di incorporamento delle immagini non blocca il thread corrente, ma restituisce immediatamente. Evocherà il suo ascoltatore dei risultati con il risultato del rilevamento ogni volta che ha terminato l'elaborazione di un frame di input. Se la funzione
embedAsync
viene chiamata quando l'attività Inserimento di immagini è impegnata a elaborare un altro frame, l'attività ignora il nuovo frame di input.
Nel codice di esempio, la funzione embed
è definita nel
file ImageEmbedderHelper.kt.
Gestire e visualizzare i risultati
Dopo l'esecuzione dell'inferenza, l'attività di inserimento 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 inserendo la seguente immagine:
Puoi confrontare la somiglianza di due embedding utilizzando la funzione
ImageEmbedder.cosineSimilarity
. Vedi il codice seguente per un
esempio.
// Compute cosine similarity.
double similarity = ImageEmbedder.cosineSimilarity(
result.embeddingResult().embeddings().get(0),
otherResult.embeddingResult().embeddings().get(0));