首先明确一下,我们这里考虑的二维数组的形式,因为我们主要的学习目标是图像处理。
1. 偶数的情况
我们类比于一维中的情况,DFT中一个周期的对称中心是 M / 2 M/2 M/2,如果 M M M 恰好是一个偶数,那么 M / 2 M/2 M/2 会是一个具体的点,如果 M / 2 M/2 M/2 是一个奇数,则显然对称中心不存在某一个具体的点,它在两点之间。为了简单起见,我们现在只考虑 M M M 恰好是一个偶数的情况。
二维的情况其实很简单,将输入的数据乘 ( − 1 ) x + y (-1)^{x+y} (−1)x+y,那么频谱就会位移 M / 2 M/2 M/2 和 N / 2 N/2 N/2。
f ( x , y ) ( − 1 ) x + y ⇔ F ( u − M / 2 , v − N / 2 ) f(x, y)(-1)^{x+y} \Leftrightarrow F(u-M / 2, v-N / 2) f(x,y)(−1)x+y⇔F(u−M/2,v−N/2)
MATLAB为我们提供了一个函数来实现这个功能,而不用我们自己来对输入的 M × N M\times N M×N 的 data array 做处理。我们来观察一下。
array =[1,2,3,4;
5,6,7,8;
9,10,11,12;
13,14,15,16];
fft_array=fft2(array);
fft_array_shifted=fftshift(fft_array);
array_ifft=ifft2(fft_array_shifted)
array_ifft =
1 -2 3 -4
-5 6 -7 8
9 -10 11 -12
-13 14 -15 16
完美符合要求,证明了对于偶数大小的矩阵来说,fftshift
确实成功实现了中心化,也就是对频谱位移了
M
/
2
M/2
M/2 和
N
/
2
N/2
N/2。
2. 奇数的情况
那对于奇数大小的矩阵呢?我们来验证一下。
array =[1,2,3;
4,5,6;
7,8,9];
fft_array=fft2(array);
fft_array_shifted=fftshift(fft_array);
array_ifft=ifft2(fft_array_shifted)
array_ifft =
1.0000 + 0.0000i -1.0000 + 1.7321i -1.5000 - 2.5981i
-2.0000 + 3.4641i -2.5000 - 4.3301i 6.0000 + 0.0000i
-3.5000 - 6.0622i 8.0000 + 0.0000i -4.5000 + 7.7942i
很遗憾,对于奇数大小矩阵似乎无法正确实现频谱位移的功能。这是可以理解的,因为位移的点是整数,想要将频谱位移 M / 2 M/2 M/2 在 M M M 是奇数的情况下显然是无法实现的。实际上从一维度,我们可以更方便的理解这一点:
对于一维离散DFT,我们知道有
f
(
x
)
e
j
2
π
(
u
0
x
/
M
)
⇔
F
(
u
−
u
0
)
f(x) e^{j 2 \pi\left(u_{0} x / M\right)} \Leftrightarrow F\left(u-u_{0}\right)
f(x)ej2π(u0x/M)⇔F(u−u0)
fftshift
对频谱的位移效果,会导致
u
0
u_{0}
u0 不是一个整数,那么如果
u
0
u_0
u0 不是个整数会发生什么?
array=[1,2,3];
array_fft=fft(array)
array=[1,-2,3];
array_fft_another=fft(array)
array_fft =
6.0000 + 0.0000i -1.5000 + 0.8660i -1.5000 - 0.8660i
array_fft_another =
2.0000 + 0.0000i 0.5000 + 4.3301i 0.5000 - 4.3301i
事实上,他是连续形式傅里叶变化位移之后的直接抽样。上面的二维情况是同理。