被fft相位谱迷惑了!

信息处理 fft matlab 阶段
2022-01-08 14:40:48

一个非常简单的 MATLAB 实验:

f = 200;  
fs = 1000;  
t = 0: 1/fs : 1;
x = cos(2*pi*f*t);  
plot(angle(fftshift(fft(x))));  

这是输出: 在此处输入图像描述

现在,对上面的代码片段做了一个小的改动;仅将持续时间减少 1 个样本,如下所示:

f = 200;  
fs = 1000;  
t = 0: 1/fs : 1 - 1/fs;
x = cos(2*pi*f*t);  
plot(angle(fftshift(fft(x)))); 

相位谱变得非常疯狂:

在此处输入图像描述

问题:

  1. 在第一个图中,我希望看到 bin 700 处的零相位对应于本例中的正频率 200。情况似乎并非如此。其次,我不理解图 1 中图形的线性部分。我确实很欣赏由于所谓的数值噪声而可能存在的相位分量,但是那个噪声怎么可能在相位上如此“线性”呢?

  2. 在第二个图中,为什么只删除一个样本会对相位图产生如此巨大的影响?

  3. 我在这里做一些根本错误的事情吗?

3个回答

你没有做错任何事,但你也没有仔细考虑你应该看到什么,这就是为什么你对结果感到惊讶。对于问题1,您的猜想很接近,但实际上您的情况倒退了;困扰您的第二个的是数字噪音,而不是您的第一个。

图片可能会有所帮助。这是第一次试验的幅度和相位图:

x = Cos[2.0 \[Pi] 200 Range[0, 1, 1/1000]];
fx = Fourier[x];
ListLinePlot[Abs[fx], PlotRange -> All]
ListLinePlot[Arg[fx], PlotRange -> All]

在此处输入图像描述

在此处输入图像描述

第二个:

x = Cos[2.0 \[Pi] 200 Range[0, 1 - 1/1000, 1/1000]];
fx = Fourier[x];
ListLinePlot[Abs[fx], PlotRange -> All]
ListLinePlot[Arg[fx], PlotRange -> All]

在此处输入图像描述

在此处输入图像描述

那么这里发生了什么?第二个最容易解释。首先,第二个 FFT 的幅度为零,除了幅度谱中可见的两个峰值;这是因为使用 1,000 个数据点的 FFT 定义形式的频率,因此您的信号恰好落在频率箱上。结果,在其他 998 个点上,您的信号完全是由于浮点误差引起的机器噪声,因此您的相位谱是无意义的,因为它实际上是伪随机数的相位。k/10000k999

但是,对于第一个,FFT 的定义包含形式的频率,而您的信号频率是,而不是的形式。结果,您的信号会因频谱泄漏而变宽,并且几乎在所有地方都是非零的。我不会评论相位图的物理形式,但我会说它承认一个封闭的分析形式。k/10010k1000200/1000k/1001

总的来说,我认为单独的相位角图对于传达信息来说是一个非常糟糕的主意,正是因为这个原因。首先,您无法判断您查看的是低幅度垃圾的相位还是实际信号的相位,其次,它不是平移不变的,对于简单的输入,很容易得到完全令人眼花缭乱的图表。更好的是,如果您仍在寻找传达相位信息的东西,那么是一个以相同的视觉方式同时描绘相位和幅度信息的图形,例如相位被编码为色调和幅度被编码为亮度的图。

附录:这是来自 Mathematica 的几张图片,它们说明了我在上一段中所述的原理:

hue = Compile[{{z, _Complex}}, {(1.0 Arg[-z] + \[Pi])/(2 \[Pi]), 
Exp[1 - Max[Abs[z], 1]], Min[Abs[z], 1]}, 
CompilationTarget -> "C", RuntimeAttributes -> {Listable}];
L = 500;
data = Table[Boole[x <= 11 && y <= 11], {x, L}, {y, L}];
Image[hue@
RotateRight[
10 RotateRight[Fourier[RotateRight[data, {-5, -5}]], {L/2, L/2}]], 
ColorSpace -> Hue, Magnification -> 1]
Image[hue@
RotateRight[
10 RotateRight[Fourier[RotateRight[data, {-4, -4}]], {L/2, L/2}]], 
ColorSpace -> Hue, Magnification -> 1]
Image[hue@
RotateRight[
10 RotateRight[Fourier[RotateRight[data, {0, 0}]], {L/2, L/2}]], 
ColorSpace -> Hue, Magnification -> 1]

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

所有三幅图像都是相同输入信号的 2D 傅里叶变换(平方用零填充到的长度),但输入已经循环旋转了 5、4 和 0,并且200 个数据点。幅度谱(由像素亮度编码)是相同的,但相位谱完全不同!完成相位编码,以便 1 映射到红色,映射到绿色,映射到青色,11×11500×500i1i映射为紫色。当我说相位谱是非位移不变的,因此不适合人类视觉理解时,这就是我的意思。例如,对于 200 个数据点的循环移位,完全无法判断相位中发生了什么,因为它看起来像静态的,但输入信号并不比其他输入情况复杂。

如果您想改变信号的频率或 FFT 长度,以便信号在 FFT 孔径中完全周期性和非完全周期性之间变化,并且不希望看到该信号变化的峰值幅度箱的相位,如果 FFT 孔径而不是开头,则可以将信号的初始相位参考到中心(对于生成的 sin(t),将 t=0 放在 FFT 阵列的中心)。

Gaussian Waves 网站详细介绍了相位及其类似随机行为的部分:正如 DumpsterDoofus 所说,只是浮点错误的问题