Guida alla segmentazione delle immagini per Android

L'attività MediaPipe Image Segmenter ti consente di suddividere le immagini in regioni in base a categorie predefinite per applicare effetti visivi come la sfocatura dello sfondo. Queste istruzioni mostrano come utilizzare lo strumento di segmentazione delle 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 MediaPipe Tasks contiene due semplici implementazioni di un'app di segmentazione delle immagini per Android:

Gli esempi utilizzano 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 di Image Segmenter è ospitato su GitHub.

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

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 il seguente comando:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. 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 Segmenter:
    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 istruzioni, consulta la Guida alla configurazione per Android.

Componenti chiave

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

  • ImageSegmenterHelper.kt: inizializza l'attività di segmentazione delle immagini e gestisce la selezione del modello e del delegato.
  • CameraFragment.kt: fornisce l'interfaccia utente e il codice di controllo di una videocamera.
  • GalleryFragment.kt: fornisce l'interfaccia utente e il codice di controllo per la selezione di file di immagini e video.
  • OverlayView.kt: gestisce e formatta i risultati della segmentazione.

Configurazione

Questa sezione descrive i passaggi chiave per configurare l'ambiente di sviluppo e i progetti di codice per utilizzare Image Segmenter. 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 Segmenter 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à di segmentazione delle immagini MediaPipe richiede un modello addestrato compatibile con questa attività. Per ulteriori informazioni sui modelli addestrati disponibili per Image Segmenter, 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

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.

Nel codice di esempio di Image Segmenter, il modello è definito nella classe ImageSegmenterHelper.kt nella funzione setupImageSegmenter().

Crea 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à Segmentazione immagini supporta i seguenti tipi di dati di input: immagini fisse, file video e live streaming video. Devi specificare la modalità di esecuzione corrispondente al tipo di dati di input durante la creazione dell'attività. Scegli la scheda corrispondente al tipo di dati di input per scoprire 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 del codice di esempio di Image Segmenter 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 visualizzare questo codice nella classe ImageSegmenterHelper tramite la funzione setupImageSegmenter().

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
outputCategoryMask Se impostato su True, l'output include una maschera di segmentazione come immagine uint8, in cui ogni valore del pixel indica il valore della categoria migliore. {True, False} False
outputConfidenceMasks Se impostato su True, l'output include una maschera di segmentazione come immagine con valore float, in cui ogni valore float 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 disponibile. Il valore predefinito è en per l'inglese. Puoi aggiungere etichette localizzate ai metadati di un modello personalizzato utilizzando l'API TensorFlow Lite Metadata Writer Codice delle impostazioni internazionali it
resultListener Imposta l'ascoltatore dei risultati in modo da ricevere i risultati della segmentazione in modo asincrono quando lo segmentatore di immagini è in modalità LIVE_STREAM. Può essere utilizzato solo quando la modalità di esecuzione è impostata su LIVE_STREAM N/D N/D
errorListener Imposta un listener di errore facoltativo. N/D Non impostato

Preparazione dei dati

Lo strumento di segmentazione delle 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 il frame di input in un oggetto com.google.mediapipe.framework.image.MPImage prima di trasmetterlo a Image Segmenter.

Immagine

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

// Load an image on the users device as a Bitmap object using BitmapFactory.

// Convert an Androids Bitmap object to a MediaPipes 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 videos metadata, load the METADATA_KEY_DURATION and
// METADATA_KEY_VIDEO_FRAME_COUNT value. Youll need them
// to calculate the timestamp of each frame later.

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

// Convert the Androids Bitmap object to a MediaPipes 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 CameraXs ImageAnalysis to continuously receive frames
// from the devices camera. Configure it to output frames in RGBA_8888
// format to match with what is required by the model.

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

Nel codice di esempio di Image Segmenter, la preparazione dei dati viene gestita nella ImageSegmenterHelper classe dalla funzione segmentLiveStreamFrame().

Esegui l'attività

Chiami una funzione segment diversa in base alla modalità di esecuzione in uso. La funzione Segmentatore di immagini restituisce le regioni dei segmenti identificati all'interno dell'immagine o dell'inquadratura 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 segue:

  • Quando esegui l'operazione in modalità video o in modalità live streaming, devi anche fornire il timestamp del frame di input all'attività Image Segmenter.
  • Quando viene eseguita in modalità immagine o video, l'attività Image Segmenter blocca il thread corrente fino al termine dell'elaborazione dell'immagine o del frame di input. Per evitare di bloccare l'interfaccia utente, esegui l'elaborazione in un THREAD in background.
  • Quando viene eseguita in modalità live streaming, l'attività Image Segmenter 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 segmentAsync viene chiamata quando l'attività Segmentazione immagini è impegnata a elaborare un altro frame, l'attività ignora il nuovo frame di input.

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

Gestire e visualizzare i risultati

Dopo l'esecuzione dell'inferenza, l'attività di segmentazione delle immagini restituisce un oggetto ImageSegmenterResult che contiene i risultati dell'attività di segmentazione. I contenuti dell'output dipendono dal valore outputType impostato durante la configurazione dell'attività.

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

Affidabilità della categoria

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

Due ragazze che cavalcano un cavallo e una ragazza che cammina accanto al cavallo La maschera dell&#39;immagine che delinea la forma delle ragazze e del cavallo della fotografia precedente. Viene acquisito il contorno della metà sinistra dell&#39;immagine, ma non quello della metà destra

Output della maschera di affidabilità dell'immagine e della categoria originale. Immagine di origine del set di dati Pascal VOC 2012.

Valore della categoria

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

Due ragazze che cavalcano un cavallo e una ragazza che cammina accanto al cavallo La maschera dell&#39;immagine che delinea la forma delle ragazze e del cavallo dell&#39;immagine precedente. La forma di tutte e tre le ragazze e del cavallo è mascherata con precisione

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