当前位置:   article > 正文

窗函数作用和性质

窗函数

什么是窗函数?

窗函数能够产生一段特定的信号,假定为w

我们假设一段信号为x,给这段信号加窗,指的是将x乘上w

下面的代码说明了这个过程

import numpy as np
from scipy.signal import get_window
import matplotlib.pyplot as plt
%matplotlib inline

M = 128                                     # 信号的长度
x = np.cos( np.linspace(0, 8*np.pi, 128) )  # 生成一段cos信号
w = get_window('hanning', M)                # 调用窗函数,生成w(hanning是一种窗函数)

xw = x*w                                    # 加窗

plt.figure(figsize=(10,10))
plt.subplot(311)
plt.plot(x);plt.title('Input signal')
plt.subplot(312)
plt.plot(w);plt.title('Haning window')
plt.subplot(313)
plt.plot(xw);plt.title('Windowed signal')

plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

png

窗函数的作用是什么?

1.防止泄露

关于泄露,参见什么是泄漏?

在信号处理中,我们通常对信号进行截断分析,如果信号截断为非周期截断,那么频谱将发生泄露。通过加窗,可以减少频谱的泄露。我们可以这么想象,窗函数可以将一个非周期的信号,强行变成一个周期的信号。

下面的代码展示了什么是泄露,以及窗函数可以减少泄露
可以从(c)和(d)的对比中看到,加窗后可以有效的减少泄露

import numpy as np
from scipy.signal import get_window
from scipy.fftpack import fft

import matplotlib.pyplot as plt

%matplotlib inline

M = 128                                           # 信号的长度
x = np.cos( np.linspace(0, 80.7*np.pi, 128) )     # 生成一段非周期信号
w = get_window('hanning', M)                      # 调用窗函数,生成w(hanning是一种窗函数)

X = fft(x)
mX = np.abs(X)

xw = x*w                                          # 加窗
XW = fft(xw)
mXW = np.abs(XW)

plt.figure(figsize=(12,12))
plt.subplot(321)
plt.plot(x);plt.title('(a)Input signal')
plt.subplot(322)
plt.plot(xw);plt.title('(b)Windowed signal')
plt.subplot(323)
plt.plot(mX);plt.title('(c)Amplitude of unwindowed signal')
plt.subplot(324)
plt.plot(mXW);plt.title('(d)Amplitude of windowed signal')

plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

png

2. 分析意义

一个加窗后的信号,它的傅里叶变换结果可以表示为窗函数的傅里叶变换。非常神奇的性质,并且在信号分析中非常重要,见如下证明

trans_of_window_sinewave

有哪些常用的窗函数?它们特点是什么?

窗函数有很多很多种,Scipy中的get_window提供了多种窗函数的实现,具体请参看scipy.signal.get_window

每种窗函数都可以由两个特征来区别:主瓣的宽度(main-lobe width)和副瓣最大高度(side-lobe level)

analysis_window

下面介绍几种常用的窗函数

Rectangular

w [ n ] = { 1 , n=-M/2,...,0,...,M/2 0 , n=elsewhere w[n] =

{1,n=-M/2,...,0,...,M/20,n=elsewhere
w[n]={1,0,n=-M/2,...,0,...,M/2n=elsewhere

W [ k ] = π k π k / M W[k] = \frac{\pi k}{\pi k/M} W[k]=πk/Mπk

main-lobe width: 2 bins

side-lobe level: -13.3db

from scipy import signal
from scipy.fftpack import fft, fftshift
import matplotlib.pyplot as plt

window = signal.boxcar(51)
plt.plot(window)
plt.title("Boxcar rectangular window")
plt.ylabel("Amplitude")
plt.xlabel("Sample")

plt.figure()
A = fft(window, 2048)
freq = np.linspace(-0.5, 0.5, len(A))
response = 20 * np.log10(np.abs(fftshift(A / abs(A).max())))
plt.plot(freq, response)
plt.axis([-0.5, 0.5, -120, 0])
plt.title("Frequency response of the boxcar window")
plt.ylabel("Normalized magnitude [dB]")
plt.xlabel("Normalized frequency [cycles per sample]")

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

png

png

Hanning

w [ n ] = 0.5 + 0.5 ∗ cos ⁡ ( 2 π n / M ) w[n] = 0.5+0.5*\cos (2\pi n/M) w[n]=0.5+0.5cos(2πn/M)
W [ k ] = 0.5 D [ k ] + 0.25 ( D [ k − 1 ] + D [ k + 1 ] ) , D [ k ] = sin ⁡ ( π k ) π k / M W[k] = 0.5D[k] + 0.25(D[k-1] + D[k+1]), D[k] = \frac{\sin (\pi k)}{\pi k/M} W[k]=0.5D[k]+0.25(D[k1]+D[k+1]),D[k]=πk/Msin(πk)

main-lobe width: 4 bins

side-lobe level: -31.5db

window = signal.hanning(51)
plt.plot(window)
plt.title("Hanning window")
plt.ylabel("Amplitude")
plt.xlabel("Sample")

plt.figure()
A = fft(window, 2048)
freq = np.linspace(-0.5, 0.5, len(A))
response = 20 * np.log10(np.abs(fftshift(A / abs(A).max())))
plt.plot(freq, response)
plt.axis([-0.5, 0.5, -120, 0])
plt.title("Frequency response of the Hanning window")
plt.ylabel("Normalized magnitude [dB]")
plt.xlabel("Normalized frequency [cycles per sample]")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

png

png

Hamming

w [ n ] = 0.54 + 46 ∗ cos ⁡ ( 2 π n / M ) w[n] = 0.54+46*\cos (2\pi n/M) w[n]=0.54+46cos(2πn/M)

main-lobe width: 4 bins

side-lobe level: -42.7db

window = signal.hamming(51)
plt.plot(window)
plt.title("Hamming window")
plt.ylabel("Amplitude")
plt.xlabel("Sample")

plt.figure()
A = fft(window, 2048)
freq = np.linspace(-0.5, 0.5, len(A))
response = 20 * np.log10(np.abs(fftshift(A / abs(A).max())))
plt.plot(freq, response)
plt.axis([-0.5, 0.5, -120, 0])
plt.title("Frequency response of the Hamming window")
plt.ylabel("Normalized magnitude [dB]")
plt.xlabel("Normalized frequency [cycles per sample]")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

png

png

Blackman

w [ n ] = 0.42 − 0.5 cos ⁡ ( 2 π n / M ) + 0.08 cos ⁡ ( 4 π n / M ) w[n] = 0.42 - 0.5\cos(2\pi n/M) + 0.08\cos(4\pi n/M) w[n]=0.420.5cos(2πn/M)+0.08cos(4πn/M)

main-lobe width: 6 bins

side-lobe level: -58db

window = signal.blackman(51)
plt.plot(window)
plt.title("Blackman window")
plt.ylabel("Amplitude")
plt.xlabel("Sample")

plt.figure()
A = fft(window, 2048)
freq = np.linspace(-0.5, 0.5, len(A))
response = 20 * np.log10(np.abs(fftshift(A / abs(A).max())))
plt.plot(freq, response)
plt.axis([-0.5, 0.5, -120, 0])
plt.title("Frequency response of the Blackman window")
plt.ylabel("Normalized magnitude [dB]")
plt.xlabel("Normalized frequency [cycles per sample]")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

png

png

Blackman-Harris

w [ n ] = 1 M ∑ i = 0 3 α i cos ⁡ ( 2 n / π / M ) , α 0 = 0.35875 , α 1 = 0.35875 , α 1 = 0.35875 , α 3 = 0.35875 w[n] = \frac{1}{M}\sum_{i=0}^{3} \alpha_i \cos(2n/\pi/M), \alpha_0=0.35875, \alpha_1=0.35875, \alpha_1=0.35875, \alpha_3=0.35875 w[n]=M1i=03αicos(2n/π/M),α0=0.35875,α1=0.35875,α1=0.35875,α3=0.35875

main-lobe width: 8 bins

side-lobe level: -92 db

window = signal.blackmanharris(51)
plt.plot(window)
plt.title("Blackman-Harris window")
plt.ylabel("Amplitude")
plt.xlabel("Sample")

plt.figure()
A = fft(window, 2048)
freq = np.linspace(-0.5, 0.5, len(A))
response = 20 * np.log10(np.abs(fftshift(A / abs(A).max())))
plt.plot(freq, response)
plt.axis([-0.5, 0.5, -120, 0])
plt.title("Frequency response of the Blackman-Harris window")
plt.ylabel("Normalized magnitude [dB]")
plt.xlabel("Normalized frequency [cycles per sample]")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
<matplotlib.text.Text at 0x227ea5e2cc0>
  • 1

png

png

总结

本文中,我们首先介绍了窗函数的定义,说明了窗函数能够减少信号泄露,并且在信号分析非常的便利,然后我们又介绍了常见的几种窗函数和它们的性质

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/104887
推荐阅读
相关标签
  

闽ICP备14008679号