2015-12-17 8 views
5

Sto usando un algoritmo di convoluzione diretta per calcolare la convoluzione tra questa immagine:Artefatti in circonvoluzione

enter image description here

e questo kernel:

enter image description here

Sto usando l'attuazione in astropy per la convoluzione diretta.

Il risultato è il seguente circonvoluzione, lasciando tutte le impostazioni (comprese la gestione di confine) ai valori di default, vale a dire astropy.convolution.convolve (immagine, kernel):

enter image description here

Questa convoluzione ha alcuni manufatti sconcertanti . In particolare, esiste un modello "quadrato" con un offset di circa 50 pixel dal bordo. Mi sembra che ciò sia dovuto all'entità del kernel; anche se il kernel ha dimensioni formalmente 249x249, la maggior parte delle informazioni è chiaramente contenuta in un raggio di circa 100 pixel - il che significa che presumibilmente incontriamo problemi quando il kernel viene applicato ai bordi.

che mi porta alle mie domande:

  1. È questa ipotesi corretta - che è davvero un problema di bordo?
  2. Come potrei risolvere? Non so come giustificare l'utilizzo di diversi edge-handling (zero padding, interpolation, wrapping, ...) Sono sicuro che casi diversi richiedono soluzioni diverse, ma non sono sicuro su come decidere su questo ...
  3. Solo ... cercando di capire la differenza tra l'utilizzo di un algoritmo diretto e una convoluzione FFT. Se il kernel e l'immagine sono ugualmente grandi, non è necessario alcun padding zero per la convoluzione FT, non verranno visualizzati effetti di bordo. Per il metodo diretto, inavvertitamente avrai un po 'di gestione dei bordi ... quindi ci sono risultati anche equivalenti? Perché in linea di principio solo le loro prestazioni dovrebbero differire, giusto?

risposta

7

Sì, questo è un problema di bordo che si verifica perché si hanno valori negativi nel proprio kernel. Non appena il kernel è parzialmente fuori dal bordo, il valore medio del kernel inizia a cambiare.

Una soluzione sarebbe utilizzare boundary='fill' e fill_value=(mean of your image) o qualcosa del genere. Potrebbe non rimuovere completamente questi artefatti, ma dovrebbe ridurli.

Per la convoluzione FFT della tua domanda, la convoluzione FFT farà la stessa cosa. Tuttavia, l'imbottitura dei bordi è necessaria per la convoluzione FFT, perché altrimenti il ​​contorno si avvolgerà. Non il padding (ad es., convolve_fft(..., boundary='wrap')) in realtà eliminerà i tuoi artefatti, ma lo farà in un modo che potrebbe sorprenderti, dal momento che calcolerà la media dei pixel dal lato destro dell'immagine con il lato sinistro.

di astropy convolve e convolve_fft sia farà la stessa cosa a parità boundary condizioni, ma la convoluzione FFT naive (cioè conv = ifft(fft(im) * fft(kernel))) è equivalente a usando boundary='wrap'.

Problemi correlati