使用Python中的PyWavelets
库实现信号小波分解和重构
pywt
进行小波变换,numpy
处理数据,matplotlib
绘图wavedec
进行多级分解waverec
重构信号import pywt
import numpy as np
import matplotlib.pyplot as plt
# 1. 生成示例信号
t = np.linspace(0, 1, 1000, endpoint=False)
signal = np.sin(2 * np.pi * 10 * t) + 0.5 * np.sin(2 * np.pi * 50 * t)
signal += 0.2 * np.random.randn(len(t)) # 添加噪声
# 2. 小波分解参数设置
wavelet = 'db4' # 使用Daubechies4小波
level = 4 # 分解层数
# 3. 执行小波分解
coeffs = pywt.wavedec(signal, wavelet, level=level)
cA4, cD4, cD3, cD2, cD1 = coeffs # 各级系数
print(f"系数结构: {[c.shape for c in coeffs]}")
# 4. (可选) 系数处理 - 这里演示简单的阈值去噪
threshold = 0.5 # 阈值大小
coeffs_thresh = [coeffs[0]] # 保留近似系数
for i in range(1, len(coeffs)):
# 对细节系数应用软阈值
coeffs_thresh.append(pywt.threshold(coeffs[i], threshold, mode='soft'))
# 5. 信号重构
reconstructed = pywt.waverec(coeffs_thresh, wavelet)
# 确保信号长度一致(小波变换可能导致边界扩展)
reconstructed = reconstructed[:len(signal)]
# 6. 结果可视化
plt.figure(figsize=(12, 10))
# 原始信号
plt.subplot(4, 1, 1)
plt.plot(t, signal)
plt.title("原始信号 (含噪声)")
plt.grid(True)
# 分解系数
plt.subplot(4, 1, 2)
for i, coeff in enumerate(coeffs_thresh):
if i == 0:
plt.plot(coeff, 'r', label=f'cA{level}')
else:
plt.plot(coeff, label=f'cD{level-i+1}')
plt.title("小波系数 (阈值处理后)")
plt.legend()
plt.grid(True)
# 重构信号
plt.subplot(4, 1, 3)
plt.plot(t, reconstructed)
plt.title("重构信号 (去噪后)")
plt.grid(True)
# 重构误差
plt.subplot(4, 1, 4)
plt.plot(t, signal - reconstructed, 'r')
plt.title("重构误差")
plt.grid(True)
plt.tight_layout()
plt.show()
# 计算重构误差
mse = np.mean((signal - reconstructed)**2)
print(f"均方误差 (MSE): {mse:.6f}")
print(f"最大绝对误差: {np.max(np.abs(signal - reconstructed)):.6f}")
'db4'
:Daubechies 4阶小波(常用)'haar'
, 'sym5'
, 'coif3'
等(根据信号特性选择)level <= pywt.dwt_max_level(len(signal), wavelet)
soft
阈值:T(x) = \text{sign}(x)(|x| - \text{threshold}) hard
阈值:T(x) = x \cdot \mathbb{I}(|x| > \text{threshold}) threshold = np.std(coeff) * np.sqrt(2*np.log(len(signal)))
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。