Guida alla segmentazione delle immagini per Android

L'attività Segmenter di immagini MediaPipe consente di suddividere le immagini in regioni in base alle categorie predefinite per applicare effetti visivi come la sfocatura dello sfondo. Queste istruzioni mostrano come utilizzare il segmento per le immagini con le app per Android. L'esempio di codice descritto in queste istruzioni è disponibile su GitHub. Per ulteriori informazioni sulle funzionalità, sui modelli e sulle opzioni di configurazione di questa attività, consulta la Panoramica.

Esempio di codice

L'esempio di codice delle attività MediaPipe contiene due semplici implementazioni di un'app di segmentazione delle immagini per Android:

Negli esempi viene utilizzata la fotocamera di un dispositivo Android fisico per eseguire la segmentazione delle immagini su un feed della videocamera in diretta oppure puoi scegliere immagini e video dalla galleria del dispositivo. Puoi utilizzare le app come punto di partenza per la tua app per Android o farvi riferimento quando modifichi un'app esistente. Il codice di esempio del segmento di immagini è ospitato su GitHub.

Le seguenti sezioni fanno riferimento all'app Segmentazione delle immagini con maschera di categoria.

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 l'istanza Git in modo da utilizzare un pagamento sparse, in modo da avere solo i file per l'app di esempio del Segmenter immagini:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_segmentation/android
    

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

Componenti chiave

I seguenti file contengono il codice cruciale per questa applicazione di esempio di segmentazione delle immagini:

  • ImageSegmenterHelper.kt: inizializza l'attività Segmenter immagini e gestisce il modello e la selezione dei delegati.
  • CameraFragment.kt: fornisce l'interfaccia utente e il codice di controllo per una videocamera.
  • GalleryFragment.kt: fornisce l'interfaccia utente e il codice di controllo per la selezione di file immagine e video.
  • OverlayView.kt: gestire e formattare i risultati della segmentazione.

Configurazione

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

Dipendenze

Il segmento di immagini 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à Segmenter di immagini MediaPipe richiede un modello addestrato compatibile con questa attività. Per ulteriori informazioni sui modelli addestrati disponibili per il Segmenter immagini, consulta la sezione Modelli della panoramica dell'attività.

Seleziona e scarica il modello, quindi archivialo all'interno della directory del progetto:

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

Usa il metodo BaseOptions.Builder.setModelAssetPath() per specificare il percorso utilizzato dal modello. Questo metodo è indicato nell'esempio di codice nella sezione successiva.

Nell'esempio di codice del segmentatore di immagini, il modello è definito nella classe ImageSegmenterHelper.kt nella funzione setupImageSegmenter().

Creare l'attività

Puoi utilizzare la funzione createFromOptions per creare l'attività. La funzione createFromOptions accetta opzioni di configurazione, inclusi i tipi di output della maschera. Per ulteriori informazioni sulla configurazione delle attività, consulta Opzioni di configurazione.

L'attività Segmenter immagini supporta i seguenti tipi di dati di input: immagini fisse, file video e stream video in diretta. Quando crei l'attività, devi specificare la modalità di esecuzione corrispondente al tipo di dati di input. Scegli la scheda relativa al tipo di dati di input per vedere come creare l'attività.

Immagine

ImageSegmenterOptions options =
  ImageSegmenterOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.IMAGE)
    .setOutputCategoryMask(true)
    .setOutputConfidenceMasks(false)
    .build();
imagesegmenter = ImageSegmenter.createFromOptions(context, options);
    

Video

ImageSegmenterOptions options =
  ImageSegmenterOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.VIDEO)
    .setOutputCategoryMask(true)
    .setOutputConfidenceMasks(false)
    .build();
imagesegmenter = ImageSegmenter.createFromOptions(context, options);
    

Live streaming

ImageSegmenterOptions options =
  ImageSegmenterOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.LIVE_STREAM)
    .setOutputCategoryMask(true)
    .setOutputConfidenceMasks(false)
    .setResultListener((result, inputImage) -> {
         // Process the segmentation result here.
    })
    .setErrorListener((result, inputImage) -> {
         // Process the segmentation errors here.
    })
    .build()
imagesegmenter = ImageSegmenter.createFromOptions(context, options)
    

L'implementazione di codice di esempio del Segmenter immagini consente all'utente di passare da una modalità di elaborazione all'altra. Questo approccio rende più complicato il codice per la creazione delle attività e potrebbe non essere appropriato per il tuo caso d'uso. Puoi vedere questo codice nella classe ImageSegmenterHelper accanto alla funzione setupImageSegmenter().

Opzioni di configurazione

Questa attività prevede 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 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.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
outputCategoryMask Se impostato su True, l'output include una maschera di segmentazione come immagine uint8, in cui ogni valore di pixel indica il valore della categoria vincente. {True, False} False
outputConfidenceMasks Se impostato su True, l'output include una maschera di segmentazione come immagine con valore in virgola mobile, in cui ogni valore in virgola mobile rappresenta la mappa del punteggio di confidenza della categoria. {True, False} True
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 Metadata Writer di TensorFlow Lite Codice impostazioni internazionali it
resultListener Imposta il listener dei risultati per ricevere i risultati di segmentazione in modo asincrono quando il segmenter di immagini è in modalità live streaming. Può essere utilizzato solo quando la modalità di esecuzione è impostata su LIVE_STREAM N/A N/A
errorListener Imposta un listener di errori facoltativo. N/A Non impostata

Preparazione dei dati

Il segmento di immagini funziona con immagini, file video e video in live streaming. L'attività gestisce la pre-elaborazione dell'input dei dati, tra cui il ridimensionamento, la rotazione e la normalizzazione dei valori.

Devi convertire l'immagine o il frame di input in un oggetto com.google.mediapipe.framework.image.MPImage prima di passarli al segmenter 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 del Segmenter immagini, la preparazione dei dati viene gestita nella classe ImageSegmenterHelper dalla funzione segmentLiveStreamFrame().

Esegui l'attività

Chiami una funzione segment diversa in base alla modalità di esecuzione in uso. La funzione Segmenter immagine restituisce le regioni di segmento identificate all'interno dell'immagine o del frame di input.

Immagine

ImageSegmenterResult segmenterResult = imagesegmenter.segment(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.
ImageSegmenterResult segmenterResult =
    imagesegmenter.segmentForVideo(image, frameTimestampMs);
    

Live streaming

// Run inference on the frame. The segmentations results will be available via
// the `resultListener` provided in the `ImageSegmenterOptions` when the image
// segmenter was created.
imagesegmenter.segmentAsync(image, frameTimestampMs);
    

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à Segmenter immagini.
  • Quando viene eseguita in modalità immagine o video, l'attività Segmenter di immagini blocca il thread corrente finché non completa l'elaborazione dell'immagine o del frame di input. Per evitare di bloccare l'interfaccia utente, esegui l'elaborazione in un thread in background.
  • Quando è in esecuzione in modalità live streaming, l'attività Segmenter di immagini non blocca il thread corrente, ma restituisce immediatamente il risultato. Richiama il proprio listener dei risultati con il risultato del rilevamento ogni volta che ha terminato l'elaborazione di un frame di input. Se la funzione segmentAsync viene richiamata quando l'attività Segmenter immagini è impegnata a elaborare un altro frame, l'attività ignora il nuovo frame di input.

Nel codice di esempio del Segmenter immagini, le funzioni segment sono definite nel file ImageSegmenterHelper.kt.

Gestire e visualizzare i risultati

Dopo aver eseguito l'inferenza, l'attività Segmenter di immagini restituisce un oggetto ImageSegmenterResult che contiene i risultati dell'attività di segmentazione. Il contenuto dell'output dipende dal valore outputType impostato al momento della configurazione dell'attività.

Le seguenti sezioni mostrano esempi di dati di output di questa attività:

Confidenza della categoria

Le immagini seguenti mostrano una visualizzazione dell'output dell'attività per una maschera di confidenza della categoria. L'output della maschera di confidenza contiene valori in virgola mobile compresi tra [0, 1].

Output della maschera di confidenza della categoria e dell'immagine originale. Immagine di origine dal set di dati di Pascal VOC 2012.

Valore categoria

Le immagini seguenti mostrano una visualizzazione dell'output dell'attività per una maschera dei valori di categoria. L'intervallo di maschere di categoria è [0, 255] e ogni valore di pixel rappresenta l'indice di categoria vincente dell'output del modello. L'indice delle categorie vincenti ha il punteggio più alto tra le categorie che il modello può riconoscere.

Output della maschera di categoria e immagine originale. Immagine di origine dal set di dati di Pascal VOC 2012.