
- f(x,y):图像二维数组(时域) ; F(u,v) 图像DFT变换生成的二维数组(频域)
- 维度数N已知,时域里图像矩阵x(i,j)(对应f)已知,目标输出变换后的图像频域矩阵Z(m,n)(对应F)
code:
<pre><code>
dft.py(对应第一个公式)
from future import division
from future import print_function
import numpy as np
def dft2(x): '''
:param x: 待分析数据,二数数组。
:return Z: 原始数据的DFT结果。
'''
N = 256
Z = np.zeros((N,N))
for m in range(N):
for n in range(N):
for i in range(N):
for j in range(N): #四层循环,先从最里层考虑,最开始先访问谁
Z[m,n] = x[i,j]*np.exp((-2)*np.pi*1J*(m*i+n*j)/N)/N
return Z
</code></pre> main.py
<pre><code> from future import division from future import print_function
import numpy as np import matplotlib.pyplot as plt from dft import dft2
if name == 'main': N = 256 # 图片尺寸 x = np.arange(N, dtype=np.float32) y = np.arange(N, dtype=np.float32)
R = 10
theta = np.pi/6 # 角度可以自己修改
u = R * np.cos(theta)
v = R * np.sin(theta)
Z = np.zeros((x.size, y.size))
for i_x in range(x.size):
for i_y in range(y.size):
Z[i_x, i_y] = np.cos(np.pi / N * (u * x[i_x] + v * y[i_y]))
Z_dft = dft2(Z) # 调用DFT
Z_dft_shift = abs(np.fft.fftshift(Z_dft)) # 将图像中的低频部分移动到图像的中心
plt.subplot(221)
plt.imshow(Z, cmap='gray')
plt.title('Original')
plt.axis('off')
plt.subplot(222)
plt.imshow(abs(Z_dft), cmap='gray') # 展示DFT结果
plt.title('DFT2')
plt.axis('off')
plt.subplot(223)
plt.imshow(Z_dft_shift, cmap='gray') # 展示移动低频到中心后的图像
plt.title('shift')
plt.axis('off')
plt.subplot(224)
plt.plot(Z_dft_shift[x.size//2, :]) # 取一行查看数值,位置可以自己定义
plt.title('x = {}'.format(x.size//2))
plt.show()
</code></pre>
TIPs:
- 循环层数 == 时间复杂度的幂数(可以相互做判据), 如dft.py里,先访问二维矩阵x的i、j(做256✖️256次操作),时间复杂度O(N^2),再访问并赋值给二维矩阵Z的m、n(再做256✖️256次操作),时间复杂度变成O(N^4),所以要写四层循环
- 循环顺序,先从最里层开始考虑哪个先迭代,先行后列
- 矩阵角度理解DFT 感觉不一定对,仅供思路提示
注意python和numpy里切片不一样,自带的list不能x[i,j],只能x[i][j],numpy里的array可以- 调试时,如果图像数据过大,可以resize图像维度debug(见eigenface的code)