时间序列信号处理(五)——小波变换python实现

简介:

小波变换(wavelet transform,WT)相比短时傅里叶变换来说,由固定窗口大小变成了自适应的窗口大小去进行信号处理,能够提供一个随频率改变的“时间-频率”窗口,是进行信号时频分析和处理的理想工具。

w\left ( a,b \right )=\frac{1}{\sqrt{a}}\cdot \int_{-\infty }^{\dotplus \infty }f\left ( t \right )\cdot \psi \left ( \frac{t-b}{a} \right )dt

不同于傅里叶变换,变量只有频率ω,小波变换有两个变量:尺度a和平移量 b。尺度a控制小波函数的伸缩,平移量 b控制小波函数的平移。尺度就对应于频率(反比),平移量 b就对应于时间

离散小波变换(Discrete Wavelet Transform,DWT)

1.对于一般的时间序列来说,不是连续变换,而是一种离散信号,这就需要用到离散小波变换,离散小波变换就只是将尺度参数a和平移参数b离散化。小波变换很大程度上弥补了傅立叶分解在非平稳时间序列上的不足,通过将傅立叶分解的正余弦波替换为一组可衰减的正交基,能较好地表达出序列中的突变和非平稳部分。

2.离散小波变换的核心:用不同频率的滤波器分析不同频率的信号,主要是高通滤波器和低通滤波器。
DWT用小波基函数(wavelet fuction)和尺度函数(scale function)来分别分析高频信号和低频信号,也即高通滤波器和低通滤波器。
3.离散小波变换步骤:

  1. 将信号x(n)通过具有脉冲响应h(n)的高通滤波器,过滤掉频率低于P/2的部分(信号最高频率为P),即为半带高通滤波。
  2. 根据奈奎斯特定理进行下采样,间隔一个剔除样本点,信号留下一半样本点,尺度翻倍,将这一半进行高通滤波。
  3. 进一步分解,就把高通滤波器的结果再次一分为二,进行高通滤波和低通滤波。
  4. 不断反复进行上述操作,根据自己要求调整。

经过上述操作,保留了频率的时间位置信息。

注意:傅里叶变换在处理突变信号,需要利用大量的三角波去拟合信号,也会导致计算复杂,信号特征提取效果降低;而小波变换是一种自适应的三角波,就是一个三角波不断进行平移、伸缩,就可以契合信号的变换,从而更好提取特征。

小波变换python示例:

# 小波
sampling_rate = 1024
t = np.arange(0, 1.0, 1.0 / sampling_rate)
f1 = 100
f2 = 200
f3 = 300
f4 = 400
data = np.piecewise(t, [t < 1, t < 0.8, t < 0.5, t < 0.3],
                    [lambda t: 400*np.sin(2 * np.pi * f4 * t),
                     lambda t: 300*np.sin(2 * np.pi * f3 * t),
                     lambda t: 200*np.sin(2 * np.pi * f2 * t),
                     lambda t: 100*np.sin(2 * np.pi * f1 * t)])
wavename = 'cgau8'
totalscal = 256
fc = pywt.central_frequency(wavename)
cparam = 2 * fc * totalscal
scales = cparam / np.arange(totalscal, 1, -1)
[cwtmatr, frequencies] = pywt.cwt(data, scales, wavename, 1.0 / sampling_rate)
plt.figure(figsize=(8, 4))
plt.subplot(211)
plt.plot(t, data)
plt.xlabel("t(s)")
plt.title('shipinpu',  fontsize=20)
plt.subplot(212)
plt.contourf(t, frequencies, abs(cwtmatr))
plt.ylabel(u"prinv(Hz)")
plt.xlabel(u"t(s)")
plt.subplots_adjust(hspace=0.4)
plt.show()

离散小波变换python示例:

 

import pywt
import matplotlib.pyplot as plt
import numpy as np

fs = 1000
N = 200
k = np.arange(200)
frq = k*fs/N
frq1 = frq[range(int(N/2))]

aa = []
for i in range(200):
    aa.append(np.sin(0.3*np.pi*i))
for i in range(200):
    aa.append(np.sin(0.13*np.pi*i))
for i in range(200):
    aa.append(np.sin(0.05*np.pi*i))
y = aa

wavename = 'db5'
cA, cD = pywt.dwt(y, wavename)
ya = pywt.idwt(cA, None, wavename, 'smooth')  # approximated component
yd = pywt.idwt(None, cD, wavename, 'smooth')  # detailed component
x = range(len(y))
plt.figure(figsize=(12, 9))
plt.subplot(311)
plt.plot(x, y)
plt.title('original signal')
plt.subplot(312)
plt.plot(x, ya)
plt.title('approximated component')
plt.subplot(313)
plt.plot(x, yd)
plt.title('detailed component')
plt.tight_layout()
plt.show()


# 图像单边谱
plt.figure(figsize=(12, 9))
plt.subplot(311)
data_f = abs(np.fft.fft(cA))/N
data_f1 = data_f[range(int(N/2))]
plt.plot(frq1, data_f1, 'red')

plt.subplot(312)
data_ff = abs(np.fft.fft(cD))/N
data_f2 = data_ff[range(int(N/2))]
plt.plot(frq1, data_f2, 'k')


plt.xlabel('pinlv(hz)')
plt.ylabel('amplitude')

plt.show()

 

 离散小波变换把信号分成了低频近似和高频细节,分离信号高低频效果还可以。可以设置阈值就可将信号高频分离出来。

以上仅是个人理解!!!可以一起多多交流。

来源:追剧入迷人

物联沃分享整理
物联沃-IOTWORD物联网 » 时间序列信号处理(五)——小波变换python实现

发表评论