# MediaPipe: Computer vision ## 🎨 Cos’è MediaPipe MediaPipe è come una **cassetta degli attrezzi magica per Computer Vision**: apri la scatola e dentro trovi modelli già pronti che riconoscono mani, volti, pose, oggetti… senza dover addestrare nulla, senza GPU mostruose e senza versare lacrime su PyTorch. È stata sviluppata da Google ed è pensata per essere **veloce, leggera e multipiattaforma**: funziona sul browser in JavaScript, in Python, su Android, iOS e persino su dispositivi “piccoli” come microcontrollori avanzati. Insomma, un coltellino svizzero dell’IA visiva. --- ## 🔧 Su cosa si basa? MediaPipe combina: * **Modelli di Machine Learning pre-addestrati** (per riconoscere mani, pose, volto, ecc.) * **Pipeline di elaborazione molto ottimizzate** che tagliano, ridimensionano, filtrano e stabilizzano i frame in tempo reale. * **Trick intelligenti di tracking** così i modelli non devono “riconoscere tutto da zero” a ogni frame: seguono ciò che hai già trovato → più veloce, più fluido. Il risultato: puoi fare **AI in tempo reale** anche sul tuo portatile, senza dover vendere un rene per una GPU. --- ## 🎁 Cosa offre, in pratica? Tanti “superpoteri” pronti all’uso, tra cui: * 🖐 **Hands** — riconosce le mani e i 21 punti delle dita (perfetto per gesti e controlli) * 😊 **Face Detection / Face Mesh / Iris** — dal “vedo la faccia” al “ti traccio ogni millimetro della pupilla” * 💃 **Pose** — stima dello scheletro del corpo per fitness, danza, sport * 🧍‍♂️ **Holistic** — combina corpo + mani + volto in un unico modello * ✂️ **Selfie Segmentation** — ritaglia la persona dallo sfondo (tipo Zoom/Meet) * 📦 **Object Detection** — rileva oggetti generici * 📦 **Objectron** — tracking 3D di alcuni oggetti (tazze, scarpe, ecc.) * 🧠 **MediaPipe Tasks** — classificazione immagini, riconoscimento gesture, embedding, audio/text ML in modo super semplice --- ## 🎉 In breve? È il modo più facile e divertente per entrare nel mondo della Computer Vision *senza romperti il cervello*. --- ## 🔧 Proviamo noi ### 🖐 MediaPipe Hands – Rilevamento delle mani Questo esempio usa MediaPipe per trovare le mani in tempo reale nella webcam e tracciare i 21 punti chiave di ogni dito. È come dare al browser la capacità di “vedere” i movimenti delle tue mani senza addestrare nessun modello. Lo snippet disegna semplicemente questi punti sul canvas, così puoi osservare in diretta come MediaPipe capisce la posizione delle dita. Da qui puoi poi creare gesti, controlli o piccoli giochi. ```html <!DOCTYPE html> <html lang="it"> <head> <meta charset="UTF-8" /> <title>MediaPipe Hands - Demo minima</title> <style> body { margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; background: #111; } #output_canvas { width: 640px; height: 480px; background: #000; } </style> </head> <body> <!-- Il video può restare nascosto, usiamo solo il canvas --> <video id="webcam" class="input_video" autoplay playsinline style="display:none;"></video> <canvas id="output_canvas" class="output_canvas" width="640" height="480"></canvas> <!-- MediaPipe: utility per disegnare e hands solution (via CDN) --> <script src="https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/camera_utils.js" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/@mediapipe/drawing_utils/drawing_utils.js" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/@mediapipe/hands/hands.js" crossorigin="anonymous"></script> <script> const videoElement = document.getElementById('webcam'); const canvasElement = document.getElementById('output_canvas'); const canvasCtx = canvasElement.getContext('2d'); // Funzione chiamata ogni volta che MediaPipe ha un risultato function onResults(results) { // Pulisci il canvas canvasCtx.save(); canvasCtx.clearRect(0, 0, canvasElement.width, canvasElement.height); // Disegna il frame video canvasCtx.drawImage( results.image, 0, 0, canvasElement.width, canvasElement.height ); // Disegna i landmarks della mano (se presenti) if (results.multiHandLandmarks) { for (const landmarks of results.multiHandLandmarks) { // linee tra i punti drawConnectors(canvasCtx, landmarks, HAND_CONNECTIONS); // puntini drawLandmarks(canvasCtx, landmarks); } } canvasCtx.restore(); } // Inizializzazione di MediaPipe Hands const hands = new Hands({ locateFile: (file) => { console.log(file) return `https://cdn.jsdelivr.net/npm/@mediapipe/hands/${file}`; } }); hands.setOptions({ maxNumHands: 2, modelComplexity: 1, minDetectionConfidence: 0.5, minTrackingConfidence: 0.5, }); hands.onResults(onResults); // Semplice wrapper camera_utils per leggere i frame dalla webcam const camera = new Camera(videoElement, { onFrame: async () => { await hands.send({ image: videoElement }); }, width: 640, height: 480 }); // Avvia la webcam quando la pagina è pronta camera.start(); </script> </body> </html> ``` --- ### 💃 MediaPipe Pose – Rilevamento dello scheletro del corpo Qui MediaPipe individua la posizione del corpo e disegna un piccolo “scheletro” che segue i tuoi movimenti in tempo reale. Il modello riconosce punti come spalle, gomiti, ginocchia e caviglie, permettendo di capire postura e movimenti. Lo snippet mostra solo le ossa e le giunture sul canvas: semplice, chiaro e già molto scenografico. Perfetto per contare squat, creare pose-game o esperimenti interattivi. Potete trovare la lista di punti a questo link: [Mappa punti Mediapipe - Pose](https://storage.googleapis.com/mediapipe-assets/documentation/mediapipe_face_landmark_fullsize.png) ![Immagine distribuzione dei punti <++](https://storage.googleapis.com/mediapipe-assets/documentation/mediapipe_face_landmark_fullsize.png) ```html <!DOCTYPE html> <html lang="it"> <head> <meta charset="UTF-8" /> <title>MediaPipe Pose - Demo minima</title> <style> body { margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; background: #111; } #output_canvas { width: 640px; height: 480px; background: #000; } </style> </head> <body> <video id="webcam" autoplay playsinline style="display:none;"></video> <canvas id="output_canvas" width="640" height="480"></canvas> <!-- Librerie MediaPipe (CDN) --> <script src="https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/camera_utils.js" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/@mediapipe/drawing_utils/drawing_utils.js" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/@mediapipe/pose/pose.js" crossorigin="anonymous"></script> <script> const videoElement = document.getElementById('webcam'); const canvasElement = document.getElementById('output_canvas'); const canvasCtx = canvasElement.getContext('2d'); function onResults(results) { canvasCtx.save(); canvasCtx.clearRect(0, 0, canvasElement.width, canvasElement.height); // disegna il frame video canvasCtx.drawImage( results.image, 0, 0, canvasElement.width, canvasElement.height ); // disegna lo scheletro se presente if (results.poseLandmarks) { drawConnectors(canvasCtx, results.poseLandmarks, POSE_CONNECTIONS); drawLandmarks(canvasCtx, results.poseLandmarks); } canvasCtx.restore(); } const pose = new Pose({ locateFile: (file) => `https://cdn.jsdelivr.net/npm/@mediapipe/pose/${file}` }); pose.setOptions({ modelComplexity: 1, smoothLandmarks: true, enableSegmentation: false, minDetectionConfidence: 0.5, minTrackingConfidence: 0.5 }); pose.onResults(onResults); const camera = new Camera(videoElement, { onFrame: async () => { await pose.send({ image: videoElement }); }, width: 640, height: 480 }); camera.start(); </script> </body> </html> ``` --- ### ✂️ MediaPipe Selfie Segmentation – Ritaglio della persona Questo esempio separa la persona dallo sfondo utilizzando una maschera generata dal modello MediaPipe. Tutto ciò che è riconosciuto come “umano” viene mantenuto, mentre lo sfondo viene colorato o sostituito. Nello snippet vedrai il classico “effetto green screen”: semplice ma molto d’impatto. È la base per creare sfondi virtuali, filtri o effetti visivi in stile video-call moderno. ```html <!DOCTYPE html> <html lang="it"> <head> <meta charset="UTF-8" /> <title>MediaPipe Pose - Demo minima</title> <style> body { margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; background: #111; } #output_canvas { width: 640px; height: 480px; background: #000; } </style> </head> <body> <video id="webcam" autoplay playsinline style="display:none;"></video> <canvas id="output_canvas" width="640" height="480"></canvas> <!-- Librerie MediaPipe (CDN) --> <script src="https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/camera_utils.js" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/@mediapipe/drawing_utils/drawing_utils.js" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/@mediapipe/pose/pose.js" crossorigin="anonymous"></script> <script> const videoElement = document.getElementById('webcam'); const canvasElement = document.getElementById('output_canvas'); const canvasCtx = canvasElement.getContext('2d'); function onResults(results) { canvasCtx.save(); canvasCtx.clearRect(0, 0, canvasElement.width, canvasElement.height); // disegna il frame video canvasCtx.drawImage( results.image, 0, 0, canvasElement.width, canvasElement.height ); // disegna lo scheletro se presente if (results.poseLandmarks) { drawConnectors(canvasCtx, results.poseLandmarks, POSE_CONNECTIONS); drawLandmarks(canvasCtx, results.poseLandmarks); } canvasCtx.restore(); } const pose = new Pose({ locateFile: (file) => `https://cdn.jsdelivr.net/npm/@mediapipe/pose/${file}` }); pose.setOptions({ modelComplexity: 1, smoothLandmarks: true, enableSegmentation: false, minDetectionConfidence: 0.5, minTrackingConfidence: 0.5 }); pose.onResults(onResults); const camera = new Camera(videoElement, { onFrame: async () => { await pose.send({ image: videoElement }); }, width: 640, height: 480 }); camera.start(); </script> </body> </html> ``` --- ## Idee di evoluzione / utilizzo con questi strumenti ### A. Con **Hands** * “Telecomando a gesti”: * se il pollice è in su → mostra un testo, * se è in giù → un altro, * se la mano è aperta/chiusa → cambia slide, avvia un suono, ecc. * Gioco “segui il punto”: * disegna un cerchietto sul canvas, * se la punta dell’indice entra nel cerchio → punti. ### B. Con **Pose** * “Conta gli squat/flessioni”: * controllare l’angolo ginocchio/anca, * ogni volta che scendi sotto una certa soglia → +1. * “Semaforo postura”: * se la persona è abbastanza centrale e in piedi → cerchio verde, * se esce fuori → rosso. * Ballo/fitness: * verifica se i movimenti seguono un pattern (molto light: solo “braccia alzate / braccia abbassate”). ### C. Con **Selfie Segmentation** * Virtual background: * al posto del colore, metti un’immagine (`drawImage` di una foto), * oppure un gradiente, oppure una texture. * Effetto “sparisci nello sfondo”: * inverti la logica: mostra il video solo dove **non** c’è la persona. * Green-screen DIY: * esportare frame, fare qualche esperimento con montaggio video (anche solo concettuale).