L'attività Rilevamento di oggetti consente di rilevare la presenza e la posizione di più classi di oggetti. Ad esempio, un rilevatore di oggetti può individuare dei cani all'interno di un'immagine. Queste istruzioni mostrano come utilizzare l'attività Rilevamento di oggetti su 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 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 rilevamento di oggetti per Android. L'esempio utilizza la fotocamera di un dispositivo Android fisico per rilevare in modo continuo gli oggetti e può utilizzare anche immagini e video della galleria del dispositivo per rilevare oggetti in modo statico.
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 del rilevatore di oggetti è ospitato su GitHub.
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:
- Clona il repository git utilizzando il seguente comando:
git clone https://github.com/google-ai-edge/mediapipe-samples
- Facoltativamente, configura la tua istanza Git in modo che utilizzi il pagamento sparse, in modo da avere solo i file per l'app di esempio di 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 le istruzioni, consulta la Guida alla configurazione per Android.
Componenti chiave
I seguenti file contengono il codice fondamentale per l'applicazione di esempio di rilevamento di oggetti:
- ObjectDetectorHelper.kt: inizializza il rilevatore degli oggetti, gestisce il modello e delega la selezione
- MainActivity.kt: implementa l'applicazione e assembla i componenti dell'interfaccia utente
- OverlayView.kt: gestire e visualizzare i risultati
Configurazione
Questa sezione descrive i passaggi chiave per configurare l'ambiente di sviluppo e i progetti di codice per l'utilizzo di Rilevamento di oggetti. 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 rilevatore di oggetti 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à Rilevamento di oggetti MediaPipe richiede un modello addestrato compatibile con questa attività. Per ulteriori informazioni sui modelli addestrati disponibili per il rilevatore di oggetti, consulta la panoramica dell'attività nella sezione Modelli.
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. Per un esempio di codice, consulta la sezione successiva.
Creare l'attività
Puoi utilizzare la funzione createFromOptions
per creare l'attività. La funzione createFromOptions
accetta opzioni di configurazione, tra cui modalità di esecuzione, impostazioni internazionali dei nomi visualizzati, numero massimo di risultati, soglia di confidenza, lista consentita delle categorie e lista bloccata. Se non viene specificata un'opzione di configurazione,
viene usato il valore predefinito. Per ulteriori informazioni sulle opzioni di configurazione, consulta Panoramica della configurazione.
L'attività Rilevamento di oggetti supporta tre tipi di dati di input: immagini fisse, file video e stream video in diretta. 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 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 di codice di esempio del rilevatore di oggetti 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 funzione
ObjectDetectorHelper
della classe setupObjectDetector()
.
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 |
displayNamesLocales |
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 |
maxResults |
Imposta il numero massimo facoltativo di risultati di rilevamento con il punteggio più alto da restituire. | Eventuali numeri positivi | -1 (vengono restituiti tutti i risultati) |
scoreThreshold |
Imposta la soglia del punteggio di previsione che sostituisce quella fornita nei metadati del modello (se presenti). I risultati inferiori a questo valore vengono rifiutati. | Qualsiasi elemento in virgola mobile | Non impostata |
categoryAllowlist |
Consente di impostare l'elenco facoltativo di nomi di categorie consentite. Se il campo non è vuoto,
i risultati del rilevamento il cui nome di categoria non è in questo set verranno
filtrati. I nomi di categoria duplicati o sconosciuti vengono ignorati.
Questa opzione si esclude a vicenda con categoryDenylist e l'utilizzo di entrambe genera un errore. |
Qualsiasi stringa | Non impostata |
categoryDenylist |
Consente di impostare l'elenco facoltativo di nomi di categorie non consentiti. Se il campo non è vuoto, i risultati del rilevamento il cui nome di categoria è presente in questo set verranno filtrati. I nomi di categoria duplicati o sconosciuti vengono ignorati. Questa opzione si esclude a vicenda con categoryAllowlist e l'uso di entrambe genera un errore. |
Qualsiasi stringa | Non impostata |
resultListener |
Imposta il listener dei risultati per ricevere i risultati del rilevamento in modo asincrono quando il rilevatore dell'oggetto è in modalità live streaming. Puoi utilizzare questa opzione solo se imposti runningMode su LIVE_STREAM. | Non applicabile | Non impostata |
Preparazione dei dati
Devi convertire l'immagine o il frame di input in un oggetto com.google.mediapipe.framework.image.MPImage
prima di passarlo al rilevatore di oggetti.
I seguenti esempi spiegano e mostrano come preparare i dati per il trattamento per ciascuno 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 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 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 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() MPImage mpImage = new MediaImageBuilder(mediaImage).build();
Nel codice di esempio di Object Detector, la preparazione dei dati viene gestita nella classe ObjectDetectorHelper
all'interno delle funzioni detectImage()
, detectVideoFile()
, detectLivestreamFrame()
.
Esegui l'attività
A seconda del tipo di dati con cui lavori, utilizza il
metodo ObjectDetector.detect...()
specifico per quel tipo di dati. Utilizza
detect()
per le singole immagini,
detectForVideo()
per i frame nei file video e
detectAsync()
per gli stream video. Quando esegui rilevamenti su uno stream video, assicurati di eseguirli in un thread separato per evitare di bloccare il thread dell'interfaccia utente.
I seguenti esempi di codice mostrano semplici esempi di come eseguire Rilevamento di oggetti 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 di ciascuna di queste
modalità in modo più dettagliato
detect()
,
detectVideoFile()
e detectAsync()
.
Il codice di esempio consente all'utente di passare da una modalità di elaborazione all'altra, il che potrebbe non essere necessario per il tuo caso d'uso.
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à di rilevamento di oggetti.
- Quando viene eseguita in modalità immagine o video, l'attività Rilevamento di oggetti bloccherà il thread corrente fino a quando non completa l'elaborazione dell'immagine o del frame di input. Per evitare di bloccare il thread corrente, esegui l'elaborazione in un thread in background.
- Quando è in esecuzione in modalità live streaming, l'attività Rilevamento oggetti non blocca il thread corrente, ma restituisce immediatamente. 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 di rilevamento viene chiamata quando l'attività di rilevamento di oggetti è impegnata a elaborare un altro frame, il nuovo frame di input viene ignorato.
Gestire e visualizzare i risultati
Dopo l'esecuzione dell'inferenza, l'attività di rilevamento di oggetti restituisce un oggetto ObjectDetectorResult
che descrive gli oggetti che ha trovato nell'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 mostra come visualizzare i risultati del rilevamento restituiti dall'attività. Per ulteriori dettagli, consulta la classe OverlayView
.