MATLAB中的fft后为何要用fftshift?

fft是一维傅里叶变换,即将时域信号转换为频域信号
fftshift
是针对频域的,将FFT的DC分量移到频谱中心
即对频域的图像,(假设用一条水平线和一条垂直线将频谱图分成四块)对这四块进行对角线的交换与反对角线的交换

FFTSHIFT Shift zero-frequency component to center of spectrum.
    For vectors, FFTSHIFT(X) swaps(交换) the left and right halves of
    X. For matrices, FFTSHIFT(X) swaps the first and third
    quadrants and the second and fourth quadrants
. For N-D
    arrays, FFTSHIFT(X) swaps "half-spaces" of X along each
    dimension.

    FFTSHIFT(X,DIM) applies the FFTSHIFT operation along the 
    dimension DIM.

    FFTSHIFT is useful for visualizing the Fourier transform with
    the zero-frequency component in the middle of the spectrum.

fftshift就是对换数据的左右两边比如
x=[1 2 3 4]
fftshift(x) ->[3 4 1 2]

IFFTSHIFT Inverse FFT shift.(就是fftshift的逆)

x=[1     2     3     4     5];

y=fftshift(x)

y =

     4     5     1     2     3

ifftshift(y)

ans =

     1     2     3     4     5


   
    IFFTSHIFT undoes the effects of FFTSHIFT.


注意:在使用matlab的fft及fftshift时,应注意。

假定采样频率fs,采样间隔dt,采样点数N。

fft后,频率为(0:N-1)/N/dt

进行fftshift后,频率为

if mod(N,2)==0

n1=(0:N-1)-N/2;

else

n1=(0:N-1)-(N-1)/2;

end

实际上,频率为N点为周期的,所以

(0:N-1)

所以,对于频率0,1,2,3,4,实际上为0,1,2,-2(3-5),-1(4-5)。

fftshift后的频率为

-2,-1,0,1,2

对于二维fftshift,其与直接用下面的结果一样

if mod(tempN,2)==0

    kx=(0:tempM-1)/tempM/dx-tempM/2/tempM/dx;% kx=kx*2*pi

else

    kx=(0:tempM-1)/tempM/dx-(tempM-1)/2/tempM/dx;% kx=kx*2*pi

end

kx=kx*2*pi;

if mod(tempM,2)==0

    ky=(0:tempN-1)/tempN/dy-tempN/2/tempN/dy;% kx=kx*2*pi

else

    ky=(0:tempN-1)/tempN/dy-(tempN-1)/2/tempN/dy;% kx=kx*2*pi

end

ky=ky*2*pi;


temp1=sqrt(kx.^2+ky.^2);

k1=temp1;

[kx,ky]=meshgrid(kx,ky);

如下面程序表明上面两个相同:

dx=50e3;    

dy=50e3;

% % % % % % % % % % % 

tempN=41;

tempM=41;

% % % % % % % % % % % % 

% % % %determining the wavenumber kx and ky

if mod(tempM,2)==0

    kx=(0:tempM-1)-tempM/2;% kx=kx*2*pi

else

    kx=(0:tempM-1)-(tempM-1)/2;% kx=kx*2*pi

end

kx=kx*2*pi/tempM/dx;

if mod(tempN,2)==0

    ky=(0:tempN-1)-tempN/2;% kx=kx*2*pi

else

    ky=(0:tempN-1)-(tempN-1)/2;% kx=kx*2*pi

end

ky=ky*2*pi/tempN/dy;


[kxx,kyy]=meshgrid(kx,ky);

k00=sqrt(kx.^2+ky.^2);


% % % % % % % % % % % % % % % % 

if mod(tempM,2)==0

    temp1=tempM/2-1;

    temp2=(temp1+1):(tempM-1);

    temp2=temp2-tempM;

    temp3=[0:temp1,temp2];

    kx=temp3/tempM/dx;% kx=kx*2*pi

else

    temp1=(tempM-1)/2;

    temp2=(temp1+1):(tempM-1);

    temp2=temp2-tempM;

    temp3=[0:temp1,temp2];

    kx=temp3/tempM/dx;% kx=kx*2*pi

end

kx=kx*2*pi;

if mod(tempN,2)==0

    temp1=tempN/2-1;

    temp2=(temp1+1):(tempN-1);

    temp2=temp2-tempN;

    temp3=[0:temp1,temp2];

    ky=temp3/tempN/dy;% kx=kx*2*pi

else

    temp1=(tempN-1)/2;

    temp2=(temp1+1):(tempN-1);

    temp2=temp2-tempN;

    temp3=[0:temp1,temp2];

    ky=temp3/tempN/dy;% kx=kx*2*pi

end

ky=ky*2*pi;

[kx,ky]=meshgrid(kx,ky);

kx=fftshift(kx);

ky=fftshift(ky);

k=sqrt(kx.^2+ky.^2);

figure

subplot(3,1,1),contourf(kxx-kx)

subplot(3,1,2),contourf(kyy-ky)

subplot(3,1,3),contourf(k00-k)

%%%%%%%%%%%

fft及fftshift示例:

clf;


fs=100;N=256;   %采样频率和数据点数

n=0:N-1;t=n/fs;   %时间序列

x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t); %信号

y1=fft(x,N);    %对信号进行快速Fourier变换

y2=fftshift(y1);

mag1=abs(y1);     %求得Fourier变换后的振幅

mag2=abs(y2);    

f1=n*fs/N;    %频率序列

f2=n*fs/N-fs/2;%这个未必正确

subplot(3,1,1),plot(f1,mag1,'r');   %绘出随频率变化的振幅

xlabel('频率/Hz');

ylabel('振幅');title('图1:usual FFT','color','r');grid on;

subplot(3,1,2),plot(f2,mag1,'b');   %绘出随频率变化的振幅

xlabel('频率/Hz');

ylabel('振幅');title('图2:FFT without fftshift','color','b');grid on;

subplot(3,1,3),plot(f2,mag2,'c');   %绘出随频率变化的振幅

xlabel('频率/Hz');

ylabel('振幅');title('图3:FFT after fftshift','color','c');grid on;

### Matlab 中 `fft` 和 `fftshift` 函数的区别及使用方法 #### 1. 傅里叶变换 (`fft`) 的作用 `fft` 函数用于执行快速傅里叶变换 (Fast Fourier Transform),该算法能够高效地将时域信号转换为频域信号。这意味着输入的时间序列数据被映射成一系列复数,这些复数值代表不同频率下的振幅和相位信息。 对于长度为 N 的离散时间序列 x[n], 其 DFT 定义如下: \[X[k]=\sum_{n=0}^{N-1}{x[n]\cdot e^{-j2πkn/N}} \quad k=0,...,N−1\] 其中 \( j=\sqrt{-1}\), 并且 n 表示样本索引而 k 则对应于各个频率成分[^2]。 ```matlab Fs = 100; % Sampling frequency T = 1/Fs; % Sample time L = 1000; % Length of signal t = (0:L-1)*T; % Time vector f = Fs*(0:(L/2))/L; % Frequency domain % Create a sample sine wave with two frequencies. SineWave = sin(2*pi*50*t)+sin(2*pi*120*t); Y = fft(SineWave); P2 = abs(Y/L); % Two-sided spectrum P2 P1 = P2(1:L/2+1); % Single-sided spectrum P1 P1(2:end-1) = 2*P1(2:end-1); % Double non-DC components. figure; subplot(2,1,1) plot(t,SineWave) title('Time Domain Signal') xlabel('Time / s') ylabel('Amplitude') subplot(2,1,2) plot(f,P1,'r') % Plot single-sided amplitude spectrum. title('Single-Sided Amplitude Spectrum of Sine Wave') xlabel('Frequency / Hz') ylabel('|P1(f)|'); ``` 此代码片段展示了如何创建一个包含两个频率分量的正弦波并对其进行FFT分析,在不应用任何额外处理的情况下绘制原始幅度谱图。 #### 2. 零频移位 (`fftshift`) 功能描述 当利用 `fft` 对实数或复数序列做变换之后,默认情况下得到的结果是以直流偏置项为中心排列的;即低频位于数组两端而非中间位置。这使得解释结果变得困难,尤其是在可视化方面。为了改善这一点,MATLAB 提供了 `fftshift` 来调整输出顺序,使零频率(也称为 DC 组件)处于中心处,从而更直观地展示双侧对称特性[^4]。 具体来说: - 当传入的是矢量时,它会把左半边与右半边互换; - 若是矩阵形式,则涉及四个象限之间的交换——第一同第三、第二配第四; - 处理多维情况同样遵循这一原则,只是扩展到了更高维度上而已。 下面是修改后的绘图命令来显示经过 `fftshift` 调整过后的单边功率谱密度估计值: ```matlab Fshft = (-L/2:L/2-1)*(Fs/L); % Shifted frequency axis Y_shifted = fftshift(Y); % Apply fftshift to the FFT result P2_shifted = abs(Y_shifted)/L; figure; plot(Fshft, fftshift(P2)) % Use fftshift on magnitude before plotting title('Double-Sided Magnitude Spectrum after Applying fftshift') xlabel('Frequency / Hz') ylabel('|P2|'); grid on ``` 这段脚本先构建了一个新的频率轴 Fshft ,再调用了 `fftshift()` 方法改变 Y 数组内部元素的位置关系,最后再次作图以便对比查看效果差异。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值