连续小波变换(CWT)的定义是将所有的时间信号相加,再乘以小波的移位版本。连续小波变换的输出给出了小波系数作为输出。
这些系数是尺度和位置的函数。这个过程对简单和不连续的信号都可以进行。一个不连续的小波是一个正弦波,然后是一个中正弦波。一个简单的信号是一个慢正弦波。
本教程将探讨小波和CWT的背景理论。我们还将看一下CWT和这种变换的各种应用。最后,我们讨论计算简单和不连续信号的CWT的Python代码。
前提条件
要跟上本教程,读者需要。
CWT的理论:小波
小波是一种有效限制持续时间的波形,具有平均零值。它被定义为
这里,a和b分别称为扩张和平移参数。下面是一个小波方程的样本和它相应的小波。

该图是幅度图。
寻找CWT系数
信号f(t)的CWT由以下方程给出。
这里,是内积。
CWT的结果是许多小波系数,是a 和b 的函数。对于不同形状的小波,我们计算出系数,并将其绘制在幅值轴上,如下图所示。

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

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

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

这里,我们有一个不连续的信号。同时,我们可以看到在某一时刻,不连续发生在哪里。
使用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 给出了颜色映射。Yticks 和xticks 给出了x 和y 轴,而plt.show() 显示了输出绘图。
为了使我们的信号可视化,我们也可以用下面的命令绘制它。
# Plotting
plt.figure(figsize=(15, 10))
plt.plot(t, signal)
plt.grid(color='gray', linestyle=':', linewidth=0.5)
plt.show()
现在让我们执行我们的程序。
谱系图显示如下。

相应的信号如下图所示。

用于不连续信号的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()
当我们执行这个程序时,我们将得到信号的绘图和相应的谱图绘图。
例如,该信号如下图所示。

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

如果你看一下谱系图,我们可以看到在哪一点上出现了断点。所以它显示了CWT在分析信号方面的优势。
结论
执行CWT是分析各种信号的一个非常重要的过程。这个过程被广泛用于我们之前讨论的各个领域。信号的scalogram视图提供了关于信号的详细视觉信息。这意味着只需看一下谱图,你就可以看到信号的行为。
编码愉快!