MATLAB中FFT函数的幅值转换问题

一、快速傅里叶变换

1.语法

Y = fft(X)
Y = fft(X,n)
Y = fft(X,n,dim)

2.说明

(1)Y = fft(X)

使用快速傅里叶变换 (FFT) 算法计算 X 的离散傅里叶变换 (DFT)。Y 与 X 的大小相同。
如果 X 是向量,则 fft(X) 返回该向量的傅里叶变换。
如果 X 是矩阵,则 fft(X) 将 X 的各列视为向量,并返回每列的傅里叶变换。
如果 X 是一个多维数组,则 fft(X) 将沿大小不等于 1 的第一个数组维度的值视为向量,并返回每个向量的傅里叶变换。

(2)Y = fft(X,n)

返回 n 点 DFT。
如果 X 是向量且 X 的长度小于 n,则为 X 补上尾零以达到长度 n。
如果 X 是向量且 X 的长度大于 n,则对 X 进行截断以达到长度 n。
如果 X 是矩阵,则每列的处理与在向量情况下相同。
如果 X 为多维数组,则大小不等于 1 的第一个数组维度的处理与在向量情况下相同。

(3)Y = fft(X,n,dim)

返回沿维度 dim 的傅里叶变换。例如,如果 X 是矩阵,则 fft(X,n,2) 返回每行的 n 点傅里叶变换

二、实数信号的FFT

1.采样点为偶数的情况

(1)单边谱

经过FFT之后的频率对应的幅值并不是真实的幅值,想要将FFT之后的频谱图跟实际的幅值对应,就要进行相应的转换。频率序号为0和 N 2 \frac{N}{2} 2N的两个点的带宽只占中间频率点的一半,也就是占 1 N \frac{1}{N} N1的带宽,因此只需要将幅值乘以 1 N \frac{1}{N} N1即可。
代码如下:

% DrawRealFFT:绘制实数信号的FFT
% N为偶数(最好为2的整数次方)
function [MagY,f] = DrawRealFFT(RealData, fs)
N = length(RealData);
fft_RealData = fft(RealData);
MagY = abs(fft_RealData(1:N/2+1));
MagY(1)=MagY(1)/N;                % 频率为0的位置除以N
MagY(end)=MagY(end)/N;            % 频率为Fs/2的位置也除以N
MagY(2:end-1)=2*MagY(2:end-1)/N;  % 其余频率点乘以2/N
f = (0:N/2)'*fs/N;
plot(f,MagY);
grid on;
xlabel('f(Hz)'), ylabel('幅度');
end

(2)双边谱

代码如下:

function [f,MagY] = DrawRealBilateralSpectrum(RealxData,fs)
N = length(RealxData);
Fs = fs;
f = Fs/N*(-N/2:N/2-1) ;
MagY = abs(fftshift(fft(RealxData)))*1/N;
plot(f,MagY);
xlabel('Frequency'); 
ylabel('Amplitude'); 
end

2.采样点为奇数的情况

(1)单边谱

当我们的样本点N为奇数时,只有0频率占 1 N \frac{1}{N} N1带宽,其余的 N + 1 2 \frac{N+1}{2} 2N+1个频率点仍然是对应幅值乘以 2 N \frac{2}{N} N2得到真实的幅值。
代码如下:

% DrawRealFFT:绘制实数信号的FFT
% N为偶数(最好为2的整数次方)
function [MagY,f] = DrawRealFFT(RealData, fs)
N = length(RealData);
fft_RealData = fft(RealData);
MagY = abs(fft_RealData(1:N/2+1));
MagY(1)=MagY(1)/N;                % 频率为0的位置除以N
MagY(2:end)=2*MagY(2:end)/N;  % 其余频率点乘以2/N
f = (0:N/2)'*fs/N;
plot(f,MagY);
grid on;
xlabel('f(Hz)'), ylabel('幅度');
end

(2)双边谱

代码如下:

function [f,MagY] = DrawRealBilateralSpectrum(RealxData,fs)
N = length(RealxData);
Fs = fs;
f = Fs/N*(-N/2:N/2-1) ;
MagY = abs(fftshift(fft(RealxData)))*1/N;
plot(f,MagY);
xlabel('Frequency'); 
ylabel('Amplitude'); 
end

三、复数信号的FFT

1.单边谱

对于复数信号,N个点FFT之后会产生N个频率点,频谱的带宽为N,每个点所占的带宽为 1 N \frac{1}{N} N1 ,将每个幅值都乘以 1 N \frac{1}{N} N1即可得到真实的频率幅值。
代码如下:

% DrawComplexFFT:绘制复数信号的FFT
% 对于复数信号,N个点FFT之后会产生N个频率点,频谱的带宽为N,每个点所占的带宽为1/N
% 将每个幅值都乘以1/N即可得到真实的频率幅值
function [MagY,f] = DrawComplexFFT(ComplexData, fs)
N = length(ComplexData);
fft_ComplexData = fft(ComplexData);
MagY = abs(fft_ComplexData(1:N/2+1))*1/N;
f = (0:N/2)'*fs/N;
plot(f,MagY);
grid on;
xlabel('f(Hz)'), ylabel('幅度');
end

2.双边谱

代码如下:

function [f,MagY] = DrawComplexBilateralSpectrum(ComplexData,fs)
N = length(ComplexData);
Fs = fs;
f = Fs/N*(-N/2:N/2-1) ;
MagY = abs(fftshift(fft(ComplexData)))*1/N;
plot(f,MagY);
xlabel('Frequency'); 
ylabel('Amplitude'); 
end

四、示例

1.实验代码

clear;clc;
close all;
Fs=1000; % 采集频率
T=1/Fs; % 采集时间间隔
N=2000; % 采集信号的长度--采样点数
f1=33; % 第一个余弦信号的频率
f2=200; % 第二个余弦信号的频率
f3=500; % 第二个余弦信号的频率
t=(0:1:N-1)*T; % 定义整个采集时间点
t=t'; % 转置成列向量
ComplexY = 1.2+2.7*exp(1j*2*pi*f1*t)+5*exp(1j*2*pi*f2*t)+4*exp(1j*2*pi*f3*t);      % 复数时域信号
DoubleY = 1.2+2.7*cos(2*pi*f1*t+pi/4)+5*cos(2*pi*f2*t+pi/6)+4*cos(2*pi*f3*t+pi/3); % 实数时域信号
figure(1);
DrawComplexFFT(ComplexY,Fs);
figure(2);
DrawComplexBilateralSpectrum(ComplexY,Fs);
figure(3);
DrawRealFFT(DoubleY,Fs);
figure(4);
DrawRealBilateralSpectrum(DoubleY,Fs);

2.实验结果

如图所示,复数信号的双边谱不是对称的。画图时,单边谱的横坐标为f = (0:N/2)'fs/N,即频率从0到 F s 2 \frac{F_{s}}{2} 2Fs,所以对于单边谱来说,频率为500(即 F s 2 \frac{F_{s}}{2} 2Fs)的谱线出现在频率为500处。双边谱的横坐标为Fs/N(-N/2:N/2-1),即频率从 − F s 2 -\frac{F_{s}}{2} 2Fs F s 2 − F s N \frac{F_{s}}{2}-\frac{F_{s}}{N} 2FsNFs,在本例中即-500Hz~499.5Hz,所以对于双边谱来说,频率为500(即 F s 2 \frac{F_{s}}{2} 2Fs)的谱线出现在频率为-500处。
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值