计算信号的fft频谱并获得正确的幅度

时间:2016-01-12 22:21:56

标签: matlab window signal-processing fft

我正在尝试一些相当简单的方法,即在具有固定长度的信号频谱中获得正确的值。我不知道包含的频率,因此我不能相应地选择fft节点的数量。这让我有泄漏的问题。我试图通过使用一个窗口淡出我的时间信号的开始和结束来避免这种情况。有了这个我有问题,以获得正确的振幅。这是我到目前为止所做的:

  • 通过将频谱乘以因子
  • 来补偿窗口
  • 双面至单面光谱 - >将频谱幅度乘以2
  • normalice频谱幅度除以频率节点数'N'

只要fft节点的数量等于我的时间信号中的数量,它就能很好地工作。但是当fft节点的数量小于时间信号节点时,频谱的幅度就会出错。

我建立了一个计算三个光谱的小例子:

  1. 使用带窗口的fft()
  2. 使用fft()而不使用窗口
  3. 使用频谱图()
  4. 通过改变SampleTime可以改变时间信号的长度,通过改变N可以改变FFT节点的数量。通过以下设置,所有幅度都是正确的,但是对于具有Hanning窗口的光谱。为什么这么多?感谢您提前提供任何帮助。

    SampleTime=0.001;
    Fs=1/SampleTime;
    t=0:SampleTime:10;
    
    y=2*sin(2*pi*10*t)+3*cos(2*pi*30*t); % Time Signal
    
    fn = Fs/2; % Nyquistfrequency
    N = 1001; % FFT-length (use N=2^x to use DFT-Algorithm)
    df = Fs/N; % frequency resolution
    
    %% Generating spectrum using fft()
    win = hann(length(y))';  % generate Hanning window for Time Signal
    
    ywin = y.*win*length(win)/sum(win); % amplitude correction to get correct values with window
    
    Hwin = fft(ywin, N); % spectrum of windowed signal
    H = fft(y,N);  % complex spectrum of signal without window
    
    amplHwin = abs(Hwin); % absolute values of spectrum of windowed signal
    amplH = abs(H); % absolute values of spectrum without window
    
    % Double sided spectrum -> single sided spectrum of windowed signal
    amplitudengang = fftshift(amplH/N);
    amplitudengang = amplitudengang(ceil(length(amplitudengang)/2+1):end);
    amplitudengang(2:end) = amplitudengang(2:end)*2;
    
    % Double sided spectrum -> single sided spectrum of unwindowed signal
    amplitudengangwin = fftshift(amplHwin/N);
    amplitudengangwin = amplitudengangwin(ceil(length(amplitudengangwin)/2+1):end);
    amplitudengangwin(2:end) = amplitudengangwin(2:end)*2;
    
    %% Generating spectrum using spectrogram()
    noverlap = floor(0.5*N);
    window = hann(N);
    [B,F,T] = spectrogram(y,window,noverlap,N,Fs);
    % Scaling
    FFTScalingFactor = 2 * 1 / N; % 2 for Hanning window, 2^(-1/2) for RMS, 1 for peak
    A = FFTScalingFactor * B;
    B = FFTScalingFactor * abs(B);
    B(2:end-1,:) = 2.*B(2:end-1,:); % single side spectrum with even block length
    
    %% Plots
    
    x_fn = 0 : df : fn-df; % Frequency vector
    
    figure
    subplot(2,2,1)
    plot(x_fn,amplitudengangwin,'r')
    hold on
    plot(x_fn,amplitudengang)
    legend('Hanning window','no window')
    title('FFT()')
    subplot(2,2,3)
    plot(t,y)
    title('Time signal')
    subplot(2,2,2)
    plot(F,B(:,1))
    title('Spectrogram()')
    

1 个答案:

答案 0 :(得分:3)

您应该更改FFT的数量。

Hwin = fft(ywin, N); % spectrum of windowed signal
H = fft(y,N);  % complex spectrum of signal without window

这里N是1001。

这意味着当您执行窗口信号的FFT时,您在所有数据样本(10001个样本)中仅使用了前1001个样本。

您使用的窗口信号如下所示。

enter image description here

更改您的代码,如下所示

Hwin = fft(ywin, length(y)); % spectrum of windowed signal
H = fft(y,length(y));  % complex spectrum of signal without window
    amplHwin = abs(Hwin); % absolute values of spectrum of windowed signal
amplH = abs(H); % absolute values of spectrum without window

% Double sided spectrum -> single sided spectrum of windowed signal
amplitudengang = fftshift(amplH/length(y));
amplitudengang = amplitudengang(ceil(length(amplitudengang)/2+1):end);
amplitudengang(2:end) = amplitudengang(2:end)*2;

% Double sided spectrum -> single sided spectrum of unwindowed signal
amplitudengangwin = fftshift(amplHwin/length(y));
amplitudengangwin = amplitudengangwin(ceil(length(amplitudengangwin)/2+1):end);
amplitudengangwin(2:end) = amplitudengangwin(2:end)*2;

fftAll=[amplitudengang' amplitudengangwin'];

figure(1)
    plot(fftAll)
    xlim([0 500])

你会得到以下频谱。

enter image description here

您定义了N = 1001,但您的数据长度为10001.如果您只想使用1001个样本,则应将窗口长度设置为1001。

如果您只想在数据中使用1001个样本,请更改您的代码,如下所示。

SampleTime=0.001;
Fs=1/SampleTime;
t=0:SampleTime:10;

y=2*sin(2*pi*10*t)+3*cos(2*pi*30*t); % Time Signal

fn = Fs/2; % Nyquistfrequency
N = 1001; % FFT-length (use N=2^x to use DFT-Algorithm)
df = Fs/N; % frequency resolution

%% Generating spectrum using fft()
win = hann(N)';  % generate Hanning window for Time Signal

figure(10)
plot(win)

ywin = y(1:N).*win*length(win)/sum(win); % amplitude correction to get correct values with window
figure(11)
plot(ywin)
xlim([0 1001])
   Hwin = fft(ywin, N); % spectrum of windowed signal
H = fft(y,N);  % complex spectrum of signal without window
    amplHwin = abs(Hwin); % absolute values of spectrum of windowed signal
amplH = abs(H); % absolute values of spectrum without window

% Double sided spectrum -> single sided spectrum of windowed signal
amplitudengang = fftshift(amplH/N);
amplitudengang = amplitudengang(ceil(length(amplitudengang)/2+1):end);
amplitudengang(2:end) = amplitudengang(2:end)*2;

% Double sided spectrum -> single sided spectrum of unwindowed signal
amplitudengangwin = fftshift(amplHwin/N);
amplitudengangwin = amplitudengangwin(ceil(length(amplitudengangwin)/2+1):end);
amplitudengangwin(2:end) = amplitudengangwin(2:end)*2;

fftAll=[amplitudengang' amplitudengangwin'];

figure(1)
    plot(fftAll)
    xlim([0 50])

在这段代码中,我将所有长度(y)都改为N. 我改变了ywin,如下所示。

ywin = y(1:N).*win*length(win)/sum(win);

结果如下所示。

enter image description here