几种常见窗函数及其MATLAB实现

对于窗函数一些教材和论坛都有好的定义和解释说明。鉴于前人的基础上,我也作了一些学习和研究。本文针对于不同的窗函数进行简单的对比,并有MATLAB程序应用。

:原文来源: http://blog.csdn.net/demo_deng/article/details/17351647       感谢博主

数字信号处理中通常是取其有限的时间片段进行分析,而不是对无限长的信号进行测量和运算。具体做法是从信号中截取一个时间片段,然后对信号进行傅里叶变换、相关分析等数学处理。信号的截断产生了能量泄漏,而用FFT算法计算频谱又产生了栅栏效应,从原理上讲这两种误差都是不能消除的。在FFT分析中为了减少或消除频谱能量泄漏及栅栏效应,可采用不同的截取函数对信号进行截短,截短函数称为窗函数,简称为窗。


泄漏与窗函数频谱的两侧旁瓣有关,对于窗函数的选用总的原则是,要从保持最大信息和消除旁瓣的综合效果出发来考虑问题,尽可能使窗函数频谱中的主瓣宽度应尽量窄,以获得较陡的过渡带;旁瓣衰减应尽量大,以提高阻带的衰减,但通常都不能同时满足这两个要求。频谱中的如果两侧瓣的高度趋于零,而使能量相对集中在主瓣,就可以较为接近于真实的频谱。不同的窗函数对信号频谱的影响是不一样的,这主要是因为不同的窗函数,产生泄漏的大小不一样,频率分辨能力也不一样。信号的加窗处理,重要的问题是在于根据信号的性质和研究目的来选用窗函数。图1是几种常用的窗函数的时域和频域波形,其中矩形窗主瓣窄,旁瓣大,频率识别精度最高,幅值识别精度最低,如果仅要求精确读出主瓣频率,而不考虑幅值精度,则可选用矩形窗,例如测量物体的自振频率等;布莱克曼窗主瓣宽,旁瓣小,频率识别精度最低,但幅值识别精度最高;如果分析窄带信号,且有较强的干扰噪声,则应选用旁瓣幅度小的窗函数,如汉宁窗、三角窗等;对于随时间按指数衰减的函数,可采用指数窗来提高信噪比。表1 是几种常用的窗函数的比较。


如果被测信号是随机或者未知的,或者是一般使用者对窗函数不大了解,要求也不是特别高时,可以选择汉宁窗,因为它的泄漏、波动都较小,并且选择性也较高。但在用于校准时选用平顶窗较好,因为它的通带波动非常小,幅度误差也较小。

                                              

表1 几种常用的窗函数的比较

名称

特点

应用

矩形窗

Rectangle

矩形窗使用最多,习惯上不加窗就是使信号通过了矩形窗。这种窗的优点是主瓣比较集中,缺点是旁瓣较高,并有负旁瓣,导致变换中带进了高频干扰和泄漏,甚至出现负谱现象。频率识别精度最高,幅值识别精度最低,所以矩形窗不是一个理想的窗。

如果仅要求精确读出主瓣频率,而不考虑幅值精度,则可选用矩形窗,例如测量物体的自振频率等,也可以用在阶次分析中。

汉宁窗

Hanning

又称升余弦窗。主瓣加宽并降低,旁瓣则显著减小,从减小泄漏观点出发,汉宁窗优于矩形窗.但汉宁窗主瓣加宽,相当于分析带宽加宽,频率分辨力下降。它与矩形窗相比,泄漏、波动都减小了,并且选择性也提高。

是很有用的窗函数。如果测试信号有多个频率分量,频谱表现的十分复杂,且测试的目的更多关注频率点而非能量的大小,需要选择汉宁窗。如果被测信号是随机或者未知的,选择汉宁窗。

海明窗

(汉明窗)

Hamming

与汉宁窗都是余弦窗,又称改进的升余弦窗,只是加权系数不同,使旁瓣达到更小。但其旁瓣衰减速度比汉宁窗衰减速度慢。

与汉明窗类似,也是很有用的窗函数。

平顶窗

Flap Top

平顶窗在频域时的表现就象它的名称一样有非常小的通带波动。

由于在幅度上有较小的误差,所以这个窗可以用在校准上。

凯塞窗

Kaiser

定义了一组可调的由零阶贝塞尔Bessel函数构成的窗函数,通过调整参数β可以在主瓣宽度和旁瓣衰减之间自由选择它们的比重。对于某一长度的Kaiser窗,给定β,则旁瓣高度也就固定了。

 

布莱克曼窗

Blackman

二阶升余弦窗,主瓣宽,旁瓣比较低,但等效噪声带宽比汉宁窗要大一点,波动却小一点。频率识别精度最低,但幅值识别精度最高,有更好的选择性。

常用来检测两个频率相近幅度不同的信号。

高斯窗

Gaussian

是一种指数窗。主瓣较宽,故而频率分辨力低;无负的旁瓣,第一旁瓣衰减达一55dB。常被用来截短一些非周期信号,如指数衰减信号等。

对于随时间按指数衰减的函数,可采用指数窗来提高信噪比。

三角窗

(费杰窗)

Fejer

是幂窗的一次方形式。与矩形窗比较,主瓣宽约等于矩形窗的两倍,但旁瓣小,而且无负旁瓣。

如果分析窄带信号,且有较强的干扰噪声,则应选用旁瓣幅度小的窗函数,如汉宁窗、三角窗等。

切比雪夫窗Chebyshev

在给定旁瓣高度下,Chebyshev窗的主瓣宽度最小,具有等波动性,也就是说,其所有的旁瓣都具有相等的高度。

 


下面是几种窗函数归一化DTFT幅度的MATLAB程序:

附上DTFT函数(dtft.m):

function [ X ] = dtft( x,n,w )
%   Computes Discrete-time Fourier Transform
%   [X] = dtft(x,n,w)
%    X = DTFT values computed at w.frequencies
%    x = finite duration sequence over n
%    n = sample position vector
%    w = frequency location vector
X = x*exp(-j*n'*w);
%
end


矩形窗:

%DTFT of a Rectangular Window, M=10,25,50,101
clc; close all;
Hf_1=figure; set(Hf_1,'NumberTitle','off','Name','P0304a');
w=linspace(-pi,pi,501); wtick=[-1:0.5:1]; magtick=[0:0.5:1.1];
% M=10
M=10; n=0:M; x=ones(1,length(n));
X=dtft(x,n,w); magX=abs(X); magX=magX/max(magX);
subplot(2,2,1); plot(w/pi,magX,'LineWidth',1.5); axis([-1 1 0 1.1]);
ylabel('|X|'); title(['M=10']);
set(gca,'XTick',wtick,'YTick',magtick);
% M=25
M=25; n=0:M; x=ones(1,length(n));
X=dtft(x,n,w); magX=abs(X); magX=magX/max(magX);
subplot(2,2,2); plot(w/pi,magX,'LineWidth',1.5); axis([-1 1 0 1.1]);
title(['M=25']); set(gca,'XTick',wtick,'YTick',magtick);
% M=50
M=50; n=0:M; x=ones(1,length(n));
X=dtft(x,n,w); magX=abs(X); magX=magX/max(magX);
subplot(2,2,3); plot(w/pi,magX,'LineWidth',1.5); axis([-1 1 0 1.1]);
xlabel('\omega/\pi'); ylabel('|X|'); 
title('M=50'); set(gca,'XTick',wtick,'YTick',magtick);
% M=101
M=101; n=0:M; x=ones(1,length(n));
X=dtft(x,n,w); magX=abs(X); magX=magX/max(magX);
subplot(2,2,4); plot(w/pi,magX,'LineWidth',1.5); axis([-1 1 0 1.1]);
xlabel('\omega/\pi'); ylabel('|X|');
title(['M=101']);

 

三角窗:

% Triangular Window: 
% DTFT of a Triangular Window,M = 10,25,50,101
clc; close all;
Hf_1=figure; set(Hf_1,'NumberTitle','off','Name','P0304b');
w=linspace(-pi,pi,501); wtick=[-1:0.5:1]; magtick=[0:0.5:1.1];
% M = 10
M=10; n=0:M; x=(1-(abs(M-1-(2*n))/(M+1)));
x=dtft(x,n,w); magX=abs(X); magX=magX/max(magX);
subplot(2,2,1); plot(w/pi,magX,'LineWidth',1.5); axis([-1 1 0 1.1]);
ylabel('|X|'); title(['M = 10']);
set(gca,'XTick',wtick,'YTick',magtick);
% M = 25
M=25; n=0:M; x=(1-(abs(M-1-(2*n))/(M+1)));
X=dtft(x,n,w); magX=abs(X); magX=magX/max(magX);
subplot(2,2,2); plot(w/pi,magX,'LineWidth',1.5); axis([-1 1 0 1.1]);
title(['M = 25']); set(gca,'XTick',wtick,'YTick',magtick);
% M = 50
M=50; n=0:M; x=(1-(abs(M-1-(2*n))/(M+1)));
X=dtft(x,n,w); magX=abs(X); magX=magX/max(magX);
subplot(2,2,3); plot(w/pi,magX,'LineWidth',1.5); axis([-1 1 0 1.1]);
xlabel('\omega/\pi'); ylabel('|X|'); title(['M = 50']); 
set(gca,'XTick',wtick,'YTick',magtick);
% M = 100
M=101;n=0:M; x=(1-(abs(M-1-(2*n))/(M+1)));
X=dtft(x,n,w); magX=abs(X); magX=magX/max(magX);
subplot(2,2,4); plot(w/pi,magX,'LineWidth',1.5); axis([-1 1 0 1.1]);
xlabel('\omega/\pi'); title(['M = 101']); 
set(gca,'XTick',wtick,'YTick',magtick);

 

汉宁窗:

% Hann Window
% DTFT of a Hann Window, M = 10,25,50,101
clc;close all;
Hf_1 = figure; set(Hf_1,'NumberTitle','off','Name','P0304c');
w=linspace(-pi,pi,501); wtick=[-1:0.5:1]; magtick=[0:0.5:1.1];
% M = 10
M=10;n=0:M; x=0.5*(1-cos((2*pi*n)/(M-1)));
X=dtft(x,n,w); magX=abs(X); magX=magX/max(magX);
subplot(2,2,1); plot(w/pi,magX,'LineWidth',1.5); axis([-1 1 0 1.1]);
ylabel('|X|'); title(['M = 10']);
set(gca,'XTick',wtick,'YTick',magtick);
% M = 25
M=25;n=0:M; x=0.5*(1-cos((2*pi*n)/(M-1)));
X=dtft(x,n,w); magX=abs(X); magX=magX/max(magX);
subplot(2,2,2); plot(w/pi,magX,'LineWidth',1.5); axis([-1 1 0 1.1]);
 title(['M = 25']);
set(gca,'XTick',wtick,'YTick',magtick);
% M = 50
M=50;n=0:M; x=0.5*(1-cos((2*pi*n)/(M-1)));
X=dtft(x,n,w); magX=abs(X); magX=magX/max(magX);
subplot(2,2,3); plot(w/pi,magX,'LineWidth',1.5); axis([-1 1 0 1.1]);
xlabel('\omega/\pi'); ylabel('|X|'); title(['M = 50']);
set(gca,'XTick',wtick,'YTick',magtick);
% M = 101
M=101;n=0:M; x=0.5*(1-cos((2*pi*n)/(M-1)));
X=dtft(x,n,w); magX=abs(X); magX=magX/max(magX);
subplot(2,2,4); plot(w/pi,magX,'LineWidth',1.5); axis([-1 1 0 1.1]);
xlabel('\omega/\pi'); title(['M = 101']);
set(gca,'XTick',wtick,'YTick',magtick);


 

汉明窗:

% Hamming Window:
clc; close all;
Hf_1=figure; set(Hf_1,'NumberTitle','off','Name','P0304d');
w=linspace(-pi,pi,501); wtick=[-1:0.5:1]; magtick=[0:0.5:1.1];
% M = 10
M=10; n=0:M; x=(0.54-0.46*cos((2*pi*n)/(M-1)));
X=dtft(x,n,w); magX=abs(X); magX=magX/max(magX);
subplot(2,2,1); plot(w/pi,magX,'LineWidth',1.5); axis([-1 1 0 1.1]);
 ylabel('|X|'); title(['M = 10']);
set(gca,'XTick',wtick,'YTick',magtick);
% M = 25
M=25; n=0:M; x=(0.54-0.46*cos((2*pi*n)/(M-1)));
X=dtft(x,n,w); magX=abs(X); magX=magX/max(magX);
subplot(2,2,2); plot(w/pi,magX,'LineWidth',1.5); axis([-1 1 0 1.1]);
title(['M = 25']);
set(gca,'XTick',wtick,'YTick',magtick);
% M = 50
M=50; n=0:M; x=(0.54-0.46*cos((2*pi*n)/(M-1)));
X=dtft(x,n,w); magX=abs(X); magX=magX/max(magX);
subplot(2,2,3); plot(w/pi,magX,'LineWidth',1.5); axis([-1 1 0 1.1]);
xlabel('\omega/\pi'); ylabel('|X|'); title(['M=50']);
set(gca,'XTick',wtick,'YTick',magtick);
% M = 101
M=101; n=0:M; x=(0.54-0.46*cos((2*pi*n)/(M-1)));
X=dtft(x,n,w); magX=abs(X); magX=magX/max(magX);
subplot(2,2,4); plot(w/pi,magX,'LineWidth',1.5); axis([-1 1 0 1.1]);
xlabel('\omega/\pi');title(['M=101']);
set(gca,'XTick',wtick,'YTick',magtick);



  • 26
    点赞
  • 199
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 常见窗函数包括矩形、汉明、汉宁和布莱克曼等。这些窗函数在信号处理中常用于频谱分析、滤波器设计和数据间的相互转换。 在MATLAB中,可以使用window函数来实现常见窗函数。例如,对于矩形,可以使用MATLAB中的rectwin函数来实现。具体的实现代码如下: n = 256; % 窗函数长度 w = rectwin(n); % 矩形窗函数长度 plot(w); xlabel('样本序号'); ylabel('幅度'); title('矩形窗函数'); 对于汉明,可以使用MATLAB中的hamming函数来实现。具体的实现代码如下: n = 256; % 窗函数长度 w = hamming(n); % 汉明窗函数长度 plot(w); xlabel('样本序号'); ylabel('幅度'); title('汉明窗函数'); 对于汉宁,可以使用MATLAB中的hann函数来实现。具体的实现代码如下: n = 256; % 窗函数长度 w = hann(n); % 汉宁窗函数长度 plot(w); xlabel('样本序号'); ylabel('幅度'); title('汉宁窗函数'); 对于布莱克曼,可以使用MATLAB中的blackman函数来实现。具体的实现代码如下: n = 256; % 窗函数长度 w = blackman(n); % 布莱克曼窗函数长度 plot(w); xlabel('样本序号'); ylabel('幅度'); title('布莱克曼窗函数'); 以上是常见窗函数MATLAB实现方法,通过给定窗函数的长度,可以得到对应的窗函数序列,并进行绘制和使用。在实际应用中,可以根据需要选择合适的窗函数来进行信号处理和频谱分析等操作。 ### 回答2: 常见窗函数有矩形、三角、汉宁、汉明和布莱克曼等。下面以Matlab为例,介绍这几种窗函数实现方法。 1. 矩形: rectwin函数可以直接生成一个长度为N的矩形。 ```matlab N = 256; % 长度 w = rectwin(N); ``` 2. 三角: triang函数可以生成一个长度为N的三角。 ```matlab N = 256; % 长度 w = triang(N); ``` 3. 汉宁: hann函数可以生成一个长度为N的汉宁。 ```matlab N = 256; % 长度 w = hann(N); ``` 4. 汉明: hamming函数可以生成一个长度为N的汉明。 ```matlab N = 256; % 长度 w = hamming(N); ``` 5. 布莱克曼: blackman函数可以生成一个长度为N的布莱克曼。 ```matlab N = 256; % 长度 w = blackman(N); ``` 生成的窗函数存储在向量w中,可以与要处理的信号进行加处理,以改善频谱分析结果或者减小频谱泄漏等问题。 ### 回答3: 常见窗函数包括矩形、汉宁、汉明和布莱克曼等。 矩形是最简单的窗函数,其实现代码如下: ``` matlab function w = rectwin(N) w = ones(N, 1); end ``` 汉宁是一种典型的平滑窗函数,其实现代码如下: ``` matlab function w = hann(N) L = N - 1; n = 0:L; w = 0.5 * (1 - cos(2 * pi * n / L))'; end ``` 汉明也是一种经典的窗函数,其实现代码如下: ``` matlab function w = hamming(N) L = N - 1; n = 0:L; w = 0.54 - 0.46 * cos(2 * pi * n / L)'; end ``` 布莱克曼是一种用于减小频谱泄露的窗函数,其实现代码如下: ``` matlab function w = blackman(N) L = N - 1; n = 0:L; w = 0.42 - 0.5 * cos(2 * pi * n / L) + 0.08 * cos(4 * pi * n / L)'; end ``` 以上是常见窗函数的简单实现代码。在Matlab中,我们可以通过这些代码生成对应的窗函数序列,并应用于信号处理、频谱分析等场景中。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值