幾種常用的經典頻譜估計方法原理介紹及Matlab算法實現

    在信號的譜分析中,由於經典的譜分析方法物理意義比較明確,能夠處理的信號信噪比可以很低(相對於現代的譜估計來說),而且處理算法簡單穩定;因此在大多數的情況下都是使用經典的譜分析方法對信號進行譜分析。

      經典的譜分析方法有:直接法、間接法、Bartlett法和Welch法。下面就來分別討論這幾種方法的特點。

直接法

    直接法又稱週期圖法,它是把隨機信號x(n)N點觀察數據視爲一個能量有限的信號,直接取的傅里葉變換,得,然後再取其幅值的平方,併除以N,作爲對x(n)真實的功率譜的估計。以表示用週期圖法估計出的功率譜,則有

                          

間接法

   此方法又稱自相關法或者BT法,此方法的理論基礎是維納-辛欽定理,即先由估計出自相關函數求傅里葉變換得到的功率譜,記之爲,並以此作爲對的估計,即

Bartlett法

   由概率論可知,對L個具有相同的均值和方差的獨立隨機變量,新的隨機變量的均值也是,但方差是爲原來的1/L。由此我們可以得到改善方差特性的一個有效的方法,即Bartlett法。Bartlett法將採樣數據分成L段,每段長度都是M,即N=LM,第i段數據加矩形窗後,變爲

式中是長度爲M的矩形窗口。分別計算每一段的功率譜,即

對應相加,再取平均,得到平均週期圖,即

Welch

      Welch法是對Bartlett法的改進。改進之一是,在對分段時,可允許每一段的數據有部分的交疊。改進之二是,每一段的數據窗口可以不是矩形窗口,例如使用漢寧窗或漢明窗。這樣可以改善由於矩形窗旁瓣較大所產生的譜失真。然後按Bartlett法求每一段的功率譜。

Matalb仿真

   爲了對比這幾種方法的優缺點,在仿真的程序中保持分析的信號不變,分別利用上述的方法進行分析。

   生成兩種不同頻率的正弦信號頻率分別爲150KHz140KHz。採樣率爲750KHz,採樣點數爲512個點,信噪比爲20dB

Matlab程序如下:

clear all;
close all;
clc;
 
f0 = 150e3;             %定義信號的頻率
f1 = 140e3;
fs = 5*f0;               %定義採樣率
points = 512;           %採樣點數
signal_points = 512;   %信號的長度
SNR = 20;                %信噪比
 
nTs = (0:points-1)/fs;
Delta_f = (0:points-1)*fs/points;
 
signal = sin(2*pi*f0*nTs)+sin(2*pi*f1*nTs);
signal(signal_points:points) = 0;
signal_noise = signal + 10^(-SNR/20)*randn(1,points);

直接法的Matlab程序

   首先計算截斷的信號的離散傅里葉變換,然後取模值的平方並歸一化,最後取以10爲底的對數然後乘以10,繪製歸一化後的功率譜圖。

fft_signal_noise = fft(signal_noise);
squar_fft_signal_noise = fft_signal_noise.*conj(fft_signal_noise);
Periodogram_method_Spectrum = squar_fft_signal_noise/points;
max_Periodogram_method_Spectrum = max(Periodogram_method_Spectrum);  %求行最大值
Periodogram_method_Spectrum = Periodogram_method_Spectrum/max_Periodogram_method_Spectrum;
log10_Periodogram_method_Spectrum = 10*log10(Periodogram_method_Spectrum);
figure;
plot(Delta_f(1:points/2)/1000,log10_Periodogram_method_Spectrum(1:points/2));
xlabel('KHz');
ylabel('歸一化功率譜P(k)/dB');
string = ['直接法(週期圖法)信號點數=',num2str(signal_points),',採樣點數=',num2str(points),...
          ',信號頻率=',num2str(f0/1000),'KHz,採樣率=',num2str(fs/1000),'KHz,信噪比SNR=',...
          num2str(SNR),'dB'];
title(string);

BT法的Matlab程序

   首先計算截斷信號的線性自相關,然後求其離散傅里葉變換,取其模值,歸一化,並取以10爲底的對數然後乘以10,繪製歸一化後的功率譜圖。

autocorr_signal_noise = xcorr(signal_noise);                    %求線性自相關
fft_autocorr_signal_noise = fft(autocorr_signal_noise);         %求自相關的fft
abs_fft_autocorr_signal_noise = abs(fft_autocorr_signal_noise)/(2*points-1); %求幅值
max_abs_fft_autocorr_signal_noise = max(abs_fft_autocorr_signal_noise);
abs_fft_autocorr_signal_noise = abs_fft_autocorr_signal_noise/max_abs_fft_autocorr_signal_noise;
log10_abs_fft_autocorr_signal_noise = 10*log10(abs_fft_autocorr_signal_noise);
Delta_f1 = (0:2*points-2)*fs/(2*points-1);
figure;
plot(Delta_f1(1:points)/1000,log10_abs_fft_autocorr_signal_noise(1:points));
xlabel('KHz');
ylabel('歸一化功率譜P(k)/dB');
string = ['間接法(自相關法BT)信號點數=',num2str(signal_points),',採樣點數=',num2str(points),...
          ',信號頻率=',num2str(f0/1000),'KHz,採樣率=',num2str(fs/1000),'KHz,信噪比SNR=',...
          num2str(SNR),'dB'];
title(string);

Bartlett法的Matlab程序

   首先將截斷的信號分成等長的不重疊的若干段,然後計算每一段的離散傅里葉變換,並取模值的平方,然後對應點求和。所有段計算並求和完成後,歸一化處理,並取以10爲底的對數然後乘以10,繪製歸一化後的功率譜圖。

M = 128;                %每段的點數
L = points/M;          %段數
Bartlett_Spectrum = zeros(1,points);
for i=1:L
    temp_signal = zeros(1,points);                                 %清零
    start_point = (i-1)*M;
    temp_signal(1:M) = signal_noise((start_point+1):(start_point+M));  %截取第i段信號
    fft_temp_signal = fft(temp_signal);
    squar_fft_temp_signal = fft_temp_signal.*conj(fft_temp_signal);    %求當前段的功率譜
    Bartlett_Spectrum = Bartlett_Spectrum + squar_fft_temp_signal;     %累加
end
max_Bartlett_Spectrum = max(Bartlett_Spectrum);
Bartlett_Spectrum = Bartlett_Spectrum/max_Bartlett_Spectrum;           %歸一化
log10_Bartlett_Spectrum = 10*log10(Bartlett_Spectrum);                 %求對數
Delta_f2 = (0:points-1)*fs/points;
figure;
plot(Delta_f2(1:points/2)/1000,log10_Bartlett_Spectrum(1:points/2));
xlabel('KHz');
ylabel('歸一化功率譜P(k)/dB');
string = ['Bartlett法,信號點數=',num2str(signal_points),',採樣點數=',num2str(points),...
          ',信號頻率=',num2str(f0/1000),'KHz,採樣率=',num2str(fs/1000),'KHz,信噪比SNR=',...
          num2str(SNR),'dB,段數L=',num2str(L),',每段點數M=',num2str(M)];
title(string);

Welch法的Matlab程序

   首先將截斷的信號分成等長的有重疊的若干段,然後計算每一段的離散傅里葉變換,並取模值的平方,然後對應點求和。所有段計算並求和完成後,歸一化處理,並取以10爲底的對數然後乘以10,繪製歸一化後的功率譜圖。

M = 128;                              %每段的點數
Overlap = M-M/16;                       %重疊點數
L = (points - Overlap)/(M-Overlap);  %段數
Welch_Spectrum = zeros(1,points);
for i=1:L
    temp_signal = zeros(1,points);                                 %清零
    start_point = (i-1)*(M-Overlap);
    temp_signal(1:M) = signal_noise((start_point+1):(start_point+M));  %截取第i段信號
    fft_temp_signal = fft(temp_signal);
    squar_fft_temp_signal = fft_temp_signal.*conj(fft_temp_signal);    %求當前段的功率譜
    Welch_Spectrum = Welch_Spectrum + squar_fft_temp_signal;          %累加
end
max_Welch_Spectrum = max(Welch_Spectrum);
Welch_Spectrum = Welch_Spectrum/max_Welch_Spectrum;           %歸一化
log10_Welch_Spectrum = 10*log10(Welch_Spectrum);              %求對數
Delta_f3 = (0:points-1)*fs/points;
figure;
plot(Delta_f3(1:points/2)/1000,log10_Welch_Spectrum(1:points/2));
xlabel('KHz');
ylabel('歸一化功率譜P(k)/dB');
string = ['Welch法,信號點數=',num2str(signal_points),',採樣點數=',num2str(points),...
          ',信號頻率=',num2str(f0/1000),'KHz,採樣率=',num2str(fs/1000),'KHz,信噪比SNR=',...
          num2str(SNR),'dB,段數L=',num2str(L),',每段點數M=',num2str(M),',重疊點數=',...
          num2str(Overlap)];
title(string);

Matlab運行結果及分析

   設置相應參數運行上述程序得到如下圖:



1信號的時域圖


2週期圖法得到的功率譜圖                                                            3 BT法得到的功率譜(M=128)


4 Batlett法得到的功率譜(4段)                                             5 Welch法得到的功率譜(128)


6 BT法得到的功率譜(M=64)                                                            7 BT法得到的功率譜(M=32)


8 Batlett法得到的功率譜(8段)                            9 Welch法得到的功率譜(64)


  1爲生成的仿真信號,一共512個點。

   圖2爲用週期圖法對數據直接求出功率譜。由於主瓣寬度B = 2/512 = 0.003906 < (150-140)/750 = 0.013所以f0f1能夠分開。

      圖3是利用BT法求出的功率譜,M=128,依然能將f0與f1分開;對於與圖2其主瓣更寬了。當M=64時,如圖6 f0與f1不能完全分開,只是在波形的頂部看出是兩個頻率的分量。當M=32,如圖7 f0與f1就已經無法分開了。

   圖4是利用Batlett法求出的功率譜,共分4段,每段128個點,可以看到f0f1能夠被分開,相對於圖2其更加平滑,但是主瓣的寬度比圖2的要寬。當分爲8段,每段64個點時,如圖8其變的更加平滑但f0f1已經不能完全分開了。

   圖5是利用Welch方法求出的平均週期圖,每段128個點,重合120個點,譜變得更加的平滑,效果與圖4基本一致。若每段64個點,重合60個點,如圖9 f0f1已不能分開,效果與圖8基本一致。


結論

綜合上述討論,可以得到對經典譜估計如下總結:

1.經典譜估計可以用FFT快速計算,且物理概念明確,因而仍是目前很常用的譜估計方法。

2. 譜的分辨率較低,它正比於N是所使用的數據長度。

3. 由於不可避免的窗函數的影響,使得真正譜在窗口主瓣內的功率向旁瓣部分泄露,降低了分辨率。較大旁瓣有可能掩蓋中較弱的成分,或是產生假的峯值。當分析的數據較短時,這些影響更爲突出。

4. 方差性能不好,不是的一致估計,且N增大時譜線起伏加劇。

5.週期圖的平滑和平均是和窗函數的使用緊緊相關聯的。平滑和平均主要是用來改善週期圖的方差性能,但往往又降低了分辨率和增大了偏差。沒有一個窗函數能使估計的譜在方差、偏差和分辨率這幾個方面都得到改善。因此,使用窗函數只是改進估計質量的一個技巧問題,而不是根本的解決辦法。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章