在Matlab中通过绘图计算汉明窗的主瓣宽度

信息处理 matlab 离散信号 窗函数
2022-02-01 06:53:44

我想使用 Matlab 验证 Hann/Hamming 窗口的主瓣宽度是矩形窗口的两倍。我计算了各个频率响应的解析表达式,并绘制了它们。我没有得到预期的结果。有人可以解释一下吗?

代码 :

omega = -pi:0.01:pi;
N = 20;
fn = exp(-j*omega*(N/2 - 0.5)).*((sin(omega*N/2))./(sin(omega/2)));
shift = (length(omega)-1)/(N-1); % 2pi/(N-1); length(omega) = 2*pi
fn2 = 0.54*fn' + 0.23*circshift(fn',ceil(shift)) + 0.23*circshift(fn',-ceil(shift));
plot(abs(fn)/max(abs(fn)))
hold on
plot(abs(fn2)/max(abs(fn2)),'r')

这是情节:

在此处输入图像描述

如您所见,主瓣既不宽,旁瓣也不小。

2个回答

问题在于您移动矩形窗口的变换以计算汉明窗口的变换的方式。您不能只在离散频率网格上移动,而是必须评估网格上(连续)移动的函数。如果是矩形窗口的变换Wr(ω)

(1)Wr(ω)=1Nejω(N1)/2sin(Nω/2)sin(ω/2)

那么汉明窗的变换可以写成

Wh(ω)=αW(ω)β2[Wr(ωω0)+Wr(ω+ω0)]

α=0.54β=0.46ω0=2π/(N1)

在 Matlab/Octave 中,你得到:

w = -pi:0.01:pi;
N = 20;
w0 = 2*pi/(N-1);
Wr = 1/N*exp(-j*w*(N-1)/2).*sin(N*w/2)./sin(w/2);
W1 = 1/N*exp(-j*(w-w0)*(N-1)/2).*sin(N*(w-w0)/2)./sin((w-w0)/2 );
W2 = 1/N*exp(-j*(w+w0)*(N-1)/2).*sin(N*(w+w0)/2)./sin((w+w0)/2 );
Wh = .54*Wr -.23*(W1+W2);

绘图(w/pi,20*log10(abs(Wr)),w/pi,20*log10(abs(Wh)/max(abs(Wh))))
轴([-1,1,-60,0]),网格

在此处输入图像描述

编辑:

我在评论中提到的另一个错误是公式中移动窗口的符号。您使用的正号对于零相位汉明窗有效,即以为中心的窗。但是,您的矩形窗口从开始,因此它不是零相位窗口。因此,将两个窗口组合起来,就好像它们都是零相位一样是行不通的。这就是我公式中负号的来源(两个窗口都从开始)。如果您更改代码中的符号,则结果比以前更接近汉明窗,但由于我上面提到的网格上的偏移,它仍然关闭。在下图中,您可以看到差异(蓝色:精确的汉明;红色:您的解决方案带有更正符号): n=0n=0n=0在此处输入图像描述

我认为您对窗户频率响应的分析表达式有误。

进行比较的另一种方法是在时域中创建窗口并进行 FFT。

x1 = ones(20,1);  % rectangular window
x2 = hamming(20); % hamming window

% normalize
x1 = x1 / sum(x1);
x2 = x2 / sum(x2);

X1 = mag2db(abs(fftshift(fft(x1,1024))));
X2 = mag2db(abs(fftshift(fft(x2,1024))));

plot(X1)
hold on; grid on
plot(X2,'r')
legend('Rectangular','Hamming')
ylim([-50 0])
xlim([1 1024])

在此处输入图像描述