Elaborazioni nel dominio spaziale (2)
Transcript
Elaborazioni nel dominio spaziale (2)
Elaborazione dei Segnali Multimediali a.a. 2009/2010 Elaborazioni nel dominio spaziale (2) L.Verdoliva In questo laboratorio proseguiamo lo studio sulle elaborazioni spaziali, in particolare, oltre al bit-plane slicing, esamineremo le operazioni aritmetiche e quelle geometriche. Analizzeremo infine il filtraggio in diverse applicazioni come la rimozione di rumore, mediante filtri di smoothing, e l’enhancement con enfasi sui dettagli, mediante filtri di sharpening. 1 Bit-plane slicing Consideriamo un’immagine in cui ogni livello è rappresentato su 8 bit. E’ possibile suddividere l’immagine in bit-plane, cioè in piani in cui si rappresentano ognuno dei bit da quello meno significativo (bit-plane 0) a quello più significativo (bit-plane 7). La decomposizione di un’immagine digitale in bit-plane (bit-plane slicing ) è molto utile per comprendere l’importanza che ogni bit ha nel rappresentare l’immagine e quindi se il numero di bit usato nella quantizzazione è adeguato. Proviamo ad elaborare l’immagine Fig3.13.jpg per ottenere i relativi bit-plane. Ci sono diversi modi, più o meno efficienti, di scrivere il codice Matlab. Un primo modo per ottenere i bit-plane è attraverso un’operazione a soglia, infatti la trasformazione ½ 0 se x ∈ [0, 127] y = f (x) = 1 se x ∈ [128, 255] produce il bit-plane più significativo di un’immagine rappresentata su 8 bit. In Matlab si ha semplicemente: B7 = x > 127; image(B7); colormap(gray(2)); % 1 se è vera, 0 altrimenti % visualizzazione, tipo dati uint8 Per generare i successivi bit-plane è necessario porre un po’ più di attenzione, perché bisogna introdurre sempre più soglie, a meno che non si effettui un’operazione di riporto dei dati in intervalli di valori via via più piccoli con la funzione rem. Per esempio, per generare il secondo bit-plane basta effettuare il resto modulo 128 dei dati, che lascia inalterati i valori più piccoli di 128, mentre a quelli superiori sottrae 128, a questo punto è possibile usare una sola soglia, che è la metà di quella precedente: x = rem(x,128) B6 = x > 63; image(B6); colormap(gray(2)); % visualizzazione, tipo dati uint8 Una soluzione più veloce ed elegante si ottiene utilizzando le operazioni di resto modulo 2 e di divisione 1 Operazioni aritmetiche 2 intera, rispettivamente (cioè rem e floor). Infatti, notate come l’operazione di resto modulo 2 permetta di determinare il bit-plane 0: B0 = rem(x,2); % 1 se il valore è dispari, 0 altrimenti image(B0+1); colormap(gray(2)); % visualizzazione, tipo dati double Più in generale, se consideriamo la rappresentazione in binario dei livelli di luminanza, la divisione intera per 2(i−1) equivale ad uno shift right di i − 1 posizioni. Prendendo il resto modulo 2, se ne ricava il bit meno significativo, cioè l’i-esimo bit (da destra) del valore originale. Quindi per geneare B1 si ha: B1 = rem(floor(x/2),2); image(B1+1); colormap(gray(2)); % visualizzazione, tipo dati double Infine, esistono operazioni in Matlab che consentono di lavorare direttamente sui bit che rappresentano i livelli di grigio, per cui il codice risulta ancora più efficiente. La funzione che vi permette di adottare questa soluzione è bitget, usate l’help in linea di Matlab per comprendere come si utilizza. 1.1 Esercizi proposti 1. Estrazione dei bit-plane. Scrivete uno script dal nome bit plane.m in cui generate e visualizzate tutti i bit-plane dell’immagine usando una delle procedure descritte e poi confrontate i risultati con quelli che ottenete con la funzione bitget. N.B. Potete memorizzare i bit-plane in una struttura tridimensionale in cui Bi = bitplane(:,:,i). 2. Ricostruzione mediante bit-plane. Dopo aver generato i bit-plane potete provare a ricostruire l’immagine ponendo a zero i bit-plane meno significativi (forma grezza di compressione) e visualizzare il risultato, al variare del numero di bit-plane che utilizzate nel processo di ricostruzione. Questo esperimento vi permette di stabilire fino a che punto (almeno da un punto di vista percettivo) è possibile diminuire il numero di livelli usati nel processo quantizzazione. 3. Esempio di Watermarking. Provate adesso a realizzare una forma molto semplice di Watermarking, che consiste nell’inserire una firma digitale all’interno di un’immagine. Sostituite il bit-plane meno significativo dell’immagine lena.y con l’immagine binaria marchio.y, quest’ultima ha dimensioni 350×350 quindi è necessario estrarre una sezione delle stesse dimensioni dell’immagine lena.y. Provate poi a ricostruire l’immagine e visualizzatela, noterete che da un punto di vista visivo l’immagine non ha subito modifiche percettibili. 2 Operazioni aritmetiche Le operazioni aritmetiche (somma/sottrazione, prodotto/divisione) coinvolgono una o più immagini e si effettuano pixel per pixel. In matlab sono molto semplici da realizzare, dato che è possibile effettuare queste operazioni direttamente sulle matrici. In particolare, fare la sottrazione tra due immagini vi permette di scoprire le differenze che esistono tra le due. Provate allora a visualizzare l’immagine di fig.3.13, e quella in cui sono stati posti a zero i 4 bit-plane meno significativi. Noterete come da un punto di vista visivo sono molto simili, fatene allora la differenza e visualizzatela a schermo. Elaborazione dei Segnali Multimediali a.a. 2009-2010 Operazioni geometriche 3 3 Operazioni geometriche Le operazioni geometriche consentono di ottenere, a partire da un’immagine x una nuova immagine y nella quale i valori di luminosità sono gli stessi, ma sono prelevati in posizioni diverse da quelle originali, in modo da cambiare solo la forma degli oggetti. 3.1 Ridimensionamento Rimpicciolire un’immagine (zoom in) di un fattore intero è estremamente semplice da realizzare in matlab. Supponiamo per esempio di volerla dimezzare, allora: [M,N]=size(x); y=x(1:2:M,1:2:N); % decimazione per 2 lungo le due dimensioni image(y); colormap(gray(256)); % visualizzazione Questa operazione ci permette di modificare la risoluzione spaziale dell’immagine e consiste di fatto nell’abbassare (in numerico) la frequenza di campionamento del segnale. Se¡volessimo ¢ invece rimpicciolirla di un fattore non intero, realizzando per esempio la trasformazione y(m, n) = x 32 m, 23 n bisogna fare più attenzione ¡ ¢ perchè occorre assegnare correttamente i valori di intensità in uscita, come per esempio y(1, 1) = x 23 , 23 ; quest’ultimo valore non è definito nell’immagine in ingresso per cui bisogna determinarlo mediante interpolazione usando la funzione interp2. La sintassi di questa funzione è y=interp2(n,m,x,np,mp,metodo); dove n e m rappresentano le coordinate della griglia su cui è definita l’immagine di partenza x, np e mp sono invece le coordinate dei valori che vogliamo determinare e metodo è il tipo di interpolazione. Con l’opzione nearest si effettua un’interpolazione nearest neighbor, mentre con linear di tipo bilineare. Nel nostro caso: [M,N] = size(x); [n,m] = meshgrid(1:N,1:M); [np,mp] = meshgrid(1:3/2:N,1:3/2:M); y = interp2(n,m,x,np,mp,’linear’); image(y); axis image; colormap(gray(256)); La funzione meshgrid di Matlab permette facilmente di creare la matrice in cui in ogni posizione ci sono le coordinate spaziali, in particolare n è una matrice M × N che contiene il valore della coordinata spaziale lungo la direzione verticale, m analogamente conterrà i valori lungo la direzione orizzontale. Attenzione, i comandi meshgrid e interp2 interpretano le coordinate come ascisse e ordinate non come righe e colonne. Ecco perché bisogna invertire l’ordine di m e n: infatti l’indice di riga, comportando uno spostamento verticale equivale all’ordinata (viceversa per l’indice di colonna). Nel toolbox image è presente la funzione imresize che permette di effettuare il ridimensionamento di un’immagine. Per esempio se si vuole rimpicciolire l’immagine di un fattore 0.75 con interpolazione bilineare: y = imresize(x, 0.75, ’bilinear’); image(y); axis image; colormap(gray(256)); Elaborazione dei Segnali Multimediali a.a. 2009-2010 Operazioni geometriche 4 Chiaramente si può anche ingrandire l’immagine se il fattore scelto è maggiore di 1; inoltre, anziché specificare tale fattore si possono fissare le dimensioni che deve avere la nuova immagine (se però non si fa attenzione a conservare il rapporto d’aspetto, si crea distorsione nell’immagine). 3.2 Traslazioni e rotazioni Proviamo a realizzare la traslazione di un’immagine. Anche in questo caso possiamo scrivere il codice definendo le griglie e usando interp2. In particolare, se vogliamo traslare verso sinistra e verso l’alto l’immagine considerata, il codice è: [M,N] = size(x); [n,m] = meshgrid(1:N,1:M); mp = m+50; np = n+50; y = interp2(n,m,x,np,mp,’linear’); subplot(1,2,1); imshow(x,[]); subplot(1,2,2); imshow(y,[]); In Matlab è possibile effettuare una trasformazione geometrica affine specificando direttamente la matrice di trasformazione T attraverso il comando maketform. Per esempio se volessimo effettuare la rotazione di un’immagine: T = [cos(pi/4) sin(pi/4) 0; -sin(pi/4) cos(pi/4) 0; 0 0 1]; tform = maketform(’affine’,T); y = imtransform(x, tform); subplot(1,2,1); imshow(x,[]); subplot(1,2,2); imshow(y,[]); Confrontate questo risultato con quello che ottereste direttamente con la funzione imrotate. 3.3 Esercizi proposti 1. Zoom in. Scrivete il codice per realizzare l’ingrandimento di una zona di un’immagine usando la matrice T. La sezione da ingrandire, di 100 × 150 pixel, è intorno all’occhio di lena (N.B. Per ritagliare correttamente la sezione e quindi avere informazioni sulla posizione dei pixel potete usare il comando impixelinfo o pixval in base alla versione di Matlab più o meno recente che avete). Fate degli esperimenti modificando il tipo di interpolazione e notate l’effetto di blocchettatura causato dall’interpolazione con opzione ’nearest’ rispetto a ’bilinear’ e ’bicubic’. 2. Distorsione. Scrivete la funzione che realizza la distorsione di un’immagine lungo la direzione verticale e orizzontale e che abbia il prototipo: function y=deforma(x,c,d). Scegliete un’immagine e al variare dei parametri c e d osservate il tipo di distorsione. 3. Combinazione di operazioni geometriche. La combinazione di diverse trasformazioni affini è ancora una trasformazione affine, che può essere ottenuta tramite il prodotto (matriciale) delle matrici che le definiscono. Scrivete allora una funzione dal prototipo function y=rot shear(x,theta,c) per realizzare una rotazione e poi una distorsione verticale (attenzione all’ordine!). Create l’immagine di ingresso usando il seguente comando x = checkerboard(50); in modo da generare una scacchiera su cui le modifiche risultano essere più facilmente visibili. Elaborazione dei Segnali Multimediali a.a. 2009-2010 Filtraggio spaziale 4 5 Filtraggio spaziale Il filtraggio spaziale calcola la correlazione tra un’immagine e una finestra scorrevole (maschera) per valutare l’uscita, operazione che corrisponde di fatto ad una convoluzione (quindi ad un filtraggio) se la maschera scelta è simmetrica. In base alla scelta dei coefficienti della maschera, l’immagine può essere una versione “blurred” (sfocata) di quella originaria, in tal caso si parla di filtri di smoothing, se invece si enfatizzano i dettagli contenuti in un’immagine i filtri si dicono di sharpening. Di seguito esamineremo anche un esempio di filtro non lineare (filtro mediano) particolarmente adatto al filtraggio di immagini affette da rumore impulsivo. 4.1 Filtri di smoothing I filtri di smoothing realizzano una media pesata dei pixel dell’immagine producendo un’immagine in cui vengono ridotte le transizioni tra i livelli di grigio (si attenuano le discontinuità tra gli oggetti). Quando tutti i coefficienti della maschera sono uguali tra loro e pari proprio all’inverso delle dimensioni della maschera, il valore in uscita non è altro che una media aritmetica dei pixel appartenenti alla finestra. Esaminiamo adesso l’effetto di un filtro che realizza la media aritmetica dei pixel appartenenti ad una finestra 3 × 3 per l’immagine Fig3.35(a).jpg, scrivendo il corrispondente codice in Matlab: x=double(imread(’Fig3.35(a).jpg’)); k=3; h=ones(k)/k^2; y=filter2(h,x); imagesc(y); colormap(gray(256)); axis image; La funzione filter2 realizza la correlazione bidimensionale tra l’immagine e la maschera del filtro e di default produce in uscita un’immagine delle stesse dimensioni di quella in ingresso. Ai bordi dell’immagine, dove la maschera del filtro ha bisogno per l’elaborazione anche dei valori dei pixel non appartenenti all’immagine, questi vengono assunti per default pari a zero (zero-padding). Per questo motivo si crea una distorsione ai bordi nell’immagine elaborata, che tipicamente si presenta come una cornice scura che circonda l’immagine, tanto più grande quanto più è grande la dimensione della maschera. Utilizzando l’opzione ’valid’ è possibile ottenere in uscita solo i valori elaborati dal filtro per cui la maschera si sovrappone perfettamente all’immagine (ovviamente l’uscita avrà dimensioni minori di quella in ingresso): y=filter2(h,x,’valid’); In altrnativa è possibile usare il comando conv2, che effettua proprio la convoluzione bidimensionale, ovviamente sarà necessario ribaltare la maschera del filtro (a meno che non sia simmetrica): h=fliplr(h); h=flipud(h); y=conv2(x,h); Si tenga presente però che l’immagine in uscita adesso ha dimensioni maggiori di quella in ingresso. In particolare, dette M × N le dimensioni dell’immagine e A × B quelle del filtro, l’immagine in uscita avrà dimensioni M + A − 1 × N + B − 1. Tuttavia il comando conv2 può fornire anche un’immagine delle stesse dimensioni di quella in ingresso se si aggiunge l’opzione ’same’, in tal caso si preleva la parte centrale dell’immagine. Di seguito considereremo spesso maschere simmetriche per cui è possibile confondere l’operazione di correlazione con quella di convoluzione. Elaborazione dei Segnali Multimediali a.a. 2009-2010 Filtraggio spaziale 6 Infine Il pacchetto image di Matlab mette a disposizione anche il comando imfilter, che di default ha lo stesso comportamento di filter2: y=imfilter(x,h); Oltre alle opzioni già previste per i comandi visti precedentemente, imfilter dà la possibilità di usare un’opzione che modifica i valori dell’immagine all’esterno dei bordi. In particolare, è possibile estendere simmetricamente i valori dei pixel con l’opzione ’symmetric’, replicarli semplicemente (’replicate’) oppure rendere il segnale periodico con l’opzione ’circular’. Provate ad aumentare la dimensione del filtro che realizza la media aritmetica per k = 5, 9, 15, 35 e verificate, usando i comandi whos oppure size che le dimensioni di y siano quelle attese quando tale variabile è prodotta con i comandi filter2 e conv2 con le diverse possibili scelte ’same’ ’valid’ o ’full’. Provate, infine, a vedere cosa succede ai bordi dell’immagine usando il comando imfilter con le diverse opzioni di estensione ai bordi (per quest’ultimo esperimento usate l’immagine lena.jpg). Per filtrare un’immagine può essere molto utile usare il comando fspecial, che permette di creare un determinato tipo di filtro bidimensionale. Per esempio, se si vuole creare un filtro media aritmetica di dimensioni 3 × 3, basta scrivere: h = fspecial(’average’, [3 3]) Diversi sono i filtri che si possono specificare, usate l’help in linea per avere maggiori informazioni. 4.1.1 Esercizi proposti 1. Denoising. Aggiungete del rumore gaussiano bianco ad un immagine x con il comando: noisy = x + n con n = d*randn(size(x)) dove d è la deviazione standard del rumore. Effettuate il denoising dell’immagine con i filtri a media mobile (al variare della dimensione della finestra). Valutate l’efficacia del filtraggio sia visivamente, sia calcolando l’errore quadratico medio tra x e l’immagine “ripulita”, che rappresenta una misura quantitativa per stabilire quanto l’immagine elaborata sia simile all’originale. L’MSE (Mean Squared Error) tra due immagini si definisce come: M −1 N −1 1 X X MSE = |x(m, n) − y(m, n)|2 M N m=0 n=0 2. Smoothing seguito da thresholding. Un’importante applicazione dei filtri che realizzano la media spaziale è quello di sfocare l’immagine in modo da confondere con lo sfondo oggetti piccoli di poco interesse ed enfatizzare oggetti più grandi, che quindi possono essere facilmente rilevati. Consideriamo, ad esempio, l’immagine Fig.3.36(a).jpg, proveniente dal telescopio Hubble, in orbita intorno alla terra. Realizzate le seguenti operazioni: (a) visualizzate l’immagine; (b) applicate il filtro che effettua la media aritmetica su una finestra di dimensioni 15×15 e visualizzate il risultato; (c) realizzate un’operazione a soglia (thresholding ) per eliminare oggetti piccoli, in particolare considerate una soglia pari al 25 per cento del valore massimo presente nell’immagine filtrata; (d) visualizzate il risultato dell’elaborazione. Elaborazione dei Segnali Multimediali a.a. 2009-2010 Filtraggio spaziale 7 Noterete che la scelta della dimensione della maschera deve essere confrontabile con gli oggetti che si vogliono trascurare, provate a modificarne la dimensione e valutatene gli effetti, variando anche la soglia opportunamente. 4.2 Filtri di sharpening Obiettivo dei filtri di sharpening è quello di evidenziare o enfatizzare i dettagli di un’immagine. A tal fine si utilizzano operazioni che coinvolgono derivazioni del primo e secondo ordine in termini di differenze tra i valori dei pixel di un’immagine. Proviamo a realizzare l’enhancement dell’immagine Fig3.40(a).jpg con un filtro Laplaciano la cui maschera è: 0 h(m, n) = 1 0 1 -4 1 0 1 0 Scrivete il codice Matlab per calcolare il laplaciano di un’immagine, e visualizzate il risultato. Il calcolo del Laplaciano può essere usato per enfatizzare i dettagli in un’immagine, se si effettua la seguente operazione: y(m, n) = x(m, n) − ∇2 x(m, n) Provate allora a visualizzare l’immagine y(m, n) e confrontatela con quella originale. Questa stessa operazione si può realizzare equivalentemente nel seguente modo: h=[0 -1 0; -1 5 -1; 0 -1 0]; z=filter2(h,x); Utilizzate adesso la seguente maschera del filtro, che porta in conto anche le variazioni lungo le direzioni oblique: h=[1 1 1; 1 -8 1; 1 1 1]; Che differenze notate rispetto all’elaborazione precedente? 4.3 Filtraggio non lineare Il filtro mediano realizza un’operazione non lineare sui pixel appartenenti alla maschera: i valori vengono ordinati e poi calcolato il valore che si trova nella posizione centrale dell’ordinamento (valore mediano). Questo filtro è in grado di rimuovere molto efficacemente il rumore impulsivo salt-and-pepper, un tipo di disturbo caratterizzato dal fatto che alcuni pixel dell’immagine diventano bianchi o neri. Consideriamo per esempio l’immagine a raggi X di un circuito distorta da questo tipo di rumore, Fig.3.37(a).jpg. Se la maschera ha dimensioni 5 × 5, il filtro mediano può essere realizzato usando la funzione median nel seguente modo: x = double(imread(’Fig3.37(a).jpg’)); y = nlfilter(x,[5 5],’median(x(:))’) subplot(1,2,1); imshow(x,[]); subplot(1,2,2); imshow(y,[]); La funzione nlfilter realizza l’operazione specificata attraverso una finestra scorrevole su tutta l’immagine. Può risultare piuttosto lenta per cui se l’elaborazione può anche essere realizzata sul blocco vettorizzato si può usare la seguente soluzione: y = colfilt(x,[5 5],’sliding’,@median); Elaborazione dei Segnali Multimediali a.a. 2009-2010 Filtraggio spaziale 8 Usando i comandi tic e toc, cronometrate il tempo di esecuzione delle due elaborazioni. Tenete presente comunque che il toolbox image fornisce la funzione medfilt2 per realizzare il filtraggio mediano di un’immagine. 4.3.1 Esercizi proposti 1. Rumore sale e pepe. Scegliete un’immagine, quindi aggiungete rumore sale e pepe (usate il comando imnoise di matlab), applicate il filtro mediano e valutate il risultato sia visivamente sia tramite l’errore quadratico medio se la dimensione della finestra è 5, 7, 9. 2. Filtri max e min. Confrontate l’effetto del filtro mediano e di quelli che forniscono in uscita il massimo (max filter) e il minimo (min filter) su immagini corrotte da rumore sale e pepe, usando finestre delle stesse dimensioni. 3. Elaborazioni locali. Matlab permette in modo abbastanza semplice di elaborare solo una regione dell’immagine mediante il comando roipoly, in particolare con il mouse è possibile definire i vertici del poligono della sezione da estrarre. La maschera binaria relativa viene memorizzata automaticamente nella variabile mask (uscita di roipoly): mask = roipoly(x); imshow(mask); A questo punto si può filtrare solo la regione selezionata con una determinata maschera h: y = roifilt2(h,x,mask); imshow(y); Scegliete un’immagine, provate a selezionarne una regione e a realizzare un’operazione di enhancement che ne migliori il contrasto, per esempio usando il lapalciano. Elaborazione dei Segnali Multimediali a.a. 2009-2010