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