理解Matlab FFT示例

50
我是新手,对matlab和FFT不熟悉,想要理解Matlab FFT example。目前有两个主要问题:
1)为什么x轴(频率)在500处结束?我怎么知道没有更多的频率或者它们被忽略了吗?
2)我怎么知道频率在0到500之间?难道FFT不应该告诉我频率的范围吗?FFT只返回幅度值而不是频率吗?
感谢任何提示!

问题示例:

考虑以1000 Hz采样的数据。形成一个包含振幅为0.7的50 Hz正弦波和振幅为1的120 Hz正弦波的信号,并用一些零均值随机噪声进行干扰:

Fs = 1000;                    % Sampling frequency
T = 1/Fs;                     % Sample time
L = 1000;                     % Length of signal
t = (0:L-1)*T;                % Time vector
% Sum of a 50 Hz sinusoid and a 120 Hz sinusoid
x = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t); 
y = x + 2*randn(size(t));     % Sinusoids plus noise
plot(Fs*t(1:50),y(1:50))
title('Signal Corrupted with Zero-Mean Random Noise')
xlabel('time (milliseconds)')

time domain

将信号y转换为频域,通过快速傅里叶变换(FFT)可得到噪声信号y的离散傅里叶变换。
NFFT = 2^nextpow2(L); % Next power of 2 from length of y
Y = fft(y,NFFT)/L;
f = Fs/2*linspace(0,1,NFFT/2+1);

% Plot single-sided amplitude spectrum.
plot(f,2*abs(Y(1:NFFT/2+1))) 
title('Single-Sided Amplitude Spectrum of y(t)')
xlabel('Frequency (Hz)')
ylabel('|Y(f)|')

frequency domain


2
使用离散傅里叶变换,您将不会看到高于采样频率一半的任何内容。作为经验法则,您应该将采样频率设置为所感兴趣频率的大约10倍。 - Dima Chubarov
7
10倍似乎过高,你这个数字是从哪里得到的? - Oliver Charlesworth
你可能会发现我以前的一个答案有用:https://dev59.com/OGHVa4cB1Zd3GeqPnYGC#9699983 - learnvst
4个回答

40

1) 为什么x轴(频率)以500结束?我怎么知道没有更多的频率或者它们被忽略了吗?

它以500Hz结束,因为当以1000Hz采样时,那是信号的奈奎斯特频率。看一下Mathworks示例中的这行:

f = Fs/2*linspace(0,1,NFFT/2+1);

第二个图的频率轴从0到Fs/2,即采样频率的一半。奈奎斯特频率始终是采样频率的一半,因为在其上方会发生混叠Aliasing illustration

信号将“折叠”回本身,并看起来是某个低于或等于500Hz的频率。

2)我怎么知道频率在0到500之间? FFT不应该告诉我频率在哪个范围内吗?

由于上面描述的“折叠”(奈奎斯特频率也常被称为“折叠频率”),高于500Hz的频率在FFT中物理上不可能出现;更高的频率将“折叠”并显示为较低的频率。

FFT只返回幅度值而没有频率吗?

是的,MATLAB FFT函数只返回一个幅度向量。但是,它们映射到您传递给它的频率点。

请告诉我哪些地方需要澄清,这样我才能更好地帮助你。


不,那是指模拟电路的带宽,而不是所需的采样率。欠采样不是抗混叠滤波器的解决方法,我想你可能想到了过采样... - Oliver Charlesworth
2
非常感谢你们所有人的回复!它们都很有帮助,很难选择一个作为正确答案,但我认为这是最清晰的答案。谢谢! - stefan.at.kotlin

10

这里有一些误解。

大于500的频率可以在长度为1000的FFT结果中表示。不幸的是,这些频率都被折叠在一起并混合到前500个FFT结果中。因此,通常不应该将包含采样率一半或更高频率的信号馈送给FFT,因为FFT对此不关心,并且只会将高频和低频混合在一起(混叠),从而使结果几乎没有用处。这就是为什么数据在被采样和馈送到FFT之前应该被低通滤波的原因。

FFT返回的是振幅而非频率,因为频率不仅取决于FFT的长度,还取决于数据的采样率,这不是FFT本身或其输入的一部分。您可以以任何采样率馈送相同长度的FFT数据,从而获得任何频率范围。

结果图表结束于500的原因是,对于任何实际数据输入,FFT长度一半以上的频率只是第一半数据的反射重复(共轭复数)。由于它们是重复的,大多数人都会忽略它们。为什么要绘制重复项呢?FFT计算结果的另一半是为那些馈送FFT复杂数据(具有实部和虚部)的人计算的,这确实创建了两个不同的半区间。


谢谢您提供的提示,关于FFT结果长度为1000时500以上频率的问题。我这里有一篇论文,使用了5000赫兹的采样率,2048个样本输入进行FFT分析,并分析了300到2000赫兹。您能否解释一下如何使用有效的FFT结果向量长度为1024(2048/2,因为镜像)来分析2000赫兹的范围? - stefan.at.kotlin
我已经详细陈述了我的问题,并包含了一篇文章的链接:http://dsp.stackexchange.com/questions/2648/analysing-2500-frequencies-using-fft-with-an-input-vector-of-2048-samples 如果你能够看一下,那就太好了 :-) - stefan.at.kotlin

1

听起来你需要了解一些关于FFT(例如,http://en.wikipedia.org/wiki/FFT)的背景知识。但是为了回答你的问题:

为什么x轴(频率)在500时截止?

因为输入向量的长度为1000。通常情况下,长度为N的输入波形的FFT将导致长度为N的输出向量。如果输入波形是实数,则输出将是对称的,因此前501个点是足够的。

编辑:(我没有注意到示例填充了时域向量。)

频率到500 Hz是因为时域波形声明具有1 kHz的采样率。奈奎斯特采样定理规定,采样率为fs的信号可以支持最大带宽为fs / 2的(实)信号。

如何知道频率在0和500之间?

见上文。

“FFT不应该告诉我频率的范围吗?”
“不会。”
“FFT只返回幅度值而没有频率吗?”
“FFT只是为每个频率桶分配幅度(和相位)。”

FFT的输入向量长度不是1000!它是2^nextpow2(L),即1046!当采样数为2的幂时,FFT最有效。此外,0-500是以赫兹为单位,而不是采样数!我的答案正确说明了为什么图形从0Hz到500Hz。 - kevlar1818
@kevlar1818:2^nextpow2(L)是1024,而不是1046。 - 3lectrologos
@3lectrologos 是的,没错。 :( - kevlar1818
FFT 的输入向量长度为 NFFT = 2^nextpow2(L) - kevlar1818
@kevlar1818:你说得对。我没有注意到示例填充了时间域向量。回答已更新! - Oliver Charlesworth

-1
你的X轴只绘制频率到500 Hz的原因是你的命令语句'f = Fs/2*linspace(0,1,NFFT/2+1);'。你的Fs是1000。所以当你将它除以2,然后乘以范围从0到1的值时,它返回一个长度为NFFT/2+1的向量。这个向量包含等间隔的频率值,范围从0到Fs/2(即500 Hz)。由于你使用'plot(f,2*abs(Y(1:NFFT/2+1)))'命令进行绘图,因此你的X轴限制是500 Hz。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接