2017-03-18 1 views
1

Récemment, j'apprends DM_Script pour le traitement d'images TEM je avais besoin processus de flou gaussien et j'ai trouvé celui dont le nom est « flou gaussien » dans http://www.dmscripting.com/recent_updates.htmlScript DM, pourquoi la transformée de Fourier des besoins gaussienne-Kenel module

Ce code implémente l'algorithme de flou gaussien en multipliant la transformée de Fourier rapide (FFT) de l'image source par la FFT de l'image du noyau gaussien et en effectuant finalement la transformée de Fourier inverse de celle-ci.

Voici la partie du code,

// Carry out the convolution in Fourier space 

compleximage fftkernelimg:=realFFT(kernelimg) (-> FFT of Gaussian-kernel image) 
compleximage FFTSource:=realfft(warpimg) (-> FFT of source image) 
compleximage FFTProduct:=FFTSource*fftkernelimg.modulus().sqrt() 
realimage invFFT:=realIFFT(FFTProduct) 

Le point que je veux poser est compleximage FFTProduct:. = FFTSource * fftkernelimg.modulus() sqrt()

Pourquoi la FFT de Gaussian-noyau besoin '.modulus(). Sqrt()' pour la convolution?

Cela est-il lié au fait que la transformée de Fourier d'une fonction gaussienne devient une autre fonction gaussienne? Ou est-ce lié à une sorte de limitation de la transformée de Fourier discrète?

S'il vous plaît me répondre Merci

Répondre

0

Ceci est lié à la limitation générale de précision de tout calcul numérique à virgule flottante. (Voir f 0., ou plus en profondeur here)

Un gaussien de rotation (valeur réelle) de stand.dev. sigma devrait être transformé en un Gaussioan rotatif à 100% de valeurs réelles de 1/sigma. Toutefois, cette numériquement va vous montrer les écarts: Il suffit de procédez comme suit:

number sigma = 30 
number A0 = 1 
realimage first := RealImage("First", 8, 256, 256) 
first = A0 * exp(- (iradius**2/(2*sigma*sigma))) 
first.showimage() 
complexImage second := FFT(first) 
second.Showimage() 

image nonZeroImaginaryMask = (0 != second.Imaginary()) 
nonZeroImaginaryMask.Showimage() 
nonZeroImaginaryMask.SetLimits(0,1) 

Lorsque vous multipliez ensuite ces images complexes (avant en arrière-transfert) vous introduisons encore plus d'erreurs. En utilisant le module, on s'assure que le noyau transformé vers l'avant est purement réel et donc une meilleure courbe "d'amortissement".

Une meilleure implémentation d'un code de filtrage FFT créerait en fait la FFT (gaussienne) directement avec un std.dev de 1/sigma, car c'est le résultat analytiquement correct. Faire une FFT du noyau n'a de sens que si le noyau (ou sa FFT) n'est pas analytiquement connu.

En général: Lors de l'implémentation de n'importe quel "maths" dans un code de programme, il peut être très coûteux d'y réfléchir avec des limites de calcul numérique à l'arrière de la tête. Réduire le calcul réel chaque fois que c'est possible (c'est-à-dire calculer analytiquement et utiliser le résultat au lieu de compter sur le calcul numérique par force brute) et essayer de "remodeler" les équations lorsque cela est possible, f.e. évitez les grosses sommes sur beaucoup de petits nombres, faites attention aux contrôles par rapport aux valeurs numériques exactes, évitez les expressions qui sont très sensibles aux petites erreurs numériques, etc.