1. Prima di iniziare
MediaPipe Solutions ti consente di applicare soluzioni di machine learning (ML) alle tue app. Fornisce un framework che consente di configurare pipeline di elaborazione predefinite che offrono agli utenti un output immediato, coinvolgente e utile. Puoi persino personalizzare queste soluzioni con Model Maker per aggiornare i modelli predefiniti.
Il rilevamento di oggetti è una delle diverse attività di visione ML offerte da MediaPipe Solutions. MediaPipe Tasks è disponibile per Android, Python e il web.
In questo codelab aggiungi il rilevamento di oggetti a un'app web per rilevare i cani nelle immagini e in un video in diretta della webcam.
Obiettivi didattici
- Come incorporare un'attività di rilevamento di oggetti in un'app web con MediaPipe Tasks.
Cosa creerai
- Un'app web che rileva la presenza di cani. Puoi anche personalizzare un modello per rilevare una classe di oggetti a tua scelta con MediaPipe Model Maker.
Che cosa ti serve
- Un account CodePen
- Un dispositivo con un browser web
- Conoscenza di base di JavaScript, CSS e HTML
2. Configurazione
Questo codelab esegue il codice in CodePen,un ambiente di sviluppo social che ti consente di scrivere codice nel browser e controllare i risultati durante la compilazione.
Per effettuare la configurazione:
- Nel tuo account CodePen, vai a questo CodePen. Utilizza questo codice come base di partenza per creare il tuo rilevatore di oggetti.
- Nella parte inferiore di CodePen nel menu di navigazione, fai clic su Fork per creare una copia del codice di partenza.
- Nella scheda JS, fai clic sulla freccia di espansione e poi seleziona Maximize JavaScript editor (Maximize JavaScript editor). Per questo codelab, puoi modificare il lavoro solo nella scheda JS, quindi non devi visualizzare le schede HTML o CSS.
Rivedi l'app iniziale
- Nel riquadro di anteprima, noterai due immagini di cani e un'opzione per avviare la webcam. Il modello utilizzato in questo tutorial è stato addestrato sui tre cani mostrati nelle due immagini.
- Nella scheda JS, noterai che ci sono diversi commenti nel codice. Ad esempio, nella riga 15 puoi trovare il seguente commento:
// Import the required package.
Questi commenti indicano dove devi inserire gli snippet di codice.
3. Importa il pacchetto MediaPipe tasks-vision e aggiungi le variabili richieste
- Nella scheda JS, importa il pacchetto MediaPipe
tasks-vision
:
// Import the required package.
import { ObjectDetector, FilesetResolver, Detection } from "https://cdn.skypack.dev/@mediapipe/tasks-vision@latest";
Questo codice utilizza la rete CDN (Content Delivery Network) Skypack per importare il pacchetto. Per ulteriori informazioni su come utilizzare Skypack con CodePen, consulta Skypack + CodePen.
Nei tuoi progetti, puoi utilizzare Node.js con npm o il gestore pacchetti o la CDN che preferisci. Per ulteriori informazioni sul pacchetto richiesto da installare, consulta Pacchetti JavaScript.
- Dichiara le variabili per il rilevatore di oggetti e la modalità di esecuzione:
// Create required variables.
let objectDetector = null;
let runningMode = "IMAGE";
La variabile runningMode
è una stringa impostata su un valore "IMAGE"
quando rilevi oggetti nelle immagini o su un valore "VIDEO"
quando rilevi oggetti nei video.
4. Inizializza il rilevatore di oggetti
- Per inizializzare il rilevatore di oggetti, aggiungi il seguente codice dopo il commento pertinente nella scheda JS:
// Initialize the object detector.
async function initializeObjectDetector() {
const visionFilesetResolver = await FilesetResolver.forVisionTasks(
"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm"
);
objectDetector = await ObjectDetector.createFromOptions(visionFilesetResolver, {
baseOptions: {
modelAssetPath: "https://storage.googleapis.com/mediapipe-assets/dogs.tflite"
},
scoreThreshold: 0.3,
runningMode: runningMode
});
}
initializeObjectDetector();
Il metodo FilesetResolver.forVisionTasks()
specifica la posizione del file binario WebAssembly (Wasm) per l'attività.
Il metodo ObjectDetector.createFromOptions()
esegue l'inizializzazione del rilevatore di oggetti. Devi fornire un percorso per il modello utilizzato per il rilevamento. In questo caso, il modello di rilevamento dei cani è ospitato su Cloud Storage.
La proprietà scoreThreshold
è impostata su un valore 0.3
. Ciò significa che il modello restituisce risultati per qualsiasi oggetto rilevato con un livello di confidenza pari o superiore al 30%. Puoi modificare questa soglia in base alle esigenze della tua app.
La proprietà runningMode
viene impostata all'inizializzazione dell'oggetto ObjectDetector
. Puoi modificare questa e altre opzioni in un secondo momento, se necessario.
5. Eseguire previsioni sulle immagini
- Per eseguire le previsioni sulle immagini, vai alla funzione
handleClick()
e aggiungi il seguente codice al corpo della funzione:
// Verify object detector is initialized and choose the correct running mode.
if (!objectDetector) {
alert("Object Detector still loading. Please try again");
return;
}
if (runningMode === "VIDEO") {
runningMode = "IMAGE";
await objectDetector.setOptions({ runningMode: runningMode });
}
Questo codice determina se il rilevatore di oggetti è stato inizializzato e assicura che la modalità di esecuzione sia impostata per le immagini.
Rilevamento di oggetti
- Per rilevare gli oggetti nelle immagini, aggiungi il seguente codice al corpo della funzione
handleClick()
:
// Run object detection.
const detections = objectDetector.detect(event.target);
Il seguente snippet di codice include un esempio dei dati di output di questa attività:
ObjectDetectionResult:
Detection #0:
Box: (x: 355, y: 133, w: 190, h: 206)
Categories:
index : 17
score : 0.73828
class name : aci
Detection #1:
Box: (x: 103, y: 15, w: 138, h: 369)
Categories:
index : 17
score : 0.73047
class name : tikka
Elabora e mostra le previsioni
- Alla fine del corpo della funzione
handleClick()
, chiama la funzionedisplayImageDetections()
:
// Call the displayImageDetections() function.
displayImageDetections(detections, event.target);
- Nel corpo della funzione
displayImageDetections()
, aggiungi il seguente codice per visualizzare i risultati del rilevamento degli oggetti:
// Display object detection results.
const ratio = resultElement.height / resultElement.naturalHeight;
for (const detection of result.detections) {
// Description text
const p = document.createElement("p");
p.setAttribute("class", "info");
p.innerText =
detection.categories[0].categoryName +
" - with " +
Math.round(parseFloat(detection.categories[0].score) * 100) +
"% confidence.";
// Positioned at the top-left of the bounding box.
// Height is that of the text.
// Width subtracts text padding in CSS so that it fits perfectly.
p.style =
"left: " +
detection.boundingBox.originX * ratio +
"px;" +
"top: " +
detection.boundingBox.originY * ratio +
"px; " +
"width: " +
(detection.boundingBox.width * ratio - 10) +
"px;";
const highlighter = document.createElement("div");
highlighter.setAttribute("class", "highlighter");
highlighter.style =
"left: " +
detection.boundingBox.originX * ratio +
"px;" +
"top: " +
detection.boundingBox.originY * ratio +
"px;" +
"width: " +
detection.boundingBox.width * ratio +
"px;" +
"height: " +
detection.boundingBox.height * ratio +
"px;";
resultElement.parentNode.appendChild(highlighter);
resultElement.parentNode.appendChild(p);
}
Questa funzione mostra i riquadri di delimitazione sugli oggetti rilevati nelle immagini. Rimuove eventuali evidenziazioni precedenti, quindi crea e mostra i tag <p>
per evidenziare ogni oggetto rilevato.
Testa l'app
Quando apporti modifiche al codice in CodePen, il riquadro di anteprima si aggiorna automaticamente al salvataggio. Se il salvataggio automatico è attivo, è probabile che l'app sia già stata aggiornata, ma è consigliabile aggiornarla di nuovo.
Per testare l'app:
- Nel riquadro di anteprima, fai clic su ogni immagine per visualizzare le previsioni. Un riquadro delimitante mostra il nome del cane con il livello di confidenza del modello.
- Se non è presente un riquadro delimitante, apri Chrome DevTools e controlla se nel riquadro Console sono presenti errori o rivedi i passaggi precedenti per assicurarti di non aver perso nulla.
6. Eseguire previsioni su un video della webcam in diretta
Rilevamento di oggetti
- Per rilevare gli oggetti in un video in diretta della webcam, vai alla funzione
predictWebcam()
e aggiungi il seguente codice al corpo della funzione:
// Run video object detection.
// If image mode is initialized, create a classifier with video runningMode.
if (runningMode === "IMAGE") {
runningMode = "VIDEO";
await objectDetector.setOptions({ runningMode: runningMode });
}
let nowInMs = performance.now();
// Detect objects with the detectForVideo() method.
const result = await objectDetector.detectForVideo(video, nowInMs);
displayVideoDetections(result.detections);
Il rilevamento di oggetti per i video utilizza gli stessi metodi indipendentemente dal fatto che l'inferenza venga eseguita sui dati in streaming o su un video completo. Il metodo detectForVideo()
è simile al metodo detect()
utilizzato per le foto, ma include un parametro aggiuntivo per il timestamp associato al frame corrente. La funzione esegue il rilevamento in tempo reale, quindi devi passare l'ora corrente come timestamp.
Elabora e mostra le previsioni
- Per elaborare e visualizzare i risultati del rilevamento, vai alla funzione
displayVideoDetections()
e aggiungi il seguente codice al corpo della funzione:
// Display video object detection results.
for (let child of children) {
liveView.removeChild(child);
}
children.splice(0);
// Iterate through predictions and draw them to the live view.
for (const detection of result.detections) {
const p = document.createElement("p");
p.innerText =
detection.categories[0].categoryName +
" - with " +
Math.round(parseFloat(detection.categories[0].score) * 100) +
"% confidence.";
p.style =
"left: " +
(video.offsetWidth -
detection.boundingBox.width -
detection.boundingBox.originX) +
"px;" +
"top: " +
detection.boundingBox.originY +
"px; " +
"width: " +
(detection.boundingBox.width - 10) +
"px;";
const highlighter = document.createElement("div");
highlighter.setAttribute("class", "highlighter");
highlighter.style =
"left: " +
(video.offsetWidth -
detection.boundingBox.width -
detection.boundingBox.originX) +
"px;" +
"top: " +
detection.boundingBox.originY +
"px;" +
"width: " +
(detection.boundingBox.width - 10) +
"px;" +
"height: " +
detection.boundingBox.height +
"px;";
liveView.appendChild(highlighter);
liveView.appendChild(p);
// Store drawn objects in memory so that they're queued to delete at next call.
children.push(highlighter);
children.push(p);
}
}
Questo codice rimuove eventuali evidenziazioni precedenti, quindi crea e mostra i tag <p>
per evidenziare ogni oggetto rilevato.
Testa l'app
Per testare il rilevamento di oggetti in tempo reale, è utile avere un'immagine di uno dei cani su cui è stato addestrato il modello.
Per testare l'app:
- Scarica una delle foto del cane sul tuo smartphone.
- Nel riquadro di anteprima, fai clic su Attiva webcam.
- Se il browser mostra una finestra di dialogo che ti chiede di concedere l'accesso alla webcam, concedi l'autorizzazione.
- Tieni la foto del cane sullo smartphone davanti alla webcam. Un riquadro delimitante mostra il nome del cane e il livello di confidenza del modello.
- Se non è presente un riquadro delimitante, apri Chrome DevTools e controlla se nel riquadro Console sono presenti errori o rivedi i passaggi precedenti per assicurarti di non aver perso nulla.
7. Complimenti
Complimenti! Hai creato un'app web che rileva gli oggetti nelle immagini. Per scoprire di più, consulta una versione completa dell'app su CodePen.