Python 二维傅里叶变换:FFT与傅里叶光学

Python 二维傅里叶变换:FFT与傅里叶光学,python,scipy,fft,optics,Python,Scipy,Fft,Optics,我试图用编程来增加我对傅里叶光学的理解。我知道傅里叶变换的傅里叶变换在物理上和数学上是倒转的->F{F{F(x)}=F(-x)。我有两个问题1)第二个变换除了在简单的高斯情况下(这使得它更加混乱)外,不会返回任何与原始函数类似的东西,和2)似乎有一些比例因子要求我“放大”并扭曲变换后的图像,使其变得毫无帮助(如下所示)。**根据@Cris Luengo的建议编辑 在与Cris交谈后,似乎没有缩放因子,这种DFT就是这样工作的。因此我找到的解决方案是将像素增加到可以放大并有足够清晰的图像的程度。

我试图用编程来增加我对傅里叶光学的理解。我知道傅里叶变换的傅里叶变换在物理上和数学上是倒转的->F{F{F(x)}=F(-x)。我有两个问题1)第二个变换除了在简单的高斯情况下(这使得它更加混乱)外,不会返回任何与原始函数类似的东西,和2)似乎有一些比例因子要求我“放大”并扭曲变换后的图像,使其变得毫无帮助(如下所示)。**根据@Cris Luengo的建议编辑


在与Cris交谈后,似乎没有缩放因子,这种DFT就是这样工作的。因此我找到的解决方案是将像素增加到可以放大并有足够清晰的图像的程度。这不是一个很好的解决方案,但与
光管
配合使用,现在可以了解光模式的变换看起来像,并且说明在透镜系统的像面上,它们会像在前焦场中一样出现

#%% Playing with 2d Fourier Transform

import numpy as np
import matplotlib.pyplot as plt
import LightPipes
from scipy.fftpack import fft2 as fft
from numpy.fft import fftshift, ifftshift

wavelength = 792*nm
size = 100*mm
N = 1000
w0=3*mm

# Fields
sq = np.zeros([100,100])
sq[25:75, 25:75] = 1
F=Begin(size,wavelength,N)
I0 = Intensity(0,GaussBeam(F, w0, LG=True, n=0, m=0))
I1 = Intensity(0,GaussBeam(F, w0, LG=False, n=0, m=1))+Intensity(0,GaussBeam(F, w0, LG=False, n=1, m=0))

# Plot transforms
f = sq
F = fftshift(fft(ifftshift(f)))
F_F = fftshift(fft(ifftshift(F)))

plt.subplot(331), plt.imshow(f,cmap = cmap)
plt.title(r'f'), plt.xticks([]), plt.yticks([])
plt.subplot(332), plt.imshow(np.abs(F),cmap = cmap)
plt.title(r'F\{f\}'), plt.xticks([]), plt.yticks([])
plt.subplot(333), plt.imshow(np.abs(F_F),cmap = cmap)
plt.title('F\{F\{f\}\}'), plt.xticks([]), plt.yticks([])

f = I0
F = fftshift(fft(ifftshift(f)))
F_F = fftshift(fft(ifftshift(F)))

plt.subplot(334), plt.imshow(f[450:550,450:550],cmap = cmap)
plt.title(r'f'), plt.xticks([]), plt.yticks([])
plt.subplot(335), plt.imshow(np.abs(F)[450:550,450:550],cmap = cmap)
plt.title(r'F\{f\}'), plt.xticks([]), plt.yticks([])
plt.subplot(336), plt.imshow(np.abs(F_F)[450:550,450:550],cmap = cmap)
plt.title('F\{F\{f\}\}'), plt.xticks([]), plt.yticks([])

f = I1
F = fftshift(fft(ifftshift(f)))
F_F = fftshift(fft(ifftshift(F)))

plt.subplot(337), plt.imshow(f[450:550,450:550],cmap = cmap)
plt.title(r'f'), plt.xticks([]), plt.yticks([])
plt.subplot(338), plt.imshow(np.abs(F)[450:550,450:550],cmap = cmap)
plt.title(r'F\{f\}'), plt.xticks([]), plt.yticks([])
plt.subplot(339), plt.imshow(np.abs(F_F)[450:550,450:550],cmap = cmap)
plt.title('F\{F\{f\}\}'), plt.xticks([]), plt.yticks([])

plt.tight_layout()
plt.show()

在与Cris聊天后,似乎没有缩放因子,这种DFT就是这样工作的。因此我找到的解决方案是将像素增加到可以放大并有足够清晰的图像的程度。这不是一个很好的解决方案,但与
光管
相结合,现在可以了解光模式的变换看起来像,并且说明在透镜系统的像面上,它们会像在前焦场中一样出现

#%% Playing with 2d Fourier Transform

import numpy as np
import matplotlib.pyplot as plt
import LightPipes
from scipy.fftpack import fft2 as fft
from numpy.fft import fftshift, ifftshift

wavelength = 792*nm
size = 100*mm
N = 1000
w0=3*mm

# Fields
sq = np.zeros([100,100])
sq[25:75, 25:75] = 1
F=Begin(size,wavelength,N)
I0 = Intensity(0,GaussBeam(F, w0, LG=True, n=0, m=0))
I1 = Intensity(0,GaussBeam(F, w0, LG=False, n=0, m=1))+Intensity(0,GaussBeam(F, w0, LG=False, n=1, m=0))

# Plot transforms
f = sq
F = fftshift(fft(ifftshift(f)))
F_F = fftshift(fft(ifftshift(F)))

plt.subplot(331), plt.imshow(f,cmap = cmap)
plt.title(r'f'), plt.xticks([]), plt.yticks([])
plt.subplot(332), plt.imshow(np.abs(F),cmap = cmap)
plt.title(r'F\{f\}'), plt.xticks([]), plt.yticks([])
plt.subplot(333), plt.imshow(np.abs(F_F),cmap = cmap)
plt.title('F\{F\{f\}\}'), plt.xticks([]), plt.yticks([])

f = I0
F = fftshift(fft(ifftshift(f)))
F_F = fftshift(fft(ifftshift(F)))

plt.subplot(334), plt.imshow(f[450:550,450:550],cmap = cmap)
plt.title(r'f'), plt.xticks([]), plt.yticks([])
plt.subplot(335), plt.imshow(np.abs(F)[450:550,450:550],cmap = cmap)
plt.title(r'F\{f\}'), plt.xticks([]), plt.yticks([])
plt.subplot(336), plt.imshow(np.abs(F_F)[450:550,450:550],cmap = cmap)
plt.title('F\{F\{f\}\}'), plt.xticks([]), plt.yticks([])

f = I1
F = fftshift(fft(ifftshift(f)))
F_F = fftshift(fft(ifftshift(F)))

plt.subplot(337), plt.imshow(f[450:550,450:550],cmap = cmap)
plt.title(r'f'), plt.xticks([]), plt.yticks([])
plt.subplot(338), plt.imshow(np.abs(F)[450:550,450:550],cmap = cmap)
plt.title(r'F\{f\}'), plt.xticks([]), plt.yticks([])
plt.subplot(339), plt.imshow(np.abs(F_F)[450:550,450:550],cmap = cmap)
plt.title('F\{F\{f\}\}'), plt.xticks([]), plt.yticks([])

plt.tight_layout()
plt.show()

如果您删除对
fftshift
abs
的调用,事情应该正常运行。
I0
I1
是什么?您的代码中需要这么多冗余来说明您的问题吗?@Cris Luengo很抱歉,我在为此制作的演示中发现了一个错误,并意外删除了显示
I0和
I1
是。我相信
FFT移位
对于正确地重新排列象限是必要的。标准的一点是将高频放在边缘?而
np.abs
是必要的,因为
fft2
的结果是复杂的。我试图礼貌地暗示我是在不需要的情况下尝试过的gin with.
abs
就是因为这个问题而存在的。在stackoverflow
TypeError上找到了对它的更正:dtype complex128的图像数据无法转换为float
该移位来自于FFT的youtube描述。在发现小(10x10)时使用正方形时,强度位于错误的拐角处。它们必须移动。@CrisLuengo这是促使我尝试添加
np的答案。abs
fftshift
是从左上角移动原点(DFT/FFT期望的位置)到我们喜欢看到它的中心。仅当您想显示FFT结果时才使用它。
abs
丢弃DFT的相位,破坏您的数据。它会导致所有正弦分量在原点对齐,导致每个结果中出现特征性的单峰。
FFT(FFT(f))
将产生您期望的结果。它不完全是
f(-x)
因为我们处理的是离散傅立叶变换,而不是普通的傅立叶变换。如果您删除对
fftshift
abs
的调用,事情应该会正常工作。什么是
I0
I1
?您的代码中需要这么多冗余来说明您的问题吗?@Cris Luengo抱歉,我在演示中发现了一个错误我做了这个,不小心删除了我的图片,上面显示了
I0
I1
是什么。我相信
fftshift
对于正确地重新排列象限是必要的。关于标准的一点是把高频放在边缘?而
np.abs
是必要的,因为
fft2
I的结果s复杂。我试图礼貌地建议我一开始就尝试过。abs的出现是因为这个问题。在stackoverflow
TypeError上可以找到它的更正:dtype complex128的图像数据不能转换为float
这个移位来自youtube对FFT的描述。找到这个问题后当使用一个小的(10x10)正方形时,强度在角上,这是错误的。它们必须被移动。@CrisLuengo这是促使我尝试添加
np的答案。abs
fftshift
是从左上角移动原点(DFT/FFT期望的位置)到我们喜欢看到它的中心。仅当您想显示FFT结果时才使用它。
abs
丢弃DFT的相位,破坏您的数据。它会导致所有正弦分量在原点对齐,导致每个结果中出现特征性的单峰。
FFT(FFT(f))
将产生您期望的结果。它不完全是
f(-x)
,因为我们处理的是离散傅立叶变换,而不是普通的傅立叶变换。