常见的四种窗函数的表达式为:

四种常见窗函数的参数表

对于实际信号序列,该如何选取窗函数呢?一般来说,选择第一旁瓣衰减大,旁瓣峰值衰减快的窗函数有利于缓解截断过程中产生的频谱泄漏问题。但具有这两个特性的窗函数,其主瓣宽度较大,相应会带来一些副作用,应用中需根据具体情况折中地选择。
设信号中包含fa和fb两个频率分量,窗函数的选择与两个频率分量的间距以及两个频率分量的幅度比例密切相关。窗函数选择的一般准则如下表所列。
窗函数选择的一般规则

主瓣窄的窗函数一般旁瓣泄漏大,频谱泄漏主要集中在旁瓣范围内。旁瓣衰减大的窗函数,一般主瓣较宽,泄漏主要集中在主瓣范围内。
当选择加窗DFT时,已知采样长度N的选择与最小频域分辨率有关,而从上表中看到采样长度N还与窗函数的主瓣宽度相关,所以N的选择应为
N≥(fs/△fmin)K
式中:K为窗函数的主瓣宽度与矩形窗的主瓣宽度之比。
根据窗函数对数据处理的影响,可参照下列原则选取理想的窗函数:
①窗函数频谱的主瓣应尽可能地窄,以提高谱估计时的频域分辨率和减小泄漏。
②尽量减小窗函数频谱的最大旁瓣的相对幅度,以使旁瓣高度随频率尽快衰减。
若以上两条不能同时得到满足,则往往是增加主瓣宽度以换取对旁瓣的抑制。
总之,在应用窗函数时,除要考虑窗函数频谱本身的特性外,还应充分考虑被分析信号的特点及具体处理要求。
案例、设N=256,用boxcar函数产生矩形窗,以N=256进行FFT,又以N=2048点进行FFT,比较它们的谱图。并用hanning函数,hamming函数和blackman函数得到它们的谱图和时域图,程序如下:
clear all; clc; close all;
N=256; % 窗长度
x=boxcar(N); % 设置矩形窗
y=hanning(N);
z=hamming(N);
w=blackman(N);
% 第一部分
X1=fft(x); % FFT
X1_abs=abs(fftshift(X1)); % 计算幅值
freq1=(-128:127)/N; % 频率刻度1
figure(1);
subplot 311; plot(freq1,X1_abs,'k'); % 作图
xlim([-0.1 0.1]);
xlabel('归一化频率'); ylabel('幅值');
title('(a) 补零前FFT谱图')
% 第二部分
X2=fft(x,N*8); % 对矩形窗补零后FFT
X2_abs=abs(fftshift(X2)); % 计算幅值
freq2=(-N*4:N*4-1)/(N*8); % 频率刻度2
subplot 312; plot(freq2,X2_abs,'k'); % 作图
xlim([-0.1 0.1]);
xlabel('归一化频率'); ylabel('幅值');
title('(b) 补零后FFT谱图')
X2_dB=20*log10(X2_abs/(max(X2_abs))+eps); % 幅值取分贝值
subplot 313; plot(freq2,X2_dB,'k'); % 作图
axis([0 0.1 -50 5]);
%xlim([-0.1 0.1]);
xlabel('归一化频率'); ylabel('幅值/dB');
title('(c) 补零后FFT谱图-分贝值')
set(gcf,'color','w');
%%
Y2=fft(y,N*8); % 对hanning窗补零后FFT
Y2_abs=abs(fftshift(Y2)); % 计算幅值
Y2_dB=20*log10(Y2_abs/(max(Y2_abs))+eps); % 幅值取分贝值
Z2=fft(z,N*8); % 对hamming窗补零后FFT
Z2_abs=abs(fftshift(Z2)); % 计算幅值
Z2_dB=20*log10(Z2_abs/(max(Z2_abs))+eps); % 幅值取分贝值
W2=fft(w,N*8); % 对blackman窗补零后FFT
W2_abs=abs(fftshift(W2)); % 计算幅值
W2_dB=20*log10(W2_abs/(max(W2_abs))+eps); % 幅值取分贝值
figure(2);
plot(freq2,Y2_dB,'k'); % 作图
hold on;
plot(freq2,X2_dB,'r');
plot(freq2,Z2_dB,'b');
plot(freq2,W2_dB,'g');
axis([0 0.1 -150 5]);
%xlim([-0.1 0.1]);
xlabel('归一化频率'); ylabel('幅值/dB');
title('补零后FFT谱图-分贝值')
legend('hanning','boxcar','hamming','blackman');
set(gcf,'color','w');
figure(3);
plot(hanning(N));hold on;
plot(boxcar(N));
plot(hamming(N));
plot(blackman(N));
legend('hanning','boxcar','hamming','blackman');
title('四种窗函数的时域波形图');
运行结果如下:

在程序第一部分中(第一张图片),N=256,作256点的FFT,得图1(a)。从图中可看
到矩形窗的谱图并不只有一条谱线,且没有泄漏。这是怎么回事?
矩形窗的谱函数为

在N点DFT后离散频率为wk=2πk/N(k=C,1,…,N-1)。把wk代入上式可以发现,除k=0外,其他频点的幅值都为0,这就是为什么在图1(a)中除0点有谱线外,其他都为0值。
要得到常见的矩形窗谱图(把0值之间泄漏的值都能绘制出来),可以通过对数据补零得到。在程序第二部分N=256,但FFT变换长度L=2048,其中在数据后补了1792(256*7)个零值。FFT后的结果见图1(b),同时对FFT后的幅值取分贝值后的结果见图1(c),这就是我们常见的矩形窗的谱图。
同时在程序第二部分,我们得到了四种窗函数的时域波形和频谱图。
参考文献:MATLAB数字信号处理85个实用案例精讲——入门到进阶;宋知用(编著)
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
我需要一个通过输入字符串进行计算的方法,像这样function="(a/b)*100"a=25b=50function.something>>50有什么方法吗? 最佳答案 您可以使用instance_eval:function="(a/b)*100"a=25.0b=50instance_evalfunction#=>50.0请注意,使用eval本质上是不安全的,尤其是当您使用外部输入时,因为它可能包含注入(inject)的恶意代码。另请注意,a设置为25.0而不是25,因为如果它是整数a/b将导致0(整数)。
我需要从json记录中获取一些值并像下面这样提取curr_json_doc['title']['genre'].map{|s|s['name']}.join(',')但对于某些记录,curr_json_doc['title']['genre']可以为空。所以我想对map和join()使用try函数。我试过如下curr_json_doc['title']['genre'].try(:map,{|s|s['name']}).try(:join,(','))但是没用。 最佳答案 你没有正确传递block。block被传递给参数括号外的方法
在这段Ruby代码中:ModuleMClassC当我尝试运行时出现“'M:Module'的未定义方法'helper'”错误c=M::C.new("world")c.work但直接从另一个类调用M::helper("world")工作正常。类不能调用在定义它们的同一模块中定义的模块函数吗?除了将类移出模块外,还有其他解决方法吗? 最佳答案 为了调用M::helper,你需要将它定义为defself.helper;结束为了进行比较,请查看以下修改后的代码段中的helper和helper2moduleMclassC
也许这听起来很荒谬,但我想知道这对Ruby是否可行?基本上我有一个功能...defadda,bc=a+breturncend我希望能够将“+”或其他运算符(例如“-”)传递给函数,这样它就类似于...defsuma,b,operatorc=aoperatorbreturncend这可能吗? 最佳答案 两种可能性:以方法/算子名作为符号:defsuma,b,operatora.send(operator,b)endsum42,23,:+或者更通用的解决方案:采取一个block:defsuma,byielda,bendsum42,23,
所以我正在研究RubyKoans,而且我遇到了一个我认为是ruby1.9.x特有的问题。deftest_calling_global_methods_without_parenthesesresult=my_global_method2,3assert_equal5,resultend我明白了:james@tristan:~/code/ruby_projects/ruby_koans$rake(in/home/james/code/ruby_projects/ruby_koans)cdkoans/home/james/.rvm/rubies/ruby-1.9.2-p180/bin/ru