L’innovazione nell’ambito dell’intelligenza artificiale (AI) sta rapidamente cambiando il modo in cui concepiamo e realizziamo applicazioni interattive. Il FabLab Bergamo, grazie a contributi di moduli tecnologici avanzati, ha realizzato un progetto che integra un Raspberry Pi 5 con un modulo HAILO8L all’occasione dell’Arduino Day 2025. Ringraziamo l’azienda donatrice che ha reso possibile il progetto.
L’obiettivo di questo articolo è di descrivere come usare l’AI con Raspberry Pi, usando come esempio il gioco “1,2,3 Stella”, in versione “Squid Game”, un progetto disponibile su GitHub all’indirizzo: https://github.com/fablab-bergamo/squid-game-doll, dimostrato durante l’Arduino Day 2025.
Il gioco è accompagnato di una bambola animata per segnalare le fasi di gioco (green light, red light).
La popolarità della serie TV e gli adattamenti del gioco su Roblox rendono i principi del gioco facilmente riconoscibili ai ragazzi.
AI e reti neuronali
Le reti neurali rappresentano il cuore di molte applicazioni di intelligenza artificiale, in particolare per problemi difficilissimi come il riconoscimento delle immagini (“Machine Vision“). Queste reti sono in grado di analizzare e interpretare enormi quantità di dati visivi, identificando pattern con una precisione molto elevata, che era impensabile ottenere con algoritmi tradizionali.
I modelli di rete neurale si basano però su operazioni matematiche complesse, in particolare il calcolo matriciale e le convoluzioni, che richiedono grandi capacità di elaborazione. Queste elaborazioni sono fondamentali sia durante l’addestramento (training) che per l’utilizzo in tempo reale (inference) della rete neuronale.
Durante il training, infatti, il modello impara a riconoscere pattern e a classificare dati attraverso iterazioni che comportano il calcolo di gradienti e la modifica di milioni di parametri. Una volta completato l’addestramento, il modello viene impiegato per effettuare inferenze, cioè per eseguire previsioni in tempo reale basate sui dati in ingresso. Alcuni modelli sono forniti “pre-trainati”, ovvero adattabili a nuove esigenze ma con necessità di calcolo minori.
Questa doppia esigenza spiega perché, per le applicazioni AI, sia fondamentale disporre di hardware in grado di gestire calcoli matematici complessi in maniera efficiente.
Hardware disponibile in FabLab
Grazie alla generosità di aziende locali, il FabLab dispone di un moderno Raspberry Pi 5 accessoriato. Sul mercato esistono diversi HAT (moduli aggiuntivi) per fornire la potenza di calcolo necessaria all’AI: noi abbiamo scelto l’HAILO8L, disponibile su siti come come MeloPero.
L’utilizzo di dispositivi come il Raspberry Pi 5, abbinato a moduli specifici come il HAILO, consente di eseguire inferenze in tempo reale, garantendo al contempo un basso consumo energetico rispetto ad un PC e una buona portabilità, aspetti cruciali per applicazioni embedded e prototipi in FabLab.
Questo chip, nello specifico il modello HAILO 8L, è stato scelto per la sua elevata capacità di calcolo espressa in TFLOPS (Tera Floating Point Operations per Second), una misura fondamentale per valutare le performance di elaborazione dei modelli di deep learning.
In pratica, i 13 TFLOPS rappresentano il numero di operazioni in virgola mobile che il chip può eseguire al secondo, un parametro chiave quando si parla di inferenze AI in tempo reale.
HAILO 8L e il Model Zoo: Un Ecosistema per il Deep Learning
I “Model Zoo” sono archivi di modelli pre-addestrati e ottimizzati per funzionare in maniera efficiente su specifici dispositivi, in questo caso il chip HAILO 8L. All’interno di questo zoo è possibile trovare modelli per svariate applicazioni. Ecco il “model zoo” per il nostro chip a Marzo 2025:
Nome del Modello | Descrizione | Usi Comuni | Link a tabelle modelli |
---|---|---|---|
HAILO8L_classification | Classifica immagini in categorie predefinite | Analisi di immagini, riconoscimento oggetti | 🔗 GitHub |
HAILO8L_zero_shot_classification | Classifica immagini senza bisogno di addestramento specifico | Classificazione adattabile, analisi senza training | 🔗 GitHub |
HAILO8L_depth_estimation | Stima la profondità in immagini 2D | Visione artificiale, navigazione robotica | 🔗 GitHub |
HAILO8L_stereo_depth_estimation | Stima profondità utilizzando immagini stereo | Automobili autonome, realtà aumentata | 🔗 GitHub |
HAILO8L_face_attribute | Rileva attributi facciali (età, genere, emozioni) | Marketing, sicurezza, interazione utente | 🔗 GitHub |
HAILO8L_face_detection | Rileva volti in immagini | Sicurezza, monitoraggio, fotografia | 🔗 GitHub |
HAILO8L_face_recognition | Identifica volti noti | Controllo accessi, sorveglianza | 🔗 GitHub |
HAILO8L_facial_landmark_detection | Identifica punti chiave sul viso | Animazione, filtri AR, analisi delle espressioni | 🔗 GitHub |
HAILO8L_hand_landmark_detection | Identifica punti chiave della mano | Riconoscimento gesti, VR/AR, interazione uomo-macchina | 🔗 GitHub |
HAILO8L_image_denoising | Riduce il rumore nelle immagini | Fotografia, miglioramento immagini medicali | 🔗 GitHub |
HAILO8L_instance_segmentation | Segmenta e identifica oggetti distinti nell’immagine | Veicoli autonomi, analisi scene complesse | 🔗 GitHub |
HAILO8L_zero_shot_instance_segmentation | Segmentazione senza bisogno di addestramento | Applicazioni flessibili in settori diversi | 🔗 GitHub |
HAILO8L_low_light_enhancement | Migliora immagini in condizioni di scarsa luminosità | Sorveglianza notturna, fotografia | 🔗 GitHub |
HAILO8L_object_detection | Identifica e localizza oggetti | Videosorveglianza, robotica, guida autonoma | 🔗 GitHub |
HAILO8L_object_detection_3d | Rileva e localizza oggetti in 3D | Automobili autonome, AR/VR, robotica | 🔗 GitHub |
HAILO8L_person_attribute | Rileva attributi di persone (abbigliamento, età, genere) | Analisi retail, sicurezza | 🔗 GitHub |
HAILO8L_person_re_id | Riconosce persone in immagini diverse | Sorveglianza, analisi di comportamento | 🔗 GitHub |
HAILO8L_pose_estimation | Stima la postura di più persone | Sport, animazione, monitoraggio medico | 🔗 GitHub |
HAILO8L_single_person_pose_estimation | Stima la postura di una persona | Fitness, fisioterapia, gaming | 🔗 GitHub |
HAILO8L_semantic_segmentation | Segmenta l’immagine in aree con significato | Auto autonome, visione artificiale | 🔗 GitHub |
HAILO8L_super_resolution | Aumenta la risoluzione delle immagini | TV 4K, miglioramento qualità immagini | 🔗 GitHub |
HAILO8L_text_image_retrieval | Recupera immagini basate su testo | Motori di ricerca, gestione archivi visivi | 🔗 GitHub |
Una volta scelta la “funzionalità” del modello, bisogna scegliere il singolo modello.
Selezione del Modello e Classificazione delle Applicazioni
La scelta del modello di rete neurale dipende strettamente dal tipo di applicazione che si intende realizzare. Nel caso del progetto “Squid Game Doll”, l’obiettivo è quello di riconoscere in tempo reale i giocatori, utilizzando il modello YOLO (You Only Look Once) che è molto diffuso.
I modelli di YOLO sono progettati per eseguire operazioni di object detection, cioè identificare e localizzare oggetti all’interno di un’immagine o di un flusso video. Questo tipo di applicazione richiede una combinazione di velocità e precisione, poiché il sistema deve elaborare ogni frame della webcam in tempo reale.
E’ importante, per scegliere il modello dalla pagina di download, capire alcune delle colonne che caratterizzano i modelli.
- mAP (Mean Average Precision) – Una misura delle prestazioni del modello nella rilevazione degli oggetti. Più è alto questo valore, migliore è la precisione del modello nel riconoscere e localizzare gli oggetti.
- HW Accuracy (Hardware Accuracy) – Precisione misurata direttamente sull’hardware (HAILO-8L). Può essere leggermente inferiore all’mAP a causa delle ottimizzazioni necessarie per eseguire il modello in modo efficiente sull’hardware specifico.
- FPS (Batch Size=1) – Il numero di frame al secondo (FPS) elaborati dal modello quando viene inferito con un batch size di 1 (ossia un’immagine alla volta).
- FPS (Batch Size=8) – Il numero di frame al secondo elaborati quando il modello lavora con un batch di 8 immagini alla volta, che può migliorare l’efficienza sfruttando la parallelizzazione. Non è stato usato nella nostra applicazione al momento.
- Input Resolution (HxWxC) – La risoluzione dell’immagine in input, espressa in altezza x larghezza x numero di canali (solitamente 3 per immagini RGB). Un input più grande può migliorare l’accuratezza ma rallentare le prestazioni. Nel nostro caso abbiamo usato modelli con risoluzione 640×640.
- Params (M) – Il numero totale di parametri del modello (espresso in milioni, M). Un valore più alto indica un modello più complesso e potente, ma anche più pesante da eseguire.
- OPS (G) – Le operazioni computazionali richieste per eseguire una singola inferenza, espresse in giga operazioni (G). Modelli con un numero più alto di operazioni tendono a essere più accurati ma più lenti.
- Pretrained – Link per scaricare il modello pre-addestrato su dataset standard. Questo modello può essere usato così com’è o ulteriormente affinato su dati specifici.
- Compiled – Link per scaricare la versione compilata del modello, ottimizzata per l’hardware HAILO-8L. E’ quello che andremo ad usare.
Per scaricare il modello scelto sul Raspberry Pi, basta semplicemente usare wget con l’indirizzo della colonna Compiled:
wget https://hailo-model-zoo.s3.eu-west-2.amazonaws.com/ModelZoo/Compiled/v2.14.0/hailo8l/yolov11m.hef
Utilizzo del Coprocessore HAILO8L con Python
L’utilizzo di Python per eseguire modelli di rete neurale è ormai uno standard nell’ambito dello sviluppo AI, grazie alla vasta disponibilità di librerie e framework come TensorFlow, PyTorch e OpenCV per il trattamento di immagini.
L’approccio adottato prevede di scaricare il modello precompilato per HAILO 8L, integrarlo nel codice Python e utilizzare l’API specifica fornita dal produttore per comunicare con il coprocessore. Per iniziare con una nuova piattaforma, è sempre utile seguire gli esempi del produttore, disponibili qua: hailo-ai/Hailo-Application-Code-Examples . Ci sono altre API disponibili, ma questa si è rivelata la più semplice da integrare con il resto del programma.
Illustriamo come fare con un esempio. Bisogna anzitutto installare le librerie aggiuntive, possibilmente in un Python Virtual Environment creato in precedenza:
pip install git+https://github.com/hailo-ai/hailo-apps-infra.git
pip install opencv_python numpy
Un esempio minimale di codice Python per elaborare l’immagine e ritornare gli oggetti rilevati è disponibile sotto:
import cv2
import numpy as np
from hailo_platform import HailoAsyncInference
import threading
import queue
def preprocess_image(image_path):
""" Tratta l'immagine per l'inferenza """
image = cv2.imread(image_path)
image = cv2.resize(image, (640, 640)) # YOLOv8 usa input 640x640
image = image.astype(np.float32) / 255.0 # Normalizzazione
return np.expand_dims(image, axis=0) # Aggiunta batch dimension
# Creiamo le code
input_queue = queue.Queue()
output_queue = queue.Queue()
# Inizializzazione dell'inferenza
model_path = "yolov11m.hef"
inference_engine = HailoAsyncInference(model_path, input_queue, output_queue, 1)
# Lanciamo l'engine in uno thread indipendente
inference_thread = threading.Thread(target=inference_engine.run, daemon=True)
inference_thread.start()
# Caricamento di un'immagine e ridimensionamento
# Assicurati di avere un'immagine chiamata "test.jpg" nella stessa directory
test_image = preprocess_image("test.jpg")
# Metti l'immagine nella coda di input
# Questa chiamata non è bloccante
input_queue.put([test_image])
# Recupera il risultato, questa chiamata è bloccante
# Tempo di elaborazione: circa 100-120 ms
_, hailo_output = output_queue.get()
# Estrazione delle informazioni dal risultato
for class_id, detections in enumerate(hailo_output):
for detection in detections:
bbox, confidence = detection[:4], detection[4]
print(f"Oggetto rilevato: Classe {class_id}, Confidenza {confidence:.2f}")
print(f"Rettangolo: {bbox}")
Un esempio più completo, che integra il tracking degli oggetti rilevati con ByteTrack, è disponibile nella repository di progetto : PlayerTrackerHailo.py
Performance del modello
Un aspetto fondamentale per le applicazioni di object detection in tempo reale è la misurazione delle performance in termini di FPS (Frame Per Second). Una buona performance in FPS garantisce che il sistema sia in grado di processare un numero sufficiente di frame al secondo per mantenere un riconoscimento fluido e senza ritardi.
Nel progetto “Squid Game Doll”, le misurazioni in FPS hanno dimostrato che l’integrazione del chip HAILO 8L con il Raspberry Pi 5 permette di raggiungere prestazioni elevate (circa 8 FPS), indispensabili per l’utilizzo in ambienti dinamici. La stessa elaborazione fatta sulla CPU non raggiungeva 1 FPS, creando troppo “lag” per creare un gioco divertente.
Per migliorare ulteriormente le performance riconoscimento, è stato implementato una zona di interesse (crop) e ridimensionamento dell’immagine a 640×640 pixel con OpenCV, rispetto al flusso video della Webcam in risoluzione 1920×1080. Tale accorgimento è particolarmente importante per mantenere una buona accuratezza nei riconoscimenti anche a distanze superiori a 5 metri, dove la risoluzione e il campo visivo possono influire significativamente sulle performance del modello.
Un parametro molto importante, aggiustato manualemente per garantire una buona esperienza di gioco, è la soglia di confidenza minima per il riconoscimento e il tracking dei giocatori. L’abbiamo impostata al 40%.
Integrare il tracking dei giocatori
Il progetto non si limita al semplice riconoscimento, ma integra anche un sistema di tracking avanzato basato su ByteTrack, che permette di seguire il movimento dei giocatori all’interno dello scenario. Questo sistema di tracking è particolarmente utile in contesti dinamici, dove è necessario non solo identificare la presenza degli oggetti, ma anche analizzarne il comportamento e la traiettoria (perché i giocatori possono occultarsi a vicenda durante il gioco).
ByteTrack restituisce un ID univoco dell’oggetto, basandosi sullo storico delle posizioni dei rettangoli rilevati. Per collegare l’output del modello YOLO con ByteTrack, si può usare una libreria che standardizza i dati comuni dei modelli, chiamata supervision.
# Convert Hailo inference output into Supervision detections
detections_sv = self.__extract_detections(results, ratios, self.score_thresh)
detections_sv = self.tracker.update_with_detections(detections_sv)
Serve una funzione di conversione (__extract_detections), perché le coordinate ritornate del modello YOLO sono relative ai frame 640×640, mentre la webcam aveva una risoluzione (e potenzialmente un rapporto dimensionale) diverso.
def __extract_detections(
self, hailo_output: list[np.ndarray], ratios: tuple[float, float], threshold: float
) -> sv.Detections:
"""
Converts Hailo asynchronous inference output into a supervision Detections object.
Assumes the Hailo output is a list of numpy arrays where index 0 corresponds to person detections.
The bounding boxes are expected in the normalized [ymin, xmin, ymax, xmax] format.
Args:
hailo_output (list[np.ndarray]): Raw output from Hailo inference.
(video_h (int): Height of the original video frame.
video_w (int): Width of the original video frame.)
threshold (float): Confidence threshold.
Returns:
sv.Detections: Detections object with absolute pixel coordinates.
"""
xyxy = []
confidences = []
# Iterate over all classes, but only process the 'person' class (COCO index 0)
for class_id, detections in enumerate(hailo_output):
if class_id != 0:
continue # Skip non-person detections
for detection in detections:
bbox, score = detection[:4], detection[4]
if score < threshold:
continue
# Convert bbox from normalized [ymin, xmin, ymax, xmax] to absolute [x1, y1, x2, y2]
x1 = bbox[1] * ratios[0]
y1 = bbox[0] * ratios[1]
x2 = bbox[3] * ratios[0]
y2 = bbox[2] * ratios[1]
xyxy.append([x1, y1, x2, y2])
confidences.append(score)
if not xyxy:
return sv.Detections.empty()
xyxy_np = np.array(xyxy)
conf_np = np.array(confidences)
# Hailo output does not provide tracker IDs; we assign a default value (-1)
tracker_id_np = -1 * np.ones_like(conf_np)
return sv.Detections(xyxy=xyxy_np, confidence=conf_np, tracker_id=tracker_id_np)
Sperimentazione durante l’Arduino Day
Durante l’Arduino Day il 22 marzo 2025, è stato possibile testare in condizioni reali, con multipli giocatori, il comportamento del modello neuronale. Il gioco ha riscosso successo fra i ragazzi e incuriosito molti adulti. Sono emersi spunti di miglioramento per il gioco, che verrà successivamente descritto un articolo dedicato.
Installazione con Raspberry Pi 5, Hailo chip, webcam Logitech C920 e controller NES.
La realizzazione del progetto “Squid Game Doll” rappresenta un esempio di come il FabLab Bergamo si impegni nell’adozione e nella sperimentazione di tecnologie moderne. L’integrazione di un Raspberry Pi 5 con il modulo HAILO e il supporto di un modello YOLOv11 ottimizzato dimostra come sia possibile realizzare applicazioni di intelligenza artificiale a costi contenuti.
Per chi desidera approfondire e sperimentare ulteriormente, il repository GitHub del progetto offre una documentazione dettagliata e un punto di partenza per realizzare implementazioni personalizzate. L’adozione di un approccio open source garantisce trasparenza, collaborazione e costante aggiornamento, elementi fondamentali per il progresso tecnologico in un mondo in rapido cambiamento.
Considerazioni Finali
Con l’evoluzione continua dei modelli di machine learning e l’incremento delle capacità computazionali dei dispositivi embedded, possiamo aspettarci ulteriori sviluppi e applicazioni sorprendenti. La capacità di adattare e ottimizzare i parametri dei modelli, insieme all’integrazione di sistemi di tracking come ByteTrack, offre ai maker strumenti potenti per rispondere a sfide sempre più complesse in ambito di sicurezza, monitoraggio e interazione uomo-macchina.
Il FabLab Bergamo continua a essere un punto di riferimento per la sperimentazione tecnologica, dimostrando che anche soluzioni di punta possono essere realizzate con creatività, collaborazione e l’uso di tecnologie open source.