MATLAB中的快速傅里叶变换FFT与IFFT

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013220518/article/details/79846229

背景
FFT (Fast Fourier Transform)是离散傅立叶变换的快速算法,可以将一个信号从时域变换到频域。同时与之对应的是IFFT(Inverse Fast Fourier Transform)离散傅立叶反变换的快速算法。为掌握FFT和IFFT在MATLAB中的应用,我们需要了解FFT的基本原理。

MATLAB应用及原理

X = fft(x,N);
x = ifft(X, N);

其中 x 为离散的时域信号, N 为采样点数, X 为离散的频域信号。这里我们假定采样频率为 F s ,信号频率 F

1)为便于计算, N 一般取大于信号长度的2的整数次方,当 N 大于信号长度时,FFT将取零补齐。采样频率 F s N 1 个点平均分成 N 等份,每个点的频率依次增加,对于第 n 点所表示的频率为: F n = ( n 1 ) F s / N 。因此其频率分辨率为 F s / N ,可见采样频率和采样点数决定频率分辨率。

2) X 的长度为 N ,同时关于 N 2 点对称。基于离散傅里叶变换的表达式,我们知道FFT得到的第一点频率为0,即为直流分量,其幅值为实际直流分量的 N 倍。而 X 后面的为复数,其幅值为实际的 N / 2 倍。因此为得到实际的幅值,我们需要除以一定的系数。

理想实例

Fs = 8; % 采样频率
Ts = 1 / Fs; % 采样时间间隔
L = 32; % length of signal
t = (0 : (L - 1)) * Ts; % discrete time
x = 2 + 3 * cos(2 * pi * 1 * t - 30 * pi / 180); % original signal

N = 2 ^ nextpow2(L); % 采样点数
X = fft(x, N); 
f = Fs / N * (0 : (N - 1)); % 频率
x_hat = ifft(X, N);
subplot(311)
stem(t, x);
title('original signal'),xlabel('time'),ylabel('amplitude')

subplot(312)
X(1) = X(1) / 2;
stem(f, abs(X / N * 2));
title('amplitude spectrum'),xlabel('frequency'),ylabel('amplitude')

subplot(313)
stem(t, x_hat);
title('recovered signal'),xlabel('time'),ylabel('amplitude')

仿真结果

频谱泄露
在上图中,当频率小于4 Hz时,信号仅在0 Hz和1 Hz有值,这表明信号含有0 Hz和1 Hz成分。但如果采样时间不是信号周期的整数倍时,信号将会在其它频率也有值,这种现象叫频谱泄露,同时,越靠近真实频谱的频率幅值越大。

Fs = 8; % 采样频率
Ts = 1 / Fs; % 采样时间间隔
L = 32; % length of signal
t = (0 : (L - 1)) * Ts; % discrete time
x = 2 + 3 * cos(2 * pi * 0.9 * t - 30 * pi / 180); % original signal

N = 2 ^ nextpow2(L); % 采样点数
X = fft(x, N); 
f = Fs / N * (0 : (N - 1)); % 频率
x_hat = ifft(X, N);
subplot(211)
stem(t, x);
title('original signal'),xlabel('time'),ylabel('amplitude')

subplot(212)
X(1) = X(1) / 2;
stem(f, abs(X / N * 2));
title('amplitude spectrum'),xlabel('frequency'),ylabel('amplitude')

仿真结果

猜你喜欢

转载自blog.csdn.net/u013220518/article/details/79846229