Il rilevamento dei volti rappresenta la porta d'accesso della maggior parte delle pipeline di computer vision. Ogni videochiamata, galleria fotografica e flusso di sicurezza dipende dall'individuazione dei volti umani prima che qualsiasi altra cosa possa accadere. Eppure, la scelta del modello solitamente impone un compromesso sgradevole. Le reti pesanti offrono precisione ma richiedono GPU costose e sistemi di raffreddamento a rack. I modelli più piccoli girano su hardware modesto, ma spesso faticano con i volti piccoli o i flussi ad alta risoluzione. Il modello YuNet dell'OpenCV Zoo rompe questo schema. Ho trascorso del tempo a testarlo con benchmark su diverse scale per vedere se meriti un posto in progetti reali o se sia solo bello sulla carta.

Perché YuNet merita un'analisi più approfondita

YuNet non è una curiosità accademica. Vive all'interno dell'OpenCV Zoo, una collezione di modelli pre-addestrati ottimizzati per il modulo OpenCV DNN. La variante specifica che ho testato utilizza la quantizzazione INT8, il che significa che i suoi pesi e le sue attivazioni vengono compressi in interi a 8 bit invece dei classici numeri in virgola mobile a 32 bit. Non si tratta di una nota tecnica minore. L'INT8 riduce drasticamente la larghezza di banda della memoria, diminuisce la pressione sulla cache e permette alle moderne CPU di gestire l'inferenza senza sforzo. Per chiunque lavori su un laptop, un dispositivo edge o un server senza una scheda grafica dedicata, questa efficienza rappresenta la differenza tra una pipeline fluida e una sequenza di immagini a scatti.

L'architettura stessa è leggera per progettazione. Evita il carico di enormi backbone e si concentra sul singolo compito di localizzare i volti. Questa disciplina paga quando è necessario integrare il rilevamento in un'applicazione più ampia, dove il budget di CPU e batteria deve essere condiviso con tracking, riconoscimento o codifica video.

Il Setup

Tutti i test sono stati eseguiti su un Mac Studio con chip Apple M4 Max. Il file del modello era la build ONNX quantizzata INT8 di YuNet dal repository OpenCV Zoo. Ho misurato la velocità di inferenza prima su un'immagine 1280x720, per poi confrontare il numero di rilevamenti su quattro diverse risoluzioni di input per capire come la scala influenzi i risultati.

Se desideri verificare questi numeri sulla tua macchina, il processo è completamente riproducibile. Esegui i seguenti comandi per scaricare il repository sparse ed eseguire il benchmark:

git clone --depth 1 --filter=blob:none --sparse https://github.com/kiarina/labs.git
cd labs
git sparse-checkout set .gitignore .mise/tasks Makefile mise.toml 2026/07/08/yunet-face-detection
mise -C 2026/07/08/yunet-face-detection run

Lo sparse checkout mantiene piccolo il download e il task runner mise gestisce le dipendenze dietro le quinte. Non dovrai lottare con gli ambienti Python o con l'installazione manuale dei pacchetti.

Una velocità che rimane costante

Su un'immagine 1280x720, il modello YuNet INT8 ha registrato una media di 9,21 millisecondi per inferenza. Il passaggio più veloce è stato di 8,03 ms, mentre il più lento ha toccato i 10,47 ms. Si tratta di un intervallo sorprendentemente ristretto. Meno di due millisecondi e mezzo separano il tempo migliore da quello peggiore.

In pratica, questa costanza conta più del semplice vanto. Le applicazioni in tempo reale non hanno solo bisogno di una bassa latenza media; hanno bisogno di una latenza prevedibile. Un modello che a volte impiega 50 ms crea scatti visibili in un flusso webcam. YuNet rimane costante. Puoi contare sul fatto che finisca un frame prima che arrivi il successivo, il che rende molto più semplice la pianificazione del resto della tua pipeline.

La variazione di scala rivela la vera storia

La velocità pura conta poco se il modello perde metà dei volti in una scena. Per testare questo aspetto, ho passato le stesse immagini sorgente attraverso YuNet a quattro diverse risoluzioni. I conteggi raccontano una storia chiara:

  • 320 x 180: 6 volti rilevati
  • 640 x 360: 26 volti rilevati
  • 1280 x 720: 38 volti rilevati
  • 2560 x 1440: 52 volti rilevati

Il salto è drastico. A 320 x 180, vengono registrati solo i volti più grandi e vicini. Passando a 640 x 360, il conteggio quadruplica. A 1440p completo, YuNet trova più di otto volte i volti rispetto alla risoluzione più bassa.

Questo accade perché il downsampling distrugge i dettagli più velocemente di quanto l'intuizione suggerisca. Un volto che occupa una porzione modesta in un frame a 1440p può ridursi a una macchia di cinque per cinque pixel a 360p. Una volta che i tratti somatici collassano al di sotto del campo ricettivo del modello, diventano rumore invisibile. Gli occhi si fondono con le sopracciglia. I nasi scompaiono. YuNet non ha nulla su cui aggrapparsi.

La conseguenza pratica vale la pena di essere ricordata. Se la tua telecamera cattura una visuale grandangolare di un'aula, di una sala conferenze o di un angolo di strada, i volti distanti non appariranno a meno che tu non fornisca al modello abbastanza pixel. In questo caso, la risoluzione non riguarda solo la qualità dell'immagine. È una leva diretta sulla recall.

La strategia di ridimensionamento di cui hai realmente bisogno

YuNet è abbastanza veloce da non dover ridurre forzatamente l'input a 320 x 240 per abitudine. Su M4 Max, anche 2560 x 1440 gira senza una GPU dedicata. Questo cambia il modo in cui dovresti progettare una pipeline.

Invece di forzare ogni fotogramma in una dimensione fissa minuscola, scegli la risoluzione di input in base a ciò che stai cercando di trovare. Se ti interessa solo la persona direttamente davanti alla telecamera, 720p o anche 640p sono più che sufficienti. Se devi catalogare ogni partecipante in una grande sala, fornisci al modello un ritaglio ad alta risoluzione o l'intero fotogramma nativo. Poiché YuNet è leggero, hai il margine necessario per fare questa scelta. Non sei vincolato a un unico preset per evitare un ritardo di 200 ms.

Rimane un'avvertenza. Il modello dipende ancora dalla dimensione del volto rispetto al tensore di input. Non esiste una magia di invarianza di scala in questo caso. I volti piccoli rimangono invisibili a meno che non occupino abbastanza pixel. La soluzione è meccanica: ridimensiona l'immagine sorgente verso l'alto prima dell'inferenza quando cerchi soggetti distanti, quindi mappa le bounding box risultanti sulle coordinate originali. YuNet ti offre il budget di velocità necessario per permetterti questo passaggio.

Dove si colloca nel tuo stack

YuNet non è una soluzione per ogni possibile compito relativo ai volti. Occlusioni pesanti, angolazioni di profilo estreme o l'estrazione di mesh 3D sono al di fuori del suo ambito. Ma per il lavoro fondamentale di localizzazione dei volti in foto e flussi video, occupa una posizione ideale. App webcam in tempo reale, strumenti automatizzati di selezione delle foto e sistemi embedded modesti beneficiano tutti di un rilevatore che gira velocemente su CPU standard.

Anche il formato INT8 ONNX rende la distribuzione senza complicazioni. Non è necessario installare PyTorch o TensorFlow sul dispositivo di destinazione. Il modulo DNN di OpenCV carica il modello direttamente, il che mantiene il tuo binario piccolo e l'albero delle dipendenze ridotto.

In sintesi

YuNet dimostra che il rilevamento dei volti non richiede hardware industriale o framework pesanti. I numeri parlano chiaro: meno di dieci millisecondi per un fotogramma a 720p e un aumento diretto e prevedibile del numero di rilevamenti all'aumentare della risoluzione. Puoi scegliere se desideri la massima velocità a una risoluzione moderata o una copertura più ampia a una scala maggiore, e il modello non ti penalizzerà per questa scelta.

Se stai costruendo qualcosa che elabora immagini del mondo reale, esegui i passaggi di riproduzione sopra indicati sul tuo hardware. Testalo con i tuoi filmati. Quindi, regola la tua logica di ridimensionamento per adattarla ai volti che devi effettivamente trovare. La velocità è utile solo quando puoi indirizzarla. YuNet ti offre sia la velocità che il controllo.