Guida al rilevamento di oggetti per Android

L'attività Rilevamento di oggetti consente di rilevare la presenza e la posizione di e classi di oggetti. Ad esempio, un rilevatore di oggetti può individuare i cani all'interno dell'immagine. Queste istruzioni mostrano come utilizzare l'attività Rilevamento di oggetti Android. L'esempio di codice descritto in queste istruzioni è disponibile su GitHub. Puoi vedere questa attività in azione visualizzando questa Demo web. Per ulteriori informazioni su funzionalità, modelli e opzioni di configurazione di questa attività, consulta la Panoramica.

Esempio di codice

Il codice di esempio delle attività di MediaPipe è una semplice implementazione di un rilevatore di oggetti per Android. L'esempio utilizza la fotocamera di un dispositivo Android fisico per rilevare oggetti in modo continuo e utilizzare anche immagini e video galleria di dispositivi per rilevare gli oggetti in modo statico.

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 del rilevatore di oggetti è 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 l'istanza Git in modo da utilizzare il pagamento sparso, in modo da avere solo i file per l'app di esempio Rilevamento di oggetti:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/object_detection/android
    

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

Componenti chiave

I seguenti file contengono il codice fondamentale per il rilevatore di oggetti di applicazione di esempio:

Configurazione

Questa sezione descrive i passaggi chiave per configurare l'ambiente di sviluppo e di codice per usare il rilevatore di oggetti. Per informazioni generali su configurare l'ambiente di sviluppo per l'utilizzo delle attività di MediaPipe, tra cui: i requisiti di versione della piattaforma, consulta Guida alla configurazione per Android.

Dipendenze

Il rilevatore di oggetti utilizza la libreria com.google.mediapipe:tasks-vision. Aggiungi questo al file build.gradle del tuo Progetto di sviluppo app per Android. Importa le dipendenze richieste con il seguente codice:

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

Modello

L'attività di rilevamento di oggetti MediaPipe richiede un modello addestrato che sia compatibile con dell'attività. Per ulteriori informazioni sui modelli addestrati disponibili per il rilevatore di oggetti, 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

Usa il metodo BaseOptions.Builder.setModelAssetPath() per specificare il percorso usato dal modello. Per un esempio di codice, consulta la sezione successiva.

Crea l'attività

Puoi utilizzare la funzione createFromOptions per creare l'attività. La La funzione createFromOptions accetta le opzioni di configurazione, inclusa l'esecuzione modalità, nomi visualizzati, impostazioni internazionali, numero massimo di risultati, soglia di confidenza, nella lista consentita e nella lista bloccata delle categorie. Se non viene specificata un'opzione di configurazione, verrà usato il valore predefinito. Per ulteriori informazioni sulle opzioni di configurazione, consulta la Panoramica della configurazione.

L'attività Rilevamento di oggetti supporta tre tipi di dati di input: immagini fisse e 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

ObjectDetectorOptions options =
  ObjectDetectorOptions.builder()
    .setBaseOptions(BaseOptions.builder().setModelAssetPath(‘model.tflite’).build())
    .setRunningMode(RunningMode.IMAGE)
    .setMaxResults(5)
    .build();
objectDetector = ObjectDetector.createFromOptions(context, options);
    

Video

ObjectDetectorOptions options =
  ObjectDetectorOptions.builder()
    .setBaseOptions(BaseOptions.builder().setModelAssetPath(‘model.tflite’).build())
    .setRunningMode(RunningMode.VIDEO)
    .setMaxResults(5)
    .build();
objectDetector = ObjectDetector.createFromOptions(context, options);
    

Live streaming

ObjectDetectorOptions options =
  ObjectDetectorOptions.builder()
    .setBaseOptions(BaseOptions.builder().setModelAssetPath(model.tflite).build())
    .setRunningMode(RunningMode.LIVE_STREAM)
    .setMaxResults(5)
    .setResultListener((result, inputImage) -> {
      // Process the detection result here.
    })
    .setErrorListener((result, inputImage) -> {
      // Process the classification errors here.
    })
   .build();
objectDetector = ObjectDetector.createFromOptions(context, options);
    

L'implementazione del codice di esempio del rilevatore di oggetti consente all'utente di passare di elaborazione. L'approccio rende il codice di creazione delle attività più complicato potrebbero non essere appropriati per il tuo caso d'uso. Puoi trovare questo codice nel ObjectDetectorHelper di classe setupObjectDetector().

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
displayNamesLocales Imposta la lingua delle etichette da utilizzare per i nomi visualizzati forniti nel metadati del modello dell'attività, se disponibili. Il valore predefinito è en per Inglese. Puoi aggiungere etichette localizzate ai metadati di un modello personalizzato Utilizzando l'API TensorFlow Metadata Writer Codice impostazioni internazionali it
maxResults Imposta il numero massimo facoltativo di risultati del rilevamento con il punteggio più alto su per tornare indietro. Qualsiasi numero positivo -1 (vengono restituiti tutti i risultati)
scoreThreshold Imposta la soglia del punteggio di previsione che sostituisce quella fornita in gli eventuali metadati del modello. I risultati al di sotto di questo valore vengono rifiutati. Qualsiasi numero in virgola mobile Non impostato
categoryAllowlist Consente di impostare l'elenco facoltativo di nomi di categorie consentiti. Se il campo non è vuoto, i risultati del rilevamento con nome categoria non incluso in questo set saranno esclusi. I nomi di categorie duplicati o sconosciuti vengono ignorati. Questa opzione si esclude a vicenda con categoryDenylist e utilizza entrambi generano un errore. Qualsiasi stringa Non impostato
categoryDenylist Consente di impostare un elenco facoltativo di nomi di categorie non consentiti. Se non è vuoto, i risultati del rilevamento con nome della categoria incluso in questo set verranno filtrati fuori. I nomi di categorie duplicati o sconosciuti vengono ignorati. Questa opzione è reciproca è esclusivo con categoryAllowlist e l'utilizzo di entrambi genera un errore. Qualsiasi stringa Non impostato
resultListener Imposta il listener dei risultati in modo che riceva i risultati del rilevamento in modo asincrono quando il rilevatore di oggetti è nel live streaming . Puoi utilizzare questa opzione solo quando imposti runningMode su LIVE_STREAM. Non applicabile Non impostato

Preparazione dei dati

Devi convertire l'immagine o il frame di input in un com.google.mediapipe.framework.image.MPImage prima di passarlo all'oggetto Rilevamento di oggetti.

I seguenti esempi spiegano e mostrano come preparare i dati per il trattamento per ognuno dei tipi di dati disponibili:

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 values. Use these values
// 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()
MPImage mpImage = new MediaImageBuilder(mediaImage).build();
    

Nel codice di esempio del rilevatore di oggetti, la preparazione dei dati viene gestita ObjectDetectorHelper nel corso detectImage(), detectVideoFile(), detectLivestreamFrame() funzioni.

Esegui l'attività

A seconda del tipo di dati con cui stai lavorando, utilizza ObjectDetector.detect...() specifico per il tipo di dati. Utilizza le funzionalità di detect() per le singole immagini, detectForVideo() per i frame nei file video e detectAsync() per gli stream video. Quando esegui rilevamenti su una nello stream video, assicurati di eseguire i rilevamenti su un thread separato per evitare bloccare il thread dell'interfaccia utente.

I seguenti esempi di codice mostrano semplici esempi di come eseguire Object Detector in queste diverse modalità dati:

Immagine

ObjectDetectorResult detectionResult = objectDetector.detect(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.
ObjectDetectorResult detectionResult =
    objectDetector.detectForVideo(image, frameTimestampMs);
    

Live streaming

// Run inference on the frame. The detection results will be available
// via the `resultListener` provided in the `ObjectDetectorOptions` when
// the object detector was created.
objectDetector.detectAsync(image, frameTimestampMs);
    

L'esempio di codice del rilevatore di oggetti mostra le implementazioni in modo più dettagliato detect(), detectVideoFile(), e detectAsync(). Il codice di esempio consente all'utente di passare da una modalità di elaborazione all'altra che potrebbero non essere necessarie per il tuo caso d'uso.

Tieni presente quanto segue:

  • Quando è attiva la modalità video o live streaming, devi anche fornisce il timestamp del frame di input all'attività di rilevamento di oggetti.
  • Quando viene eseguita in modalità immagine o video, l'attività Rilevamento di oggetti 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.
  • Durante l'esecuzione in modalità live streaming, l'attività Rilevamento di oggetti 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 di rilevamento viene chiamata quando l'attività Rilevamento di oggetti è impegnato a elaborare un altro frame, il nuovo frame di input verrà ignorato.

Gestire e visualizzare i risultati

Dopo l'esecuzione dell'inferenza, l'attività Rilevamento di oggetti restituisce un Oggetto ObjectDetectorResult che descrive gli oggetti che ha trovato l'immagine di input.

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

ObjectDetectorResult:
 Detection #0:
  Box: (x: 355, y: 133, w: 190, h: 206)
  Categories:
   index       : 17
   score       : 0.73828
   class name  : dog
 Detection #1:
  Box: (x: 103, y: 15, w: 138, h: 369)
  Categories:
   index       : 17
   score       : 0.73047
   class name  : dog

L'immagine seguente mostra una visualizzazione dell'output dell'attività:

Il codice di esempio del rilevatore di oggetti dimostra come visualizzare il rilevamento i risultati restituiti dall'attività, controlla OverlayView per ulteriori dettagli.