Elaborato Facce 3d

Sommario

Introduzione

Per l’esame di Sistemi di Elaborazione dobbiamo lavorare con le facce 3d. Ci sono dei progetti in questo ambito nel laboratorio del professore e quindi anche gli studenti collaborano allo sviluppo.

Esiste una discreta letteratura sulle facce 3d, ma il problema che ci è stato chiesto di affrontare riguarda la “normalizzazione” di un archivio di facce in VRML 1.0 per permettere al laboratorio procedere con il confronto. Per normalizzazione si intende la scalatura a dimensioni standard e il posizionamento standard nello spazio 3d.

Si pone un primo problema, quali sono i riferimenti standard per un volto?

La risposta più ovvia: si chiede a chi sa disegnare!

Schizzo di una testa in 3d

Leggendo questo articolo sul disegno di teste si possono estrarre alcune indicazioni importanti:

Faccia di profilo con linea verticale

  • Il volto è diviso in tre parti di dimensione comparabile:
    • La prima dall’attaccatura dei capelli all’inizio del naso.

    • La seconda dall’inizio del naso al labbro superiore.

    • La terza dal labbro superiore alla fine del mento.

Faccia divisa in 6 zone quadrate

Un’altra indicazione importante è che si può definire l’asse verticale di un volto congiungendo il punto dove finisce la fronte ed inizia il naso con il punto tra naso e labbro superiore. Osserviamo che essendo due punti molto vicini all’osso sono piuttosto stabili anche cambiando espressione.

Per procedere con il lavoro sulle facce 3d, io e il mio collega per l’elaborato, abbiamo, dovuto capire come funziona un file VRML. Un ottimo sito con esempi e documentazione (VRML Interactive Tutorial @ Lighthouse 3D) mi ha aiutato a capire che:

  • la prima lunga lista di numeri (triple) è come ci si può aspettare la lista dei punti che compongono l’immagine,
  • la seconda lunga lista di numeri (quadruple e quintuple) è la lista dei poligoni, definiti in senso antiorario (per indicare la faccia opaca) e terminati da un “-1”.

Faccia con evidenziati i poligoni più lunghi della mediaGrazie a ScientificPython ed a VPython possiamo visualizzare in poche righe di codice la nostra faccina.

Per fare una prova abbiamo calcolato media e varianza delle distanze tra i nodi di uno stesso poligono, e nell’immagine abbiamo evidenziato in rosso i poligoni che hanno un lato di lunghezza superiore alla somma di media e varianza calcolate su tutti i poligini della faccia 3d.

< — Questo è il risultato, in 41 righe di (impresentabile…) codice!

Sinceramente non conosco bene il Java, ma penso proprio che anche con tutte le librerie del mondo sarei ancora a lottare con il compilatore… mentre in python ho già finito!

Stato dell’arte

Abbiamo fatto uno studio sullo stato dell’arte nello studio di volti tridimensionali. Le pubblicazioni sono abbondanti, alcune sono purtroppo prigioniere degli esosi balzelli della IEEE, ma comunque quelle liberamente accessibili bastano ad avere una panoramica sull’argomento.

Dall’analisi è emerso che il problema è molto ampio e dà spazio a mille possibili approcci, per questo abbiamo ipotizzato un processo plausibile ed abbiamo chiesto indicazioni al professore riguardo all’aspetto dello studio da privilegiare.

Abbiamo concluso una prima fase di analisi dell’ambito operativo dell’elaborato (vedi file allegato Elaborato Facce 3d SE (PDF)) ed abbiamo identificato tre possibili fasi consecutive:

####Fase 1

Il problema è quello di identificare una nuova faccia in una delle classificazioni presenti in archivio (cioè controllare se un volto è stato ripreso frontalmente, lateramente, dal basso, etc.). In questo caso possiamo procedere suddividendo l’archivio in una parte di “addestramento” e una parte di “test” e investigare sui possibili algoritmi di classificazione.

####Fase 2

Supponiamo di avere volti già classificati per “inquadratura” (frontale, laterale, etc., come in effetti sono nell’archivio fornito). Il problema è quello di identificare la zona del volto all’interno della mesh, che, come abbiamo visto, spesso comprende componenti estranei. Data la grande differenza tra le inquadrature possibili sarà quasi sicuramente necessario sviluppare un algoritmo specifico per ogni inquadratura. In questo caso sceglieremo una delle inquadrature e indagheremo sui possibili metodi di individuzione della zona volto.

####Fase 3

Supponiamo di avere mesh di soli volti ( precedentemente classificati per inquadratura ). Il problema è quello di posizionare la mesh del volto in un sistema di riferimento robusto alle naturali differenze tra i volti in archivio. In questo caso potremo procedere identificando alcuni punti stabili ( vicino alle parti ossee ) nei volti per posizionare in modo coerente il sistema di riferimento e per avere informazioni sulla dimensione relativa dei volti forniti.

Da questa analisi della situazione risulta ovviamente che affrontare le problematiche delle tre fasi consecutive è molto impegnativo. Nella nostra analisi queste tre diverse situazioni, pur richiedendo metodologie diverse, hanno difficoltà comparabili.

Vorremo una sua indicazione sulla correttezza della nostra analisi su quale delle tre problematiche focalizzare la nostra attenzione anche in funzione di quanto già svolto nel suo laboratorio.

A parte le pubblicazioni consultate (elencate in calce all’allegato), abbiamo tratto ispirazione e sfruttato alcune immagini dalle seguenti pagine:

* drawsketch.about.com
* www.anticz.com
* www.portrait-artist.org

Il professore ha risposto di occuparci della fase 3, abbiamo scelto quindi le immagini di tipo frontale (ex fase 1), provvederemo manualmente alla selezione della zona facciale (ex fase 2) e concentreremo le nostre forze nel normalizzare posizione e dimensione del volto nello spazio 3d.

Informazioni sulla curvatura

Dovendo definire la posizione, non è possibile sfruttare alcun tipo di gradiente della superficie (mancano le nozioni di alto e di basso), e ci dobbiamo limitare ad informazioni relative.

Abbiamo definito per ogni poligono un vettore normale, rappresentato in figura.

Vettore Normale

Abbiamo visto che il solo modulo del vettore normale da indicazioni sulla posizione del poligono rispetto all’obiettivo.

  • I poligoni con modulo vicino al massimo sono poligoni molto lunghi e sono quasi paralleli all’asse dell’obiettivo.
  • I poligoni con modulo vicino al minimo sono invece perpendicolari all’asse dell’obiettivo.

Creando un grafo dei poligoni, in modo da conoscere i poligoni confinanti con ogni poligono sono possibili altre due misurazioni.

Definiamo zona di grado 0 il poligono che stiamo osservando, zona di grado 1 l’insieme dei poligoni direttamente connessi al poligono centrale, zona di grado 2 l’insieme dei poligoni connessi ad un poligono della zona di grado 1 che non siano già assegnati ad una zona di grado inferiore, e così via.

Superficie connessa

Definite queste zone, possiamo definire la prima misura come somma delle normali dei poligoni fino ad un grado arbitrario. Ad esempio per grado pari a 2:

Vettori Normali

Possiamo osservare che questa misura non è in grado di discriminare tra zone curve (tipo la punta del naso) e zone rumorose (tipo la zona dell’occhio), anzi nei pochi esperimenti abbiamo notato che il modulo vicino al massimo tende ad evidenziare le zone molto rumorose (zona oculare).

Da questa osservazione abbiamo definito una misura, più onerosa nel calcolo, ma in grado di discriminare tra zone curve e zone rumorose. Per ogni poligono nella zona di interesse (zona di grado 1 in figura) si calcola la somma di grado 1 (rosso tratteggiato) e si restituisce la proiezione del vettore somma sul vettore normale al poligono centrale (blu). La misura è la somma dei vettori proiezione (rosso).

Somma proiezioni adiacenti

Questa misura riesce a discriminare tra zone piane (modulo massimo), zone curve (modulo medio) e zone rumorose (modulo minimo).

Mappatura su un volto

Ecco la rappresentazione con la mappa “hsv” di matplotlib della norma di questi vettori:

Mappa Proiezione2 di Zona (step1=3, step2=3):

ZoneProj2-hsv-3-3-cara1_frontal1

Possiamo osservare che questa misura di curvatura evidenzia la zona oculare e la zona della bocca.

Nelle immagini a seguire abbiamo evidenziato in blu il 5% inferiore del valore normalizzato, e possiamo notare come questo identifichi nei due esempi la zona oculare.

cara1_frontal2_ZoneProj2-jet-2-2
cara1_frontal1_ZoneProj2-jet-2-2

Questo tipo di stima della regolarità permette di sfruttare l’informazione presente nel disturbo per identificare alcune zone del volto.

Queste informazioni sono molto importanti, in quando per le successive operazioni di solito la mesh viene filtrata in modo da ridurre il rumore.

Test su 20 volti

Abbiamo effettuato un test sui primi 20 volti del dataset, abbiamo identificato il primo 5% della funzione PoliProj2(2,2), abbiamo identificato le zone connesse del grafo delle facce e scelto i 3 cluster più numerosi: i primi 2 in giallo ed il 3o in celeste. Il centro della stera è il baricentro del cluster, il raggio della sfera è proporzionale alla distanza tra i primi due cluster.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20

Possiamo osservare che:

  • 18/20 i primi 2 cluster indicano almeno un occhio
  • 7/20 i primi 2 cluster indicano esattamente gli occhi
  • 13/20 i primi 3 cluster indicano gli occhi e un’altra zona
  • 3/20 i primi 3 cluster indicano gli occhi e la bocca
  • 10/20 cluster sono sul bordo della figura e potrebbero essere correttamente scartati
  • 15/20 esiste un cluster sulla bocca in posizione centrale rispetto agli occhi