手动 DWT 与 Python pywt

信息处理 小波 载重吨
2022-01-29 09:24:07

我想了解离散小波变换。我正在尝试手动完成以很好地理解所有步骤。

以小波函数“sym2”为例,知道其低分解滤波器组系数为:

dec_lo = [-0.12940952255092145, 0.22414386804185735, 0.836516303737469, 0.48296291314469025]
dec_hi = [-0.48296291314469025, 0.836516303737469, -0.22414386804185735, -0.12940952255092145]

给定一个x数组,那么它的近似系数和细节系数是:

t = np.linspace(0, 1.0, 128)
x = np.sin(2*np.pi*10*t)

cA = np.convolve(x, dec_lo)[1::2] 
cD = np.convolve(x, dec_hi)[1::2]

但是,我没有得到与使用库 pywt 相同的结果

cA_, cD_ = pywt.dwt(x, 'sym2')

“中间”值相等,但末端的值不相等。为什么会这样,是我做错了吗?pywt 应用了一些额外的步骤?

谢谢您的帮助。

2个回答

这可能与扩展/周期化模式有关,或者与信号在其自然边界(左和右)之外的处理方式有关。的标准扩展np.convolve可能不同于为小波开发的许多扩展方案。

由于您想手动开发它以理解概念,这是一个非常好的举措,所以我建议您使用不是正弦形的信号:它们不是分析和理解小波的最佳选择,因为后者更对分段规则信号有效,例如不同程度的多项式的串联。这是表现类似于分数微分器的半正交小波的插图

半正交离散小波分解

并且为了限制扩展的影响,明智的做法是将信号向左和向右扩展零,毕竟这仍然是分段多项式。

这是真正发生的事情。

  1. pywt 首先根据填充模式扩展信号。默认模式是对称的。
  2. 然后它执行卷积并仅返回输出的相关样本。

卷积是作为 C 扩展的一部分编写的。C 扩展实际上跳过了计算所有索引的卷积。换句话说,它通过不计算每个备用位置的输出来一起执行卷积和下采样。

您可以按如下方式复制计算。

填充:

x_padded = pywt.pad(x, len(dec_lo), 'symmetric')

卷积

lo = np.convolve(x_padded, dec_lo, 'valid')

下采样

lo = lo[::2]

从末尾删除额外的输出值

lo = lo[1:-1]

之后你会看到

np.allclose(cA_, lo)

打印真。

高通/细节部分相同:

hi = np.convolve(x_padded, dec_hi, 'valid')[::2]
hi = hi[1:-1]
np.allclose(cD_, hi)

最后,以下两个是相同的:

pywt.pad(x, len(dec_lo), 'symmetric')

np.pad(x, len(dec_lo), 'symmetric')

但是,pywt.pad它支持更多的扩展模式,其扩展模式的命名法与numpy.

在 pywt 中阅读有关信号扩展模式的更多信息