当前位置: 首页 > news >正文

小波变换 | Haar 小波变换

在这里插入图片描述

小波变换 Haar 小波变换

连续形式

在实际实现中,尺度函数和小波函数中的系数,会被当做是滤波器参数。最终可以基于这里尺度函数和小波函数构造的基函数集合,来对输入信号进行分解(将信号投影到这些基函数上)。

  • 尺度母函数 ϕ(t)={10≤t<10其他\phi(t) = \begin{cases} 1 & 0 \le t < 1 \\ 0 & 其他 \end{cases}ϕ(t)={100t<1其他
  • 小波母函数 ψ(t)={10≤t<1/2−11/2≤t<10其他\psi(t) = \begin{cases} 1 & 0 \le t < 1/2 \\ -1 & 1/2 \le t < 1 \\ 0 & 其他 \end{cases}ψ(t)=1100t<1/21/2t<1其他

计算系数 h[n]h[n]h[n]g[n]g[n]g[n]

基于 ∑n∈Zh[n]h[n−2m]=δm\sum_{n \in \mathbb{Z}} h[n] h[n-2m] = \delta_{m}nZh[n]h[n2m]=δm

Haar 中,将卷积长度限定为 L=2L=2L=2,即在 n∉{0,1}n \notin \{0, 1\}n/{0,1}h[n]=0h[n] = 0h[n]=0。而 h[n]=ah[n]=ah[n]=ah[1]=bh[1]=bh[1]=b,先使用待定系数。基于已知的 ∑n∈Zh[n]h[n−2m]=δm\sum_{n \in \mathbb{Z}} h[n] h[n-2m] = \delta_{m}nZh[n]h[n2m]=δm,我们可以对 mmm 进行讨论,从而获得关于 Haar 中 hhh 的更多限定:

∑n∈{0,1}h[n]h[n]=a2+b2=1m=0∑n∈{0,1}h[n]h[n−2]=0+0=0m=1 \begin{aligned} \sum_{n \in \{0, 1\}} h[n]h[n] & = a^2 + b^2 = 1 & m=0 \\ \sum_{n \in \{0, 1\}} h[n]h[n-2] & = 0 + 0 = 0 & m=1 \end{aligned} n{0,1}h[n]h[n]n{0,1}h[n]h[n2]=a2+b2=1=0+0=0m=0m=1

为获得最简单(对称)结构,取 a=ba=ba=b,则可以得到 h[0]=h[1]=12h[0]=h[1]=\frac{1}{\sqrt{2}}h[0]=h[1]=21。进一步,通过 Haar 中采用的构造方式,即 g[n]=(−1)nh[1−n]g[n] = (-1)^n h[1-n]g[n]=(1)nh[1n],可以进一步推出 g[0]=−g[1]=12g[0]=-g[1]=\frac{1}{\sqrt{2}}g[0]=g[1]=21。所以可以得到更具体的细化方程:

  • 尺度细化方程 ϕ(t)=21/2[h[0]ϕ(2t)+h[1]ϕ(2t−1)]=ϕ(2t)+ϕ(2t−1)\phi(t) = 2^{1/2} [h[0]\phi(2t) + h[1]\phi(2t-1)] = \phi(2t) + \phi(2t-1)ϕ(t)=21/2[h[0]ϕ(2t)+h[1]ϕ(2t1)]=ϕ(2t)+ϕ(2t1),对应的 h[0]=2−1/2,h[1]=2−1/2h[0]=2^{-1/2}, h[1]=2^{-1/2}h[0]=21/2,h[1]=21/2
  • 小波细化方程:ψ(t)=21/2[g[0]ψ(2t)+g[1]ψ(2t−1)]=ψ(2t)−ψ(2t−1)\psi(t) = 2^{1/2} [g[0]\psi(2t) + g[1]\psi(2t-1)] = \psi(2t) - \psi(2t-1)ψ(t)=21/2[g[0]ψ(2t)+g[1]ψ(2t1)]=ψ(2t)ψ(2t1),对应的 g[0]=2−1/2,g[1]=−2−1/2g[0]=2^{-1/2}, g[1]=-2^{-1/2}g[0]=21/2,g[1]=21/2

基于正交展开

在计算系数的过程中,用到了正交展开,其中系数就是对应着目标函数在各个正交基上的投影。所以如下的细化公式中的系数,可以看做是函数 ϕ(t)\phi(t)ϕ(t) 在正交归一的基函数 21/2ϕ(2t−n)2^{1/2}\phi(2t - n)21/2ϕ(2tn) 上的投影模长:

ϕ(t)=21/2∑n∈Zh[n]ϕ(2t−n) \phi(t) = 2^{1/2} \sum_{n \in \mathbb{Z}} h[n] \phi(2t -n) ϕ(t)=21/2nZh[n]ϕ(2tn)

所以可以直接计算投影系数:

h[n]=⟨ϕ(t),21/2ϕ(2t−n)⟩∥21/2ϕ(2t−n)∥2=⟨ϕ(t),21/2ϕ(2t−n)⟩(∥21/2ϕ(2t−n)∥2=1)=21/2∫01ϕ(2t−n)dt(ϕ(t)=1) \begin{aligned} h[n] & = \frac{\langle \phi(t), 2^{1/2} \phi(2t -n) \rangle}{\| 2^{1/2} \phi(2t -n) \|^2} \\ & = \langle \phi(t), 2^{1/2} \phi(2t -n) \rangle \quad (\| 2^{1/2} \phi(2t -n) \|^2 = 1) \\ & = 2^{1/2} \int^{1}_{0} \phi(2t - n) dt \quad (\phi(t) = 1) \\ \end{aligned} h[n]=21/2ϕ(2tn)2ϕ(t),21/2ϕ(2tn)⟩=ϕ(t),21/2ϕ(2tn)⟩(21/2ϕ(2tn)2=1)=21/201ϕ(2tn)dt(ϕ(t)=1)

考虑其中的放缩偏移版本的尺度函数,满足如下范围:

ϕ(2t−n)={1t∈[n/2,(n+1)/2]0其他 \phi(2t - n) = \begin{cases} 1 & t \in [n/2, (n+1)/2] \\ 0 & 其他 \end{cases} ϕ(2tn)={10t[n/2,(n+1)/2]其他

考虑到 ϕ(t)\phi(t)ϕ(t) 本身对自变量的范围限制,我们可以知道 nnn 仅可以取值为 0 或者 1:

h[n]=21/2∫01ϕ(2t−n)dt={21/2∫1/21ϕ(2t−1)dt=21/2∫1/211dt=12n=121/2∫01/2ϕ(2t)dt=21/2∫01/21dt=12n=0 \begin{aligned} h[n] & = 2^{1/2} \int^{1}_{0} \phi(2t - n) dt \\ & = \begin{cases} 2^{1/2} \int^{1}_{1/2} \phi(2t-1) dt = 2^{1/2} \int^{1}_{1/2} 1 dt = \frac{1}{\sqrt{2}} & n=1 \\ 2^{1/2} \int^{1/2}_{0} \phi(2t) dt = 2^{1/2} \int^{1/2}_{0} 1 dt = \frac{1}{\sqrt{2}} & n=0 \\ \end{cases} \\ \end{aligned} h[n]=21/201ϕ(2tn)dt={21/21/21ϕ(2t1)dt=21/21/211dt=2121/201/2ϕ(2t)dt=21/201/21dt=21n=1n=0

从而可得最终的细化方程。同理 g[n]g[n]g[n] 也可以计算得到。

连续时间到离散索引

应用于实际的离散采样序列(如音频或图像)时,离散小波变换的目标是将信号分解为一组多尺度、多位置的正交基函数上的展开系数。这个过程中,我们通常将原始的信号视为最细层级 Jmax⁡=⌊log⁡2N⌋J_{\max} = \lfloor \log_2{N} \rfloorJmax=log2N(假定该尺度信号长度为 NNN)。每完成一级小波分解,就将尺度系数(低频部分)下采样一半,进入更粗一层的表示(数据分辨率降低,时间、空间尺度增大)。能够进行的最大分解层数由信号长度决定。最终,原始信号被完整表示为来自最粗层的尺度系数 aJa_{J}aJ 和所有层的小波系数 {dj}j=JJmax⁡−1\{d_{j}\}_{j=J}^{J_{\max}-1}{dj}j=JJmax1。他们分别对应信号在不同尺度的近似于细节成分。

在处理离散数据序列的时候,实际上涉及到了尺度函数和小波函数的离散形式,这里 1/N1/N1/N 实际上是因为考虑到了正交基在离散过程中正交归一性的保持才修改的:

ϕj,k(t),ψj,k(t)⇒ϕj,k′[n]=1Nϕj,k[n],ψj,k′[n]=1Nψj,k[n] \phi_{j,k}(t), \psi_{j,k}(t) \Rightarrow \phi'_{j,k}[n] = \frac{1}{\sqrt{N}} \phi_{j,k}[n], \psi'_{j,k}[n] = \frac{1}{\sqrt{N}} \psi_{j,k}[n] ϕj,k(t),ψj,k(t)ϕj,k[n]=N1ϕj,k[n],ψj,k[n]=N1ψj,k[n]

实现中则依照 Jmax⁡→JJ_{\max} \rightarrow JJmaxJ 的方向不断拆分,其中 aaa 表达了每个尺度的近似(低频)系数,而 ddd 捕捉了每个尺度的细节(高频)系数。而对于 Jmax⁡J_{\max}Jmax,通常直接定义 aJmax⁡=x[n]a_{J_{\max}} = x[n]aJmax=x[n],也就是说,原始采样信号本身就是最细尺度下的尺度系数。我们无需再从别的什么空间“计算”它,它就是我们处理的起点。

处理离散时间信号 x[n]x[n]x[n],取 J=0J=0J=0,则其在 VJV_{J}VJWJW_{J}WJ 上的正交基函数展开:

x[n]=∑kaJ[k]ϕJ,k′[n]+∑j=JJmax⁡∑kdj[k]ψj,k′[n]ϕj,k[n]=2jNϕ(2jNn−k)ψj,k[n]=2jNψ(2jNn−k) \begin{aligned} x[n] & = \sum_k a_{J}[k] \phi'_{J,k}[n] + \sum^{J_{\max}}_{j=J} \sum_k d_{j}[k] \psi'_{j,k}[n] \\ \phi_{j,k}[n] & = \sqrt{\frac{2^{j}}{N}} \phi \left ( \frac{2^{j}}{N} n - k \right ) \\ \psi_{j,k}[n]& = \sqrt{\frac{2^{j}}{N}} \psi \left ( \frac{2^{j}}{N} n - k \right ) \\ \end{aligned} x[n]ϕj,k[n]ψj,k[n]=kaJ[k]ϕJ,k[n]+j=JJmaxkdj[k]ψj,k[n]=N2jϕ(N2jnk)=N2jψ(N2jnk)

从 [[100-收集的信息碎片/小波变换 离散小波变换|小波变换 离散小波变换]] 中可以知道如下对应分解和重构两个过程的公式:

aj[k]=∑mh[m−2k]aj+1[m]dj[k]=∑mg[m−2k]aj+1[m]aj+1[k]=∑mh[k−2m]aj[m]+∑mg[k−2m]dj[m] \begin{aligned} a_{j}[k] & = \sum_{m} h[m-2k] a_{j+1}[m] \\ d_{j}[k] & = \sum_{m} g[m-2k] a_{j+1}[m] \\ a_{j+1}[k] & = \sum_{m} h[k-2m] a_{j}[m] + \sum_{m} g[k-2m] d_{j}[m] \\ \end{aligned} aj[k]dj[k]aj+1[k]=mh[m2k]aj+1[m]=mg[m2k]aj+1[m]=mh[k2m]aj[m]+mg[k2m]dj[m]

此时带入 hhhggg 的具体取值,则存在:

aj[k]=h[0]aj+1[2k]+h[1]aj+1[2k+1]=2−1/2(aj+1[2k]+aj+1[2k+1])dj[k]=g[0]aj+1[2k]+g[1]aj+1[2k+1]=2−1/2(aj+1[2k]−aj+1[2k+1])aj+1[k]⇐{aj+1[2m]=h[0]aj[m]+g[0]dj[m]=2−1/2aj[m]+2−1/2dj[m]k=2maj+1[2m+1]=h[1]aj[m]+g[1]dj[m]=2−1/2aj[m]−2−1/2dj[m]k=2m+1 \begin{align} a_{j}[k] & = h[0] a_{j+1}[2k] + h[1] a_{j+1}[2k+1] = 2^{-1/2} (a_{j+1}[2k] + a_{j+1}[2k+1]) \\ d_{j}[k] & = g[0] a_{j+1}[2k] + g[1] a_{j+1}[2k+1] = 2^{-1/2} (a_{j+1}[2k] - a_{j+1}[2k+1]) \\ a_{j+1}[k] & \Leftarrow \begin{cases} a_{j+1}[2m] & = h[0] a_{j}[m] + g[0] d_{j}[m] = 2^{-1/2} a_{j}[m] + 2^{-1/2} d_{j}[m] & k=2m \\ a_{j+1}[2m+1] & = h[1] a_{j}[m] + g[1] d_{j}[m] = 2^{-1/2} a_{j}[m] - 2^{-1/2} d_{j}[m] & k=2m+1 \end{cases} \end{align} aj[k]dj[k]aj+1[k]=h[0]aj+1[2k]+h[1]aj+1[2k+1]=21/2(aj+1[2k]+aj+1[2k+1])=g[0]aj+1[2k]+g[1]aj+1[2k+1]=21/2(aj+1[2k]aj+1[2k+1]){aj+1[2m]aj+1[2m+1]=h[0]aj[m]+g[0]dj[m]=21/2aj[m]+21/2dj[m]=h[1]aj[m]+g[1]dj[m]=21/2aj[m]21/2dj[m]k=2mk=2m+1

对于一个简单的例子:x=[x0,x1,x2,x3]x = [x_0, x_1, x_2, x_3]x=[x0,x1,x2,x3],下面给出了几种不同的处理视角。

直接公式推导版

  1. 预设最大层级系数(j=2j=2j=2):a2=xa_2 = xa2=x
  2. 第一次分解(j=2→1j=2 \rightarrow 1j=21):a1[k]=2−1/2(a2[2k]+a2[2k+1])a_1[k] = 2^{-1/2} (a_{2}[2k] + a_{2}[2k+1])a1[k]=21/2(a2[2k]+a2[2k+1])
    1. a1[0]=2−1/2(a2[0]+a2[1])=2−1/2(x0+x1)a_1[0] = 2^{-1/2} (a_{2}[0] + a_{2}[1]) = 2^{-1/2} (x_{0} + x_{1})a1[0]=21/2(a2[0]+a2[1])=21/2(x0+x1)
    2. a1[1]=2−1/2(a2[2]+a2[3])=2−1/2(x2+x3)a_1[1] = 2^{-1/2} (a_{2}[2] + a_{2}[3]) = 2^{-1/2} (x_{2} + x_{3})a1[1]=21/2(a2[2]+a2[3])=21/2(x2+x3)
    3. d1[0]=2−1/2(a2[0]−a2[1])=2−1/2(x0−x1)d_1[0] = 2^{-1/2} (a_{2}[0] - a_{2}[1]) = 2^{-1/2} (x_{0} - x_{1})d1[0]=21/2(a2[0]a2[1])=21/2(x0x1)
    4. d1[1]=2−1/2(a2[2]−a2[3])=2−1/2(x2−x3)d_1[1] = 2^{-1/2} (a_{2}[2] - a_{2}[3]) = 2^{-1/2} (x_{2} - x_{3})d1[1]=21/2(a2[2]a2[3])=21/2(x2x3)
  3. 第二次分解(j=1→0j=1 \rightarrow 0j=10):a0[k]=2−1/2(a1[2k]+a1[2k+1])a_0[k] = 2^{-1/2} (a_{1}[2k] + a_{1}[2k+1])a0[k]=21/2(a1[2k]+a1[2k+1])
    1. a0[0]=2−1/2(a1[0]+a1[1])a_0[0] = 2^{-1/2} (a_{1}[0] + a_{1}[1])a0[0]=21/2(a1[0]+a1[1])
    2. d0[0]=2−1/2(a1[0]−a1[1])d_0[0] = 2^{-1/2} (a_{1}[0] - a_{1}[1])d0[0]=21/2(a1[0]a1[1])
  4. 完整形式表示:x(t)=a0[0]ϕ0,0(t)+d0[0]ψ0,0(t)+d1[0]ψ1,0(t)+d1[1]ψ1,1(t)x(t) = a_0[0] \phi_{0,0}(t) + d_0[0] \psi_{0,0}(t) + d_1[0] \psi_{1,0}(t) + d_1[1] \psi_{1,1}(t)x(t)=a0[0]ϕ0,0(t)+d0[0]ψ0,0(t)+d1[0]ψ1,0(t)+d1[1]ψ1,1(t)

矩阵系数版

对于这个计算过程,其实可以直接写成矩阵形式。Haar 分解矩阵是正交的,所以直接使用转置即可重构数据。

[a0[0]d0[0]d1[0]d1[1]]=[h[0]h[0]h[1]h[0]h[0]h[1]h[0]h[1]h[0]g[0]h[1]g[0]h[0]g[1]h[0]g[1]g[0]g[1]0000g[0]g[1]][x[0]x[1]x[2]x[3]]=[1/21/21/21/21/21/2−1/2−1/21/2−1/200001/2−1/2][x[0]x[1]x[2]x[3]] \begin{aligned} \begin{bmatrix} a_0[0] \\ d_0[0] \\ d_1[0] \\ d_1[1] \end{bmatrix} & = \begin{bmatrix} h[0]h[0] & h[1]h[0] & h[0]h[1] & h[0]h[1] \\ h[0]g[0] & h[1]g[0] & h[0]g[1] & h[0]g[1] \\ g[0] & g[1] & 0 & 0 \\ 0 & 0 & g[0] & g[1] \end{bmatrix} \begin{bmatrix} x[0] \\ x[1] \\ x[2] \\ x[3] \end{bmatrix} \\ & = \begin{bmatrix} 1/2 & 1/2 & 1/2 & 1/2 \\ 1/2 & 1/2 & -1/2 & -1/2 \\ 1/\sqrt{2} & -1/\sqrt{2} & 0 & 0 \\ 0 & 0 & 1/\sqrt{2} & -1/\sqrt{2} \end{bmatrix} \begin{bmatrix} x[0] \\ x[1] \\ x[2] \\ x[3] \end{bmatrix} \end{aligned} a0[0]d0[0]d1[0]d1[1]=h[0]h[0]h[0]g[0]g[0]0h[1]h[0]h[1]g[0]g[1]0h[0]h[1]h[0]g[1]0g[0]h[0]h[1]h[0]g[1]0g[1]x[0]x[1]x[2]x[3]=1/21/21/201/21/21/201/21/201/21/21/201/2x[0]x[1]x[2]x[3]

下采样卷积版

这里基于公式:

aj[k]=∑mh[m−2k]aj+1[m]dj[k]=∑mg[m−2k]aj+1[m]aj+1[k]=∑mh[k−2m]aj[m]+∑mg[k−2m]dj[m](重构时,这里的aj被不断更新) \begin{aligned} a_{j}[k] & = \sum_{m} h[m-2k] a_{j+1}[m] \\ d_{j}[k] & = \sum_{m} g[m-2k] a_{j+1}[m] \\ a_{j+1}[k] & = \sum_{m} h[k-2m] a_{j}[m] + \sum_{m} g[k-2m] d_{j}[m] \quad (重构时,这里的a_{j}被不断更新) \\ \end{aligned} aj[k]dj[k]aj+1[k]=mh[m2k]aj+1[m]=mg[m2k]aj+1[m]=mh[k2m]aj[m]+mg[k2m]dj[m](重构时,这里的aj被不断更新)

对于离散序列 a[k] 和 h[m],其离散卷积定义为:(a∗h)[m]=∑ka[k]h[m−k](a * h)[m] = \sum_{k} a[k] h[m-k](ah)[m]=ka[k]h[mk]。而这里的形式其实可以看做是卷积核被翻转了。从 2k−m2k-m2km 变为了 m−2km-2km2k所以在两个系数的逐层计算中,完全可以利用下采样和基于 hhhggg 两种卷积核的卷积来计算。

具体实现

import mathimport numpy as npclass HaarWaveletTransform:def __init__(self):# Haar Coefficientsself.g_0 = self.h_1 = self.h_0 = 1 / math.sqrt(2)self.g_1 = -self.g_0print(f"[h_0, h_1, g_0, g_1]: {[self.h_0, self.h_1, self.g_0, self.g_1]}")# Haar Scale Functiondef phi(self, t) -> float:if 0 <= t < 1:return 1else:return 0def phi_jk(self, j, k, t) -> float:return 2 ** (j / 2) * self.phi(2**j * t - k)# Haar Wavelet Functiondef psi(self, t) -> float:if 0 <= t < 1 / 2:return 1elif 1 / 2 <= t < 1:return -1else:return 0def psi_jk(self, j, k, t) -> float:return 2 ** (j / 2) * self.psi(2**j * t - k)@propertydef coefficient_matrix(self):# Haar 分解矩阵是正交的,所以直接使用转置即可重构数据return np.array([[self.h_0 * self.h_0, self.h_1 * self.h_0, self.h_0 * self.h_1, self.h_1 * self.h_1],[self.h_0 * self.g_0, self.h_1 * self.g_0, self.h_0 * self.g_1, self.h_1 * self.g_1],[self.g_0, self.g_1, 0, 0],[0, 0, self.g_0, self.g_1],])def matrix_based_decompose(self, x):x = np.array(x).reshape(-1, 1)return self.coefficient_matrix.dot(x)def matrix_based_reconstruct(self, coef_matrix):return self.coefficient_matrix.T.dot(coef_matrix)def formula_based_decompose(self, x):"""分解(Decomposition)/分析(Analysis)阶段,又称 Forward DWT(正向离散小波变换)或 分析滤波器组(Analysis Filter Bank)。将原始信号通过低通/高通滤波+下采样,依次提取出每一层的近似系数(approximation)和细节系数(detail),构成系数序列。"""n_levels = math.ceil(math.log2(len(x)))n_elements = 2**n_levelsx.extend([0] * (n_elements - len(x)))a = x  # a_{J_{\max}} = xa_seq = []d_seq = []for j in range(n_levels, 0, -1):d_down = []a_down = []# print(f"Level {j}->{j - 1}")for k in range(0, len(a), 2):# print(f"{k} and {k + 1} (a[{j},{k}]={a[k]}, a[{j},{k + 1}]={a[k + 1]})")d_down.append(self.g_0 * a[k] + self.g_1 * a[k + 1])a_down.append(self.h_0 * a[k] + self.h_1 * a[k + 1])a = a_downd_seq.append(d_down)a_seq.append(a_down)assert len(a) == 1d_seq.reverse()  # from 0 to J_max-1a_seq.reverse()return a_seq, d_seqdef formula_based_reconstruct(self, a_seq, d_seq):"""重构(Reconstruction)/综合(Synthesis)阶段,又称 Inverse DWT(逆离散小波变换)或 综合滤波器组(Synthesis Filter Bank),将最粗尺度的近似系数和各层细节系数反向上采样、滤波并叠加,恢复出原始信号。"""n_elements = 2 ** len(d_seq)n_levels = len(d_seq)scale_factor = 1 / math.sqrt(n_elements)# reconstruct original signalreconstructed_x = []for t in range(n_elements):cur_t = t / n_elements# low frequencyx_t = a_seq[0][0] * self.phi_jk(0, 0, cur_t) * scale_factor# high frequencyfor j in range(n_levels):for k in range(2**j):# print(f"Collecting (j,k)={j, k}")x_t += d_seq[j][k] * self.psi_jk(j, k, cur_t) * scale_factorreconstructed_x.append(x_t)return reconstructed_xdef convolve(self, x, kernel, flip_kernel=True, verbose=False):"""x[m], 0 <= m < M, kernel[k], 0 <= k < Ky[n] = sum_{m=0}^{(K-1)+(M-1)} x[m] * kernel[n-m]"""M = len(x)K = len(kernel)O = M + K - 1  # 至少存在一个重叠if flip_kernel:kernel = kernel[::-1]  # => kernel[K-1-k]y = np.zeros(O)for n in range(O):for m in range(M):k = n - mif 0 <= k < K:y[n] += x[m] * kernel[k]if verbose:print(f"y[{n}]={y[n]}, x[{m}]={x[m]}, k[{k}]={kernel[k]}")return ydef downsample_1d(self, x):return x[1::2]def upsample_1d(self, x):y = np.zeros(len(x) * 2, dtype=x.dtype)y[::2] = xreturn ydef conv_based_decompose(self, x):"""a_{j}[k] =  \sum_{m} h[m-2k] a_{j+1}[m], d_{j}[k] = \sum_{m} g[m-2k] a_{j+1}[m]=> \sum_{m} h[(1+1k) - m] a_{j+1}[m] = \sum_{m} g[(1+2k) - m] a_{j+1}[m]=> 基于标准卷积,但是下采样需要取奇数项"""n_levels = math.ceil(math.log2(len(x)))n_elements = 2**n_levelsx = x + [0] * (n_elements - len(x))h_kernel = np.array([self.h_0, self.h_1])g_kernel = np.array([self.g_0, self.g_1])a_seq = []d_seq = []a = x  # a_{J_{\max}} = xfor j in range(n_levels, 0, -1):d = self.convolve(a, g_kernel, flip_kernel=True)a = self.convolve(a, h_kernel, flip_kernel=True)d = self.downsample_1d(d)a = self.downsample_1d(a)a_seq.append(a)d_seq.append(d)a_seq.reverse()d_seq.reverse()return a_seq, d_seqdef conv_based_reconstruct(self, a_0, d_seq):n_levels = len(d_seq)h_kernel = np.array([self.h_0, self.h_1])g_kernel = np.array([self.g_0, self.g_1])a = a_0for j in range(n_levels):a = self.upsample_1d(a)d = self.upsample_1d(d_seq[j])a = self.convolve(a, h_kernel, flip_kernel=False)d = self.convolve(d, g_kernel, flip_kernel=False)a = a[: 2 ** (j + 1)]d = d[: 2 ** (j + 1)]a = a + dreturn ax = [1, 4, -3, 0]
hwt = HaarWaveletTransform()print(">>>  Formula based decomposition and reconstruction")
a_seq, d_seq = hwt.formula_based_decompose(x)
print(a_seq, d_seq)
decoded_x = hwt.formula_based_reconstruct(a_seq, d_seq)
print(x, decoded_x)print(">>>  Convolution based decomposition and reconstruction")
a_seq, d_seq = hwt.conv_based_decompose(x)
print(a_seq, d_seq)
decoded_x = hwt.conv_based_reconstruct(a_seq[0], d_seq)
print(x, decoded_x)print(">>>  Matrix based decomposition and reconstruction")
coef = hwt.matrix_based_decompose(x)
print(coef.flatten().tolist())
decoded_x = hwt.matrix_based_reconstruct(coef)
print(x, decoded_x.flatten().tolist())
http://www.xdnf.cn/news/1120753.html

相关文章:

  • 浏览器自动化领域的MCP
  • 实战--Tlias教学管理系统(部门管理)
  • 纯CSS轮播
  • SAP ERP与微软ERP dynamics对比,两款云ERP产品有什么区别?
  • 【第零章编辑器开发与拓展】
  • 不用下载软件也能录屏?Windows 10 自带录屏功能详解
  • Postman、Apifox、Apipost用哪个? 每个的优缺点和综合比较(个人观点)
  • qt多线程的实战使用
  • 【记录】BLE|百度的旧蓝牙随身音箱手机能配对不能连接、电脑能连接不能使用的解决思路(Wireshark捕获并分析手机蓝牙报文)
  • Linux(Ubuntu)硬盘使用情况解析(已房子举例)
  • HTML面试题
  • 消费 Kafka 一个TOPIC数据,插入到另一个KAFKA的TOPIC
  • python学习2
  • ubuntu(22.04)系统上安装 MuJoCo
  • FRP Ubuntu 服务端 + MacOS 客户端配置
  • 微前端架构详解
  • 《C++初阶之STL》【泛型编程 + STL简介】
  • Nacos 技术研究文档(基于 Nacos 3)
  • 基于R语言的极值统计学及其在相关领域中的实践技术应用
  • 迅为八核高算力RK3576开发板摄像头实时推理测试 ppyoloe目标检测
  • 《亿级流量系统架构设计与实战》通用高并发架构设计 读场景
  • 文心4.5开源之路:引领技术开放新时代!
  • Go从入门到精通(22) - 一个简单web项目-统一日志输出
  • 如何单独安装设置包域名
  • LeetCode--45.跳跃游戏 II
  • 雷卯针对灵眸科技RV1106G3开发板防雷防静电方案
  • AI数字人正成为医药行业“全场景智能角色”,魔珐科技出席第24届全国医药工业信息年会
  • 2024年中国公交网络数据集(Shp/分城市)
  • 【DOCKER】-6 docker的资源限制与监控
  • 【机器学习深度学习】Ollama vs vLLM vs LMDeploy:三大本地部署框架深度对比解析