傅立叶如何变换1和0的数组

时间:2019-10-10 12:31:30

标签: python arrays numpy fft

我正在尝试使用Python进行傅立叶变换,将0的矩阵转换为带有1的实心圆(如针孔)。我正在尝试获取通风函数的图像,该图像看起来应该像是从上方看的同心圆波纹。我对Python和更一般的编码仍然还是一个初学者。

import numpy as np
dimension = 256

list1 = []
listpiece = []

for i in range(dimension):
    for j in range(dimension):
        listpiece.append(0)
    list1.append(listpiece)
    listpiece = []

k=128
for i in range(dimension):
    for j in range(dimension):
        if (i-k)*(i-k) + (j-k)*(j-k) <= 64*2:
            list1[i][j] = 1

import matplotlib.pylab as plt
import scipy.sparse as sparse

plt.spy(list1)
plt.show()

哪个给了这张图片of a black circle on a white background。 然后,我将此列表转换为numpy数组。

singledimlist = []
for i in range(dimension):
    for j in range(dimension):
        singledimlist.append(list1[i][j])

prefourierline = np.array( singledimlist )
shape = ( dimension, dimension )
prefourier = prefourierline.reshape( shape )
print(prefourier)
plt.spy(prefourier)
plt.show()

哪个给出了相同的图像:

使用np.fft.fft2可以得到空白图像,即使输出变化很大:

from scipy.fftpack import fft, ifft
fouriered = np.fft.fft2(prefourier)
plt.spy(fouriered)
plt.show()

输出:

[[ 405.        +0.00000000e+00j -401.08038516-1.50697234e-16j
   389.47420686-2.31615451e-15j ... -370.63201656-5.88988318e-15j
   389.47420686+2.35778788e-15j -401.08038516+8.95615360e-15j]
 [-401.08038516-2.27306384e-15j  397.18553235-1.77932604e-15j
  -385.65292606-1.63119926e-15j ...  366.93100304+7.84568423e-15j
  -385.65292606-2.13934425e-15j  397.18553235-1.08069809e-14j]
 [ 389.47420686+8.66313300e-15j -385.65292606-1.67296339e-14j
   374.33891021+6.30297134e-15j ... -355.97430091-1.40810576e-14j
   374.33891021+1.25700186e-14j -385.65292606-1.24588719e-14j]
 ...
 [-370.63201656-4.69963986e-14j  366.93100304+4.87944288e-14j
  -355.97430091-4.69561772e-14j ...  338.1937218 +3.81585557e-14j
  -355.97430091-4.67444422e-14j  366.93100304+3.64531853e-14j]
 [ 389.47420686+3.34933421e-14j -385.65292606-2.70693599e-14j
   374.33891021+3.08443590e-14j ... -355.97430091-3.30709228e-14j
   374.33891021+2.07603249e-14j -385.65292606-2.63513116e-14j]
 [-401.08038516-5.83528175e-14j  397.18553235+7.09535468e-14j
  -385.65292606-5.72142574e-14j ...  366.93100304+7.01916155e-14j
  -385.65292606-6.12008707e-14j  397.18553235+6.47498390e-14j]]

因此,我尝试使用np.fft.fft,但效果要好一些,不是空白图像,而是输出宽度与原始圆的半径相同的黑色水平条纹,将白色背景一分为二。

from scipy.fftpack import fft, ifft
fouriered = np.fft.fft(prefourier)
plt.spy(fouriered)
plt.show()

我怀疑主要问题出在电脑屏幕和椅子之间。

我的问题是,我在做什么错?一个傅立叶如何变换这种数组?

谢谢,感谢您的帮助,

ES

1 个答案:

答案 0 :(得分:1)

有很多事情,所以我只是提供了一个使用numpy的工作示例。零和一的问题也不是问题,因为那些也是合法的浮点数,因此物理原理很好。在输出中找到正确答案有两个问题。一种是放大,或者使圆变小。试一试,并从封闭式解决方案(Airy-Function)中计算出预期的戒指尺寸。 另一个是对比。下面我只是使用日志来更好地可视化。替代方法是扎根。另外请注意,我并未将结果平方(正如物理学所表明的,即强度与电场)。

import matplotlib.pyplot as p 
import numpy as np

n=1000
aa=np.ones((n,n))
x=np.linspace(-1,1,n)  
y=np.linspace(-1,1,n)
X,Y= np.meshgrid(x,y)    #this allows us to use vectorized approach, no for loops
R = np.sqrt(X**2+Y**2)


aa[R<0.1]=0


p.figure(figsize=(20,6))
p.subplot(131)
p.imshow(aa)
p.colorbar()

p.subplot(132)
spec= np.fft.fftshift(np.fft.fft2(aa)) 
p.imshow( np.log(np.abs(spec)))
p.colorbar() 
p.title('airy func too fine to see')

p.subplot(133)

p.imshow(  np.log(np.abs(spec[450:550,450:550])))
p.colorbar()
p.title('zoomed in');

enter image description here