Python中简单和不连续信号的连续小波变换

787 阅读7分钟

连续小波变换(CWT)的定义是将所有的时间信号相加,再乘以小波的移位版本。连续小波变换的输出给出了小波系数作为输出。

这些系数是尺度和位置的函数。这个过程对简单和不连续的信号都可以进行。一个不连续的小波是一个正弦波,然后是一个中正弦波。一个简单的信号是一个慢正弦波。

本教程将探讨小波和CWT的背景理论。我们还将看一下CWT和这种变换的各种应用。最后,我们讨论计算简单和不连续信号的CWT的Python代码。

前提条件

要跟上本教程,读者需要。

  • 熟悉Python编程语言。
  • 在你的电脑上安装Pycharm。你可以从这里下载。

CWT的理论:小波

小波是一种有效限制持续时间的波形,具有平均零值。它被定义为

psi_a,b(t)=frac1sqrtapsi(ffractba)a,binrˋeal\\psi\_{a,b}(t) = \\frac{1}{sqrt a}\\psi(ffrac{t-b}{a}) a,b \\ in \`real

这里,a和b分别称为扩张和平移参数。下面是一个小波方程的样本和它相应的小波。

Wavelet

该图是幅度图。

寻找CWT系数

信号f(t)的CWT由以下方程给出。

CWT_(a,b)=(f,psi_a,b)=frac1sqrtaint+infin_infinf(t).psi\*(fractba)dtCWT\_{(a,b)} = (f, \\psi\_{a,b}) = frac{1}{sqrt{a}}\\int^{+\\infin}\_{-\\infin}f(t).\\psi\*(\\frac{t-b}{a})dt

这里,(f,psi_a,b)(f, \\psi\_{a,b})是内积。

CWT的结果是许多小波系数,是ab 的函数。对于不同形状的小波,我们计算出系数,并将其绘制在幅值轴上,如下图所示。

Wavelet plot

从原点开始的尺度轴是较低的尺度,沿轴是较高的尺度。在低尺度下,小波被压缩,这里的频率很高。

在较高的尺度上,它被拉伸,这里的频率就低。这种系数的排列方式被称为scalogram。下面是谱系图的实际图,对于一些有小波的信号来说,它是完整的。

Scalogram

CWT的应用

  • CWT主要用于信号的频谱分析。我们可以用它来研究频率断裂、时间不连续、信号突发、信号阻尼和振动模式。
  • 谱图形式的CWT系数可以作为图像输入到深度神经网络,用于信号分类。

不同信号的谱系图样本显示如下。

1.频率断裂

frequency break

在信号中,有一个频率断裂。这种明显的差异可以在谱图中看到。此外,它还显示了频率在哪一点上发生了变化。

2.不连续检测

Discontinuity detection

这里,我们有一个不连续的信号。同时,我们可以看到在某一时刻,不连续发生在哪里。

使用Python对信号进行CWT处理

我们使用Python的pywavelet 库来计算CWT。Pywavelet 是Python的一个开源的小波变换软件。它将简单和高级的界面与低级别的C和Python性能相结合。此外,它还附带有Anaconda发行版。因此,我们在使用Anaconda时不需要单独安装它。

它的依赖性是:numpy,SciPy, 和Matplotlib (所有这些库都是Anaconda发布的)。

计算CWT的一般语法是。

coefs, freqs = pywt.cwt(signal, scales, wavelets)

其中。

  • Signal: 是阵列形式的信号。
  • Scales:是数组形式的CWT所使用的尺度。
  • Wavelets是所用小波的名称。
  • Coefs表示CWT系数。
  • Freqs:是阵列形式中与尺度相对应的频率。

还有一些其他的可选参数。这意味着你不需要定义它们。

例如。

  • Method:方法有卷积 (conv) 或快速傅里叶变换 (fft)。
  • Sampling period:是指输出频率所需的秒数。

支持的小波和它们在Python中使用的相应语法是这样的。

  • Mexican hat(mexh)
  • 莫勒特(morl)
  • 复合小波(cmorB-C)
  • 高斯派生(gausP)
  • 复合高斯导数(cgauP)
  • Shannon(shanB-C)
  • 频率B-Spline(fbspB-C)

用于一维信号CWT的Python代码

我们首先要导入一些库。这些库如下所示。

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

Pywt 用于计算CWT, ,用于数值计算, ,用于绘制输出。然后我们定义要使用的时间空间、信号和刻度。numpy matplotlib

t = np.linspace(0, 1, 200)

# Finding signal by adding three different signals
signal = np.cos(2 * np.pi * 7 * t) + np.real(np.exp(-7 * (t-0.4)**2)*np.exp(1j*2*np.pi*2*(t-0.4)))
scales = np.arange(1, 31)  # No. of scales

时间空间的范围是0到1。linspace() 函数将轴分开,等于200点。这里使用的标度数是31。

现在,我们使用pywt.cwt() 函数来计算CWT,如下所示。

coef, freqs = pywt.cwt(signal, scales, 'gaus1')  # Finding CWT using gaussian wavelet

这个函数使用信号、标度和小波类型作为参数。在执行这个函数时,我们得到存储在coef 变量中的CWT系数。这个函数的另一个输出是存储在freqs 变量中的相应频率。

让我们将CWT系数以谱图的形式绘制出来。

# Plotting scalogram
plt.figure(figsize=(15, 10))
plt.imshow(abs(coef), extent=[0, 200, 30, 1], interpolation='bilinear', cmap='bone',
           aspect='auto', vmax=abs(coef).max(), vmin=abs(coef).max())
plt.gca().invert_yaxis()
plt.yticks(np.arange(1, 31, 1))
plt.xticks(np.arange(0, 201, 10))
plt.show()

在这里,我们通过假设矩阵是一个图像来绘制谱图。这就是我们使用imshow() 函数的原因。abs() 函数给出了系数的绝对值coefs

我们将使用的其他参数有:interpolation 。它用于软化绘图。cmap 给出了颜色映射。Yticksxticks 给出了xy 轴,而plt.show() 显示了输出绘图。

为了使我们的信号可视化,我们也可以用下面的命令绘制它。

# Plotting
plt.figure(figsize=(15, 10))
plt.plot(t, signal)
plt.grid(color='gray', linestyle=':', linewidth=0.5)
plt.show()

现在让我们执行我们的程序。

谱系图显示如下。

Scalogram

相应的信号如下图所示。

Signal plot

用于不连续信号的CWT的Python代码

我们首先导入所需的库。

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

然后我们定义我们的信号。

Fs = 44100.0  #Samples per second
tclip = 10e-3
nos = np.int(Fs*tclip)  #No of samples in 10ms
tpoints = np.linspace(0, 10e-3, nos) #Time points
x = np.cos(2*np.pi*500*tpoints)  #cos(2*pi*f*t) signal

这里,我们的信号Fs ,采样频率为44100,信号持续时间为10ms。为了得到样本数,我们得到每秒的样本数Fs 和信号的持续时间tclip 的乘积。

如果乘积不是整数,函数int() 将其四舍五入为最接近的整数。我们还定义了时间点tpoints 和信号x 。最后,我们有一个由cos() 函数定义的余弦信号。

让我们给我们的信号引入不连续性。如下图所示,通过强迫信号在某个给定的点为0来实现。

scales = np.arange(1, 21, 1)  #No. of scales=20
x[87:89] = 0  #Giving discontinuity
x[307:309] = 0  #Giving discontinuity

我们正在强迫信号在定义的点上归零。然后,我们使用同样的函数pywt.cwt() ,计算这个信号的CWT,并使用类似的命令来绘制谱图,如下图所示。

coef, freqs = pywt.cwt(x, scales, 'gaus4')  # Finding CWT using gaussian wavelet

# Plotting scalogram
plt.figure(figsize=(15, 10))
plt.imshow(abs(coef), extent=[0, 10e-3, 20, 1], interpolation='bilinear', cmap='copper',
           aspect='auto', vmax=abs(coef).max(), vmin=abs(coef).max())
plt.gca().invert_yaxis()
plt.yticks(np.arange(1, 21, 1))
plt.xticks(np.arange(0, nos/Fs, nos/(20*Fs)))
plt.show()

# Plotting
plt.figure(figsize=(15, 10))
plt.plot(tpoints, x)
plt.grid(color='gray', linestyle=':', linewidth=0.5)
plt.show()

当我们执行这个程序时,我们将得到信号的绘图和相应的谱图绘图。

例如,该信号如下图所示。

Signal

我们可以看到,信号在2ms和7ms处分别有一个不连续点。相应的频谱图如下所示。

Scalogram

如果你看一下谱系图,我们可以看到在哪一点上出现了断点。所以它显示了CWT在分析信号方面的优势。

结论

执行CWT是分析各种信号的一个非常重要的过程。这个过程被广泛用于我们之前讨论的各个领域。信号的scalogram视图提供了关于信号的详细视觉信息。这意味着只需看一下谱图,你就可以看到信号的行为。

编码愉快!