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

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

MATLAB应用及原理

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

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

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

2) X X 的长度为 N N ,同时关于 N2 N 2 点对称。基于离散傅里叶变换的表达式,我们知道FFT得到的第一点频率为0,即为直流分量,其幅值为实际直流分量的 N N 倍。而 X X 后面的为复数,其幅值为实际的 N/2 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')

MATLAB中的快速傅里叶变换FFT与IFFT_第1张图片

频谱泄露
在上图中,当频率小于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')

MATLAB中的快速傅里叶变换FFT与IFFT_第2张图片

你可能感兴趣的:(信号处理基础)