创建绘制FFT幅度时如何设置频率轴的混淆

时间:2016-03-07 18:48:56

标签: matlab signal-processing fft

该代码对信号进行FFT处理,并将其绘制在新的频率轴上。

f=600;
Fs=6000;
t=0:1/Fs:0.3;
n=0:1:length(t);
x=cos(2*pi*(400/Fs)*n)+2*sin(2*pi*(1100/Fs)*n);
y=fft(x,512);

freqaxis=Fs*(linspace(-0.5,0.5, length(y)));
subplot(211)
plot(freqaxis,fftshift(abs(y)));

我理解为什么我们使用fftshift,因为我们希望看到信号以0 Hz(DC)值为中心,并且更适合观察。

enter image description here

但是我似乎对如何定义频率轴感到困惑。具体来说,为什么我们特别将[-0.5 0.5]的范围乘以Fs,我们得到[-3000 3000]范围?它可能是[-0.25 0.25]

1 个答案:

答案 0 :(得分:3)

范围介于[-Fs/2,Fs/2]之间的原因是因为Fs/2Nyquist frequency。这是最大可能的频率,具有可视化的能力以及频率分解中最终存在的频率。我也不同意你的评论范围"可能介于[-0.25,0.25]"之间。这与奈奎斯特频率的定义相反。

根据信号处理理论,我们知道必须至少采样信号带宽的两倍才能正确地重建信号。带宽定义为信号中可见的最大可能频率分量,也称为奈奎斯特频率。换句话说:

Fs = 2*BW

我们可以将频谱可视化以及最终带宽/奈奎斯特频率的上限定义为:

BW = Fs / 2; 

因此,由于您的采样频率为6000 Hz,这意味着奈奎斯特频率为3000 Hz,因此可视化范围为[-3000,3000] Hz,这在您的幅度图中是正确的。

顺便说一下,每个频率的bin中心都不正确。您在FFT中指定了二进制位的总数为512,但指定二进制位的方式与信号的总长度有关。我很惊讶为什么你没有得到语法错误,因为fft函数的输出应该给你512分,你的频率轴变量将是一个大于512的数组。情况,这是不正确的。每个bin i的频率应该是:

f = i * Fs / N, for i = 0, 1, 2, ..., N-1

N是您在FFT中的总点数,即512.您最初将其作为length(y)并且这不正确...所以这可能就是为什么你有一个检查频率轴时的混淆源。您可以通过在此处引用用户Paul R的精彩帖子来了解这种情况的原因:How do I obtain the frequencies of each value in an FFT?

请注意,我们只指定从0到N-1的分档。为了在指定每个频率的分箱中心时考虑到这一点,通常在{{1}中指定附加点命令并删除最后一点:

linspace
顺便说一下,您宣布freqaxis=Fs*(linspace(-0.5,0.5, 513); %// Change freqaxis(end) = []; %// Change 的方式对我来说有点模糊。这对我来说更具可读性:

freqaxis

我个人讨厌使用freqaxis = linspace(-Fs/2, Fs/2, 513); freqaxis(end) = []; 而我更喜欢length

在任何情况下,当我运行更正的代码来指定bin中心时,我现在得到这个图。请注意,我插入了多个数据光标,其中光谱的峰值对应于您声明的每个余弦的频率(400 Hz和1100 Hz):

enter image description here

您会发现存在一些轻微的不准确之处,主要是由于您指定的垃圾箱数量(即512)。如果增加了总箱数,您将看到每个峰值的频率将更准确。