Prove di Face Detection

Primi esperimenti con reti neurali, cercando di trovare il volto delle persone.

Approfittando della pausa natalizia mi sto addentrando nel mondo dell’intelligenza artificiale. Uno degli esercizi del corso che sto seguendo prevede di applicare il riconoscimento facciale alle immagini prese dalla webcam. Quanto l’ho letto mi sono esaltato, ma mettendoci le mani dentro ho capito la differenza tra Conoscere e Sapere! E diciamo pure che le mie paure su un futuro imminente dominato dall’intelligenza artificiale si sono dissolte come neve al sole.

Le prime prove

I primi test li ho fatti usando il trailer di Top Gun II, ovvero Maverik, che ho scaricato e dissezionato frame per frame.

Non entro nei dettagli di come fare, questo non è un blog di coding. Però immagino che qualcuno possa essere incuriosito, pertanto vi lascio alcuni riferimenti in calce all’articolo.

Frame per frame

Questa è stata la prima scoperta, ovvero un stream di immagini viene analizzato frame per frame. Pensavo di vedere qualcosa di più avanzato, in cui il tracking venisse fatto sfruttando il fatto che le immagini di due frame adiacenti sono praticamente uguali, invece no, frame per frame, come se ogni frame fosse una cosa completamente diversa.

Face Detection e Face Recognition

Inoltre ho capito che stiamo parlando di Face Detection, non Face Recognition, ovvero di un algoritmo che cerca la faccia di una persona, non di un algoritmo in grado di identificare una certa persona all’interno della scena.

Per dirla in modo più chiaro: io o Tom Cruise, per l’algoritmo siamo la stessa cosa!

Funziona?

Ho provato a cercare occhi e facce dentro le circa 3166 immagini che compongono il trailer, ed in effetti alcune le ho trovate, ma lungi dal dichiararmi soddisfatto, anzi!

A seconda del fattore di scala che si usa, o a seconda del modello che si carica, i risultati sono molto diversi. E qui viene la seconda scoperta: questo algoritmo ha bisogno di qualcuno che ottimizzi i parametri per massimizzare il risultato, che potrebbe essere più facce trovate ma anche più falsi positivi, oppure meno facce però tutte corrette.

Ah ecco, i falsi positivi sono invece la terza scoperta! Ce ne sono, eccome! Ecco un paio di esempi.

Faccia o Occhio?
Sicuro che quello è un occhio? E la faccia?

Inoltre ho notato che l’attore di colore non viene mai identificato, che si tratti di un esempio di BIAS legato al training? Sembra che il problema non sia così trascurabile! WikiPedia: Algorithmic Bias

Algorithmic Bias verso le persone di colore?

Tempi di elaborazione

Lasciamo stare! Bene che vada, per cercare occhi e facce servono 200 ms per immagine, che a casa mia fanno 5 frame al secondo. Siamo lontani dai 24 fps originali del video. Per arrivare a 10 si deve sottocampionare e ridurre l’immagine HD (1920 x 1080) al 30%, ovvero ridurre di 9 volte il numero di pixel (3 volte in larghezza e 3 volte in altezza fa un’area 9 volte più piccola).

Certo sto solo usando un Core i5 del 2015 funzionante a 2.7 GHz. Se usassi un datacenter di Google sarebbe tutto diverso… A patto di avere tutto il datacenter disponibile!

Prova con la WebCam

Oggi mi sono svegliato alle 5 (perché non riuscivo più a dormire, anche se fa figo dire: preso dalla passione per machine learning…) e mi sono messo di buzzo buono a sviluppare l’ultimo esempio del corso di Machine Vision con OpenCV e Python.

Il codice è veramente semplice. Basta una chiamata a funzione, ci si collega alla videocamera, si legge un frame alla volta, lo si analizza, si plotta il rettangolo per la faccia e i cerchi per gli occhi e il gioco è fatto.

Non intendo descrivere il codice che ho creato, basta cercare Python OpenCV e Webcam e trovate migliaia di pagine. Ma provando mi sono accorto che…

Apple non è d’accordo

Iniziamo i primi intoppi! Sto usando macOs Catalina, il quale col cavolo permette ad una applicazione di accedere alla WebCam, se questa non viene esplicitamente autorizzata.

Provo ad acquisire le immagini dalla videocamera del computer, ma inesorabilmente la mia applicazione va in crash, a dispetto di tutti i blog che spiegavano come fare.

Certo Apple ha ragione, e io da utente mi sento più tutelato sapendo che se un’applicazione surrettiziamente tenta di accedere alla videocamera o al microfono, il sistema operativo la chiude con un bel calcio nel sedere!

Ma da sviluppatore ho scoperto mio malgrado che quel sedere era il mio!

Alla fine ho risolto eseguendo lo script Python dal terminale del Mac ed autorizzando il terminale ad accedere alla fotocamera, ma che stress…

Anche usando la webcam non vado oltre i 5 fps, al punto che mi sono inventato un meccanismo di campionamento temporale per rendere il video più fluido. L’idea è quella di analizzare un frame ogni 4 o 5 e supporre che la mia faccia rimanga nella stessa posizione anche per i 4 o 5 frame successivi. Approccio interessante, arrivo anche a 10 fps, solo che se sposto la testa si vede che il rettangolo si muove a scatti.

Bias dell’inventore

Questa è una cosa a cui non avevo pensato, e che ho scoperto comparando i risultati ottenuti con Tom Cruise rispetto a quelli ottenuti con la WebCam. Non capivo come mai con Tom Cruise la percentuale di successo fosse così bassa e quando invece sulla scena c’ero io il sistema sembrava funzionare meglio.

Semplice! Perchè io voglio che funzioni, mentre a Tom non gliene importa un fico secco.

Anche senza volerlo io mi ritrovo a cercare di far apparire il rettangolo verde attorno alla faccia, e ad allargare gli occhi come il Lupo di Cappuccetto Rosso pur di vedere il cerchio verde attorno ai miei occhi.

… che oggi grandi che hai nonnina… Per vederti meglio!

Questo perché io ho scritto l’esempio e voglio che funzioni.

Cosa non funziona

Dopo questo primo test le incredibili doti delle reti neurali ne escono sminuite e francamente mi sento meno minacciato dal loro avvento!

Ho già citato in precedenza la necessità di ottimizzare vari iperparametri per minimizzare falsi positivi e massimizzare il numero di volti identificati.

Ma ci sono anche altri aspetti che ne riducono la portata. Per esempio trovo sconcertante vedere come in due immagini apparentemente uguali per noi esseri umani, il volto venga trovato solo in una. Guardate i due frame qua sotto, nel primo Tom Cruise viene identificato, nel frame successivo no. Come mai?

Notate delle differenze tra il frame 1286 il frame 1287?

Se siete curiosi riguardo a questi problemi, leggete questo bel post di Uncle Bob: Drive Me to Toronto HAL

Un’altro aspetto che ho notato è che, come è normale che sia, le prestazioni dell’algoritmo di ricerca calano quando l’immagine diventa più rumorosa. In particolare mi è capitato di spostare il portatile dalla cucina, illuminata da un bel sole mattutino, al corridoio, illuminato solo dalla luce artificiale e di vedere le prestazioni crollare. Automaticamente la telecamera ha regolato la luminosità, la mia immagine è rimasta visibile, seppur con una qualità vergognosa, ma la mia faccia era perfettamente visibile. Lo script era attivo, ma il mio viso non lo trovava, nonostante i miei sforzi di compiacere l’algoritmo.

Per finire, sottolineo come sia estremamente facile fregare l’algoritmo di ricerca. Essendo basato sulle Wavelet di Haar, è robusto rispetto alla scala, ma molto debole rispetto alla rotazione. Basta inclinare la testa di lato per fargli perdere il lume della ragione, o la faccia…

E la faccia? Basta una marcata inclinazione e va persa!

Conclusioni

Forse la mia analisi dovrebbe tener conto che si tratta di una tecnologia inventata nei primi anni 2000 (cfr Cascading Classifiers), e sicuramente oggi i vari tool che riconoscono i volti: Google Photo, SnapChat, TicTok, Facebook e altri, useranno algoritmi migliorati, ma mi sono reso conto che anche le reti neurali hanno gli stessi problemi dei sistemi di visione tradizionali, ovvero:

  • Richiedono una ottimizzazione rispetto alla applicazione
  • Bisogna bilanciare falsi positivi rispetto al read rate
  • Non credo che possano esistere sistemi che funzionano subito appena li tiri fuori dalla scatola.
  • Quando non funzionano non funzionano, prendere o lasciare. Capire il perché è impossibile.

Comunque il mio viaggio è appena iniziato, e non sarà questo primo esperimento a scoraggiarmi. Ho già adocchiato alcuni post interessanti con esempi che promettono faville. Vi farò sapere.

Ma per oggi lasciatemi dire: La mia razza sarà pure destinata all’estinzione, ma non oggi!

Sentite Tom Cruise che lo dice. Mi fa venire i brividi!

Riferimenti

Se cercate un esempio di come usare le OpenCV per riconoscere facce, ecco il tutorial ufficiale:

https://docs.opencv.org/3.4/db/d28/tutorial_cascade_classifier.html

Non avete idea di cosa sia un classificatore a cascata? Eccovi un link:

Se volete approfondire rapidamente la differenza tra Haar e LBP, potete partire dalla pagina su Wikipedia:

Se volete scaricare i modelli pre-trainati per riconoscere gatti, pedoni, posate, facce e occhi, questi sono i due link su GitHub dove trovate il tutto

Se invece volete fare un corso gratuito su Python e OpenCV, io ho seguito questo: Learn Computer Vision with OpenCV using Python

Autore: Gianbattista

Appassionato di tecnologia, è l'autore di Qt5 Quanto Basta. Per lavoro mi occupo di elaborazione delle immagini per applicazioni industriali.

2 pensieri riguardo “Prove di Face Detection”

  1. Peccato che le OpenCV non usino reti neurali e che tutti i problemi menzionati sono risolti in algoritmi a stato dell’arte. Peccato vedere errori così grossolani affermati con così tanta certezza.

    1. Grazie per il commento. Al momento sto testando altre librerie, in particolare DLib. Se però ha dei suggerimenti da darmi, ben venga.
      Quanto alle OpenCV, hai ragione, non usano le reti neurali.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *