Capitolo 6 Applicazione delle texture

Questa parte del lavoro inizia con l’acquisizione di un insieme di fotografie scelte in base agli studi sul reperto che ritraggono un individuo compatibile da diversi punti di vista quindi prosegue secondo tre step successivi.

Nel primo step le immagini subiscono una elaborazione preliminare, nel secondo vengono adattate alla superficie del reperto ricostruito e nel terzo vengono combinate per produrre una singola texture che verrà applicata secondo una mappatura cilindrica. Questo tipo di mappatura permette di osservare il modello da qualunque punto di vista riducendo al minimo gli artefatti.

 

L’applicazione delle texture è sicuramente la parte meno scientifica del lavoro, dopo aver riposto tanta cura nella ricostruzione del modello tridimensionale un uso scorretto delle texture può alterarne completamente la percezione, e dato che diverse procedure prevedono interventi manuali la correttezza dell’esecuzione è lasciata alla cura dell’operatore e degli studiosi che lo supervisionano.

Va comunque ricordato che lo studioso interessato al reperto troverà molto più interessante l’analisi dei dati nella forma volumetrica (piu’ ricca di informazioni) mentre il ruolo del modello completo delle texture è invece quello di essere un efficace mezzo per comunicare ai non adetti ai lavori i risultati raggiunti in quanto integra ed esprime molte delle conoscenze che si sono acquisite.

 

Le immagini inizialmente fornite da Francesco Mallegni si sono rivelate non adatte allo scopo per l’eccessivo contrasto e la presenza di zone completamente oscurate,  anche le immagini mostrate in questo capitolo non sono ottimali e vanno considerate principalmente dimostrative dell’uso dei programmi.

6.1 Coordinate di Texture

Il texture mapping è la tecnica che permette di applicare una immagine sopra una superficie in modo da simulare un grado di dettaglio superiore a quello raggiungibile tramite la sola modellazione.

Il particolare modo in cui si intende applicare l’immagine viene specificato fornendo alle librerie grafice le coordinate di texture che mettono in corrispondenza ciascuno dei vertici con una posizione nella texture.

VTK permette di usare texture monodimensionali, bidimensionali (immagini), e tridimensionali (volumi). Le posizioni in una texture bidimensionali sono specificate mediante due coordinate indicate con r ed s, la posizione (0,0) indica l’angolo in alto a destra nell’immagine, la posizione (1,1) l’angolo in basso a sinistra.

Figura 11 uso delle coordinate di texture

 

Si può immaginare che la texture sia ripetuta più volte in modo da tassellare completamente lo spazio r,s oppure vi sia presente una volta sola. La scelta fatta determina il risultato che si ottiene specificando posizioni con coordinate esterne all’intervallo [0,1], nel secondo caso viene restituito un colore di default.

Solitamente il numero di poligono in una superficie è tale da non permettere di specificare le coordinate di texture esplicitamente, quindi è più frequente che queste vengano calcolate derivandole secondo diverse modalità dalle coordinate dei vertici. Esistono allo scopo algoritmi che realizzano diversi tipi di mapping, la figura seguente mostra esempi di proiezione planare,cilindrica e sferica.

Figura 12 esempi di mapping cilindrico sferico e planare

 

In questi casi ci saranno dei parametri che permettono di specificare un piano, un cilindro o una sfera nello spazio, il procedimento è molto simile ad un cambio di sistema di riferimento. Il piano con la sua normale definisce un riferimento cartesiano, esprimendo un vertice rispetto a questo sistema di riferimento le coordinate r ed s vengono derivate dalle coordinate x e y, nel caso del mapping sferico r ed s sono derivate dalla longitudine e dalla latitudine, per il caso cilindrico dalla longitudine e dalla quota.

Ciascun tipo di mappatura produce diversi tipi di artefatti, in particolare la proiezione frontale è adatta solo nel caso in cui si intenda osservare la superficie da un particolare punto di vista, le altre due proiezioni limitano la presenza di artefatti alle zone dei poli.

Per l’applicazione delle texture ad un volto in generale si adotta la proiezione cilindrica secondo un asse verticale, in questo modo gli artefatti vengono a trovarsi alla base del collo, che generalmente non è visibile, e alla sommita del capo dove possono essere confusi grazie alla presenza dei capelli. Rispetto alla proiezione sferica quella cilindrica inoltre porta una distribuzione della texture piu omogenea nel senso dell’altezza.

 

L’utilizzo del Texture Mapping in VTK coinvolge diverse classi, abbiamo gli oggetti vtkTexture che ricevono in ingresso uno StructuredPoint che rappresenta l’immagine e vanno associati ad un particolare Actor. Le coordinate di texture sono attributi dei dataset e possono essere create esplicitamente o mediante le classi vtkTextureMapToBox, vtkTextureMapToPlane, vtkTextureMapToSphere, vtkTextureMapToCylinder.

6.2 Trattamento preliminare delle immagini

Distinguiamo gli effetti derivanti dall’uso delle texture in positivi e negativi.

Effetti Positivi

Il modello privo delle texture comunica, nella migliore ipotesi, la sensazione di  una statua di gesso, mediante l’uso delle texture si compie un buon passo avanti nella rappresentazione di un volto umano. In questo aspetto hanno un ruolo importante i dettagli minuti come le ciglia, le piccole rughe e i pori della pelle.

Costruendo texture a partire da fotografie questi dettagli sono facilmente acquisibili.

Effetti negativi

La tridimensionalità del modello viene percepita in massima parte grazie al gioco di luci e di ombre che si forma sulla sua superficie, le texture derivanti da fotografie portano altre ombre che confondono la percezione.

In altre parole l’aspetto del modello viene facilmente alterato più di quanto si desideri.

Per limitare gli effetti negativi occorre sottoporre le fotografie ad un trattamento preliminare, che può essere eseguito mediante un normale programma di fotoritocco, in modo da eliminare quelle ombre che risultano non desiderate.

Tale trattamento non risulta sempre facile ed in generale provoca la perdita dei dettagli minuti. Le figure di seguito mostrano due casi opposti.

Figura 13 La fotografia non ha subito nessun trattamento, risulta evidente l’alterazione del modello, in particolare nella forma del naso.

 

Figura 14 La fotografia è stata trattata senza attenzione, la forma del modello non risulta alterata ma si perdono la caratteristiche del fotorealismo.

 

Per la corretta esecuzione di questo step si deve trovare il giusto compromesso tra i due casi esposti, è inoltre opportuno avere sempre in vista il modello senza le texture per valutare il risultato.

 

Nella figura 1-10 si possono vedere le fotografie usate prima e dopo l’elaborazione preliminare, le immagini sono state ridimensionate al formato 512x512 perché le librerie richiedono che le texture abbiano dimensioni pari ad un potenza di due.

6.3 Adattamento delle fotografie al modello

Al termine di questo step le fotografie dovranno proiettarsi correttamente sull modello, ciò vale a dire che ogni feature del volto dovrà andare a posizionarsi sulla feature corrispondente della superficie tridimensionale.

Dato che le fotografie e modello rappresentano individui diversi nessuna modalità di proiezione delle texture può produrre il risultato desiderato (la corrispondenza tra le feature non può essere espressa da una trasformazione globale). Per questi motivi si è scelto di proiettare le immagini secondo una semplice proiezione planare e di creare uno strumento che permetta di deformare le fotografie osservando  interattivamente il risultato sulla superficie tridimensionale.

Il compito richiede un certo impegno da parte dell’operatore per almeno due motivi, il primo è che l’occhio umano è particolarmente attento nell’osservare i dettagli di un volto umano ed ogni artefatto, come ad esempio, un minimo errore nel posizionamento degli occhi viene immediatamente percepito. Il secondo è dovuto alla difficoltà di individuare le feature della superficie quando si aggiungono le texture Per ovviare in parte a questo inconveniente in una finestra del programma sono stati inseriti due Renderer che mostrano la superficie con e senza le texture. I due Renderer contengono lo stesso oggetto Camera in modo che le due viste restino sempre sincronizzate.

Figura 15

 

Lo strumento per la deformazione delle immagini è essenzialmente una griglia di cui si possono specificare il numero di divisioni orizzontali e verticali. La griglia viene sovraimposta all’immagine e trascinandone i vertici l’immagine si deforma in maniera corrispondente. è possibile trascinare un solo vertice, una riga oppure una colonna, si può limitare il trascinamento ad una sola direzione, i vertici non possono uscire dall’immagine. è possibile applicare trasformazioni successive e si possono annullare le ultime modifiche portate.

Figura 16 immagine di partenza

Figura 17 deformazione per righe

Figura 18 deformazione per colonne

Figura 19 deformazine per punti

Generalmente si usa una griglia a maglie larghe e spostamenti di righe o colonne nei primi passi, e la deformazione per punti con una griglia fitta per i ritocchi finali. Sebbene lo strumento sia rudimentale permette l’accuratezza necessaria in questo step, il feedback non è particolarmente brillante su macchine prive di accelerazione grafica, si ha invece l’impressione di manipolare una superficie fluida se si dispone di hardware adeguato.

 

Per descrivere l’implementazione dello strumento ci riferiamo alla figure 1-10.

Abbiamo due oggetti chiamati Grid ed SG, Grid è la griglia visibile nelle figure precedenti e serve a mostrare all’utente dove sono i vertici, è un oggetto PolyData e le sue celle sono linee definite da Cells. L’oggetto SG è uno StructuredGrid, in particolare un piano sul quale le fotografie sono applicate come texture e condivide con Grid i vertici Pts.

Figura 110 - Pipeline dello strumento per la deformazione delle immagini

 

Per cambiare il numero di divisioni della griglia o per annullare le ultime modifiche l’utente preme il pulsante ResetGrid, In risposta all’evento ResetGrid gli oggetti Cells, Pts e TCoord sono ricreati opportunamente.

In risposta all’evento MouseDown si verifica se è stato selezionato un vertice, se questo è il caso le successive MouseMove ne alterano le coordinate e lo schermo viene aggiornato chiamando il metodo Update di RW.

In risposta all’ evento Hold si nasconde l’oggetto Grid e si aggiorna lo schermo, l’immagine prodotta viene catturata mediante l’oggetto R2I e diviene la nuova texture associata all’oggetto A, la griglia viene resettata e nuovamente mostrata.

L’evento Update3Dview in modo analogo al precedente provoca l’aggiornamento della vista tridimensionale.

Figura 111

 


6.4 Costruzione della texture Cilindrica

La costruzione di una texture cilindrica T, a partire da un insieme di fotografie (viste) V1 .. Vn prevede di scandire i punti p della texture e per ciascuno di questi

·        individuare i punti corrispondenti q1 .. qn nelle fotografie

·        combinare i valori Vi(qi)  per ottenere il colore da assegnare a T(p)

 

Riguardo al primo punto, si immaginano i punti della texture posizionati su un cilindro come illustrato nella figura seguente, proiettando p sull’asse del cilindro si interseca la superficie[1] del volto in un punto q, da questo si può risalire a q1 .. qn secondo quanto indicato nel paragrafo precedente.

Figura 112 - corrispondenza tra i punti nella texture cilindrica e i punti nelle fotografie

Un modo di combinare i colori così individuati nelle viste è quello di usare una media pesata (inviluppo convesso) con pesi mi(p).

 

I pesi usati devono tenere in considerazione l’orientamento della faccia interessata da q e la sua visibilità, quindi si pongono le seguenti condizioni:

·        mi(p)  µ Nq · NVi   (certezza posizionale)

·        Nq · NVi < 0 Þ  mi(p) = 0 (auto occlusione)

L’approccio mostrato si rifa a quello presentato da Pighim ed altri in [Pigh],

Nel suo lavoro Pighim fa anche osservare che per rendere poco visibili nella texture le transizioni da una vista all’altra mi(p) deve variare dolcemente al variare di p, e mostra il procedimento da loro usato per raggiungere questo scopo.

Si costruiscono n mappe di visibilità Fk rappresentate come immagini di dimensioni pari alla texture e inizializzate ponendo Fk(p)=1 se p è visibile nella k-esima vista e 0 altrimenti.

Alle mappe di visibilità viene poi applicato un operatore di Smooth[2] e i pesi sono espressi come mi(p) = (Nq · NVi ) Fi (p).

 

La realizzazione di questa parte del nostro lavoro tiene in considerazione tutti gli aspetti esposti fino a qui ma procede in modo diverso, uno dei motivi di questa scelta è che l’operazione di proiettare il punto p della texture sulla superficie per individuare il suo corrispondente q , sebbene sia semplicemente realizzabile in VTK, risulta piuttosto gravosa il metodo esposto di seguito permette di evitarla.

 

·        Si proiettano separatamente le viste sul cilindro, nel nostro caso abbiamo usato quattro viste quindi si ottengono quattro texture cilindriche.

·        Si creano altrettante mappe dei pesi che vengono inserite nelle texture cilindriche come canale alfa, i punti con peso zero diventano quindi trasparenti e i punti con peso uno completamente opachi.

·        Si visualizzano le quattro texture cilindriche sovrapposte e si fotografa il risultato.

 

Tutte le operazioni sono semplicemente realizzabili ma prima di descriverle occorre introdurre un particolare problema dovuto alla mappaura cilindrica che viene illustrato dalla figura seguente. Il filtro vtkTextureMapToCylinder produce correttamente le coordinate di texture come ci si aspetta, con le coordinate r che variano ruotando intorno alla superficie e le coordinate t che variano dall’alto verso il basso, fissando opportunamente i parametri di la texture si richiude su se stessa in corrispondenza della nuca, .

Figura 113

In corrispondenza della cucitura ci saranno necessariamente delle facce che hanno da un lato un vertici con coordinata r >= 0 e dall’altro vertici con coordinata r <1, di conseguenza il motore di rendering proietta su queste facce l’intera sezione orizzontale della texture come illustrato nel caso (a).

Il caso e’ noto e infatti vtkTextureMapToCylinder dispone di uno switch detto PreventSeam che calcola r in modo diverso,  e cioè facendolo variare da zero ad uno andando dalla nuca verso la fronte e quindi tornando da uno a zero nell’altra metà, in questo modo la texture deve rappresentare solo metà della faccia e viene mappata due volte producendo quindi un volto simmetrico. Dato che le asimmetrie in un volto rivestono un ruolo importante nella sua percezione abbiamo ritenuto questa soluzione troppo limitativa e quindi è stato realizzato un nuovo filtro che oltre a creare le coordinate di texture previene il problema della mappatura cilindrica duplicando alcuni dei vertici della superficie in modo da potergli assegnare la coordinata di texture r=1, vedere nella figura il caso (b).

 

Torniamo alla creazione della texture cilindrica, nel programma realizzato avremo un oggetto “Surf” che rappresenta il volto, da questo otteniamo un oggetto chiamato “flat” che ne rappresenta lo sviluppo su un piano. Per ottenere “flat” si crea una copia di “surf”, si calcolano le coordinate di texture mediante il nuovo filtro realizzato, e quindi si sostituiscono le coordinate di texture alle coordinate dei punti ponendo x=r, y=s,z=0.

Figura 114 i due oggetti “surf” e “flat”, sull’oggetto surf è proiettata la vista di destra, l’immagine centrale suggerisce come la vista viene portata su flat.

 

Figura 115

Figura 116

 

 

 

Per ottenere le quattro texture cilindriche si calcolano per “Surf” le coordinate di texture secondo la proiezione planare, si inseriscono queste coordinate nell’oggetto “flat”, l’oggetto “flat” viene visualizzato associandogli come texture una delle viste, e l’immagine prodotta viene catturata e salvata.

 

Figura 117

Per ottenere le mappe dei pesi è stato scritto un filtro apposito che riceve “surf ” in ingresso ed una direzione di proiezione e quindi crea degli scalari s ponendo

s(p)  = Np · NVi   se Np · NVi  >= 0  

s(p)  = 0  altrimenti

ovvero, per ogni vertice calcola il prodotto vettoriale della normale alla superficie in quel punto per la direzione della vista, ponendolo a zero se la normale e la direzione della vista sono discordi.

Analogamente a prima questi scalari sono inseriti nell’oggetto “flat”, e visualizzati, dopo avere catturato l’immagine si applica un filtro vtkImageGaussianSmooth.

Il risultato è analolgo a quello discusso da Pighim con l’eccezione che l’operatore di Smooth viene applicato alla mappa dei pesi anziché alle mappe di visibilità.

L’ ultimo filtro creato appositamente è vtkInsertAlphaChannel che combina le singole texture cilindriche con le immagini dei pesi, usando questi ultimi come canale alfa.

 

Figura 118

 

Nella figura seguente sono illustrate le varie immagini prodotte in questa fase, gli artefatti visibili nella zona del collo dovuti ad un errore nella creazione di flat non ancora risolto per motivi di tempo.

Figura 119

 

6.5 Elaborazione finale della texture cilindrica

Si può ancora intervenire sulla texture cilindrica per inserire altri dettagli non presenti nel soggetto fotografato, questi possono essere ispirati dalla conoscenza dei costumi in usanza nella popolazione di provenienza del reperto ad esempio riguardo all’acconciatura della barba e dei capelli oppure riguardo il trucco. Altri dettagli possono essere osservati direttamente sul reperto, come l’attaccatura dei capelli ed il loro tipo, se questi sono eventualmente presenti.

 

Nonostante l’ineguatezza delle fotografie disponibili sono stato incoraggiato ad eseguire anche questa parte del lavoro, sono state create due diverse texture per dare modo all’antropologo Mallegni di valutare quanto queste possano alterare la percezione del modello tridimensionale.

Le modifiche apportate alla texture riguardano il colore della pelle, il trucco e la barba e si basano sui suggerimenti e sul materiale iconografico che sono stati forniti da Marilina Betrò.

Per le elaborazioni finali della texture è stato usato un comune programma di fotoritocco.

 

Figura 120 varie viste del della texture dopo l’elaborazione finale

 

 

Figura 121 Ricostruzione completa delle texture derivate dal soggetto 1

Figura 122 Ricostruzione completa delle texture derivate dal soggetto 2

 

 

 



[1] Se la superficie viene intersecata piu’ volte, come avviene tipicamente in corrispondenza delle orecchie, si prendera’ il punto piu’ esterno. Da cio’ possono derivare degli artefatti che che sono tipici dell’uso della mappatura cilindrica.

[2] Generalmente un operatore di Smooth e’ realizzato mediante la convoluzione con un nucleo gaussiano.