2015-11-29 37 views
5

Ecco alcuni codice che ho scritto per visualizzare lo spettro grandezza di un'immagine:Perché ottengo un'immagine vuota come output?

orig_imdata = imread('Original_Image.png'); 
spec_orig = fft2(double(orig_imdata)); 
spec_orig2 = abs(spec_orig); 
spec_img = fftshift(spec_orig2); 
imshow(spec_img); 

Quando io commento l'uso di abs e proprio fftshift l'immagine, ottengo un'immagine, anche se con la fase e l'ampiezza. Se applico la funzione abs subito dopo aver usato fftshift, ottengo un risultato vuoto da imshow. Ho bisogno di un'immagine della grandezza dell'analisi spettrale della mia immagine.

Qualcuno sa cosa sta andando male qui?

risposta

7

L'immagine non è "vuota". imshow è progettato in modo che qualsiasi valore di precisione double inferiore a 0 venga visualizzato come nero e qualsiasi valore maggiore di 1 sia visualizzato come bianco. Quando si calcolano i componenti di magnitudine dell'immagine, si producono immagini di precisione double nel codice.

Pertanto, ho il forte sospetto che poiché la maggior parte dei componenti (se non è tutti) sono maggiori di 1, questo ti dà una visualizzazione di un'immagine completamente bianca e quindi "vuota". Ora che abbiamo riscontrato il problema, tuttavia sei not out of the woods yet. Semplicemente ridimensionare i componenti in modo che rientrino nell'intervallo [0,1] non sarà di aiuto neanche. Se lo fai, il componente DC dello spettro di magnitudo sarà probabilmente così grande da sovrascrivere il resto dei componenti di magnitudo nell'immagine. Pertanto, vedrai solo un punto bianco nel mezzo e il resto dell'immagine sarà nero.

Una pratica comune è quello di applicare un'operazione log allo spettro grandezza per la visualizzazione, quindi ridimensionamento dei valori in modo che si inseriscono nella gamma di [0,1]:

%// Your code 
orig_imdata = imread('Original_Image.png'); 
spec_orig = fft2(double(orig_imdata)); 
spec_orig2 = abs(spec_orig); 
spec_img = fftshift(spec_orig2); 

%// New code 
spec_img_log = log(1 + spec_img); 
imshow(spec_img_log,[]); 

Nell'operazione log, l'enorme gamma dinamica di valori viene compresso in un intervallo più piccolo, specialmente quando i valori diventano più grandi e, quindi, il ridimensionamento naturale a [0,1] di questo intervallo compresso offre risultati visivi migliori.

Il motivo per cui si aggiunge 1 a ogni componente, quindi prendere il log è quello di evitare l'operazione log(0). Se i componenti di qualsiasi grandezza sono pari a zero, questo verrà valutato a log(1), che diventerà 0. Una volta fatto, è possibile utilizzare imshow(...,[]) per ridimensionare il display in modo che il componente di magnitudine più piccolo vada a 0 mentre il componente di magnitudine più grande va a 1 del Spettro log. Prendi nota che ho fatto non modificare lo spettro originale in modo da poter eseguire l'elaborazione su quello. Inoltre, il riscalamento eseguito da imshow viene eseguito completamente internamente alla chiamata. Non ridimensiona i dati in alcun modo - lo fa solo per la visualizzazione e basta.


Dai un'occhiata e guarda come va.

+0

bene la soluzione funziona, e una volta superato quello che devo fare, tornerò indietro e leggerò attentamente perché funzioni. Risposta incredibilmente ben dettagliata! complimenti! –

+0

@SharanDuggirala Ho aggiunto più modifiche dal momento che accetti:) ... soprattutto come funziona questo ridimensionamento. Prego. In bocca al lupo! A proposito, dare un'occhiata al paragrafo in particolare dopo il codice. Ti dice perché funziona. – rayryeng

+0

Suppongo, sarò in grado di chiarire eventuali ulteriori domande su questa risposta in seguito? Grazie ancora per questa risposta! –