小波变换

尺度函数 : scaling function (又称为父函数 father wavelet )
小波函数 : wavelet function(又称为母函数 mother wavelet)
连续的小波变换 :CWT
离散的小波变换 :DWT

小波变换的基本知识:
不同的小波基函数,是由同一个基本小波函数经缩放和平移生成的。
小波变换是将原始图像与小波基函数以及尺度函数进行内积运算, 所以一个尺度函数和一个小波基函数就可以确定一个小波变换。
离散小波变换函数

下面先列举3条关键理解:

小波分解,分解到的"不是频率域"!可以抽象理解为"小波域",但其实没有实际内涵!傅里叶变换到频率域是有实际内涵的;
小波分解得到的"小波系数"是"没有量纲"的!它其实是"没有实际意义的数",需要做系数重构才能从"小波域"再转回到"时域";
“系数重构"与"重构信号"不是一个东西!系数重构就是把无量纲的小波分解系数变回到有意义的"时域”;"重构信号"就是把分解的完整恢复回去。

离散小波变换函数:不同的适用处于搭配函数.

分解与重构/恢复信号:
    1级分解与重构原始信号函数为: dwt和dwt2 与 idwt和idwt2;
    多级(包括1级)分解与重构原始信号函数为: wavedec和wavedec2 与 waverec和waverec2;所以wavedec可涵盖dwt。

系数重构:
    1级分解的系数重构用函数的是: upcoef和upcoef2;
    多级分解的系数重构用函数的是: wrcoef和wrcoef2。

(多级)系数提取:
    多级分解低频近似系数提取:appcoef和appcoef2;
    多解分解高频细节系数提取:detcoef和detcoef2。

说明:"系数提取"只有"多级分解"才会用的到! 1级分解是不需要"系数提取"的!因为就分成了低频和高频2个部分,直接用1维或2维分解函数的返回结果就行了!所以:多级分解的系数提取,就相当于1级分解后的返回结果的直接画图。
import pywt

db3 = pywt.Wavelet(‘db3’) # 创建一个小波对象
print(db3)
“”"
Family name: Daubechies
Short name: db
Filters length: 6 #滤波器长度
Orthogonal: True #正交
Biorthogonal: True #双正交
Symmetry: asymmetric #对称性,不对称
DWT: True #离散小波变换
CWT: False #连续小波变换
“”"

def dwt_and_idwt():
‘’’
DWT 与 IDWT (离散的小波变换=>分解与重构)
使用db2 小波函数做dwt
‘’’

x = [3, 7, 1, 1, -2, 5, 4, 6]
cA, cD = pywt.dwt(x, 'db2')      # 得到近似值和细节系数
print(cA)                        # [5.65685425 7.39923721 0.22414387 3.33677403 7.77817459]
print(cD)                        # [-2.44948974 -1.60368225 -4.44140056 -0.41361256  1.22474487]
print(pywt.idwt(cA, cD, 'db2'))  # [ 3.  7.  1.  1. -2.  5.  4.  6.]

# 传入小波对象,设置模式
w = pywt.Wavelet('sym3')
cA, cD = pywt.dwt(x, wavelet=w, mode='constant')
print(cA, cD)
print(pywt.Modes.modes)
# [ 4.38354585  3.80302657  7.31813271 -0.58565539  4.09727044  7.81994027]
# [-1.33068221 -2.78795192 -3.16825651 -0.67715519 -0.09722957 -0.07045258]
# ['zero', 'constant', 'symmetric', 'periodic', 'smooth', 'periodization', 'reflect', 'antisymmetric', 'antireflect']

print(pywt.idwt([1, 2, 0, 1], None, 'db3', 'symmetric'))
print(pywt.idwt([1, 2, 0, 1], [0, 0, 0, 0], 'db3', 'symmetric'))
# [ 0.83431373 -0.23479575  0.16178801  0.87734409]
# [ 0.83431373 -0.23479575  0.16178801  0.87734409]

def wavelet_packets():
# 小波包 wavelet packets
X = [1, 2, 3, 4, 5, 6, 7, 8]
wp = pywt.WaveletPacket(data=X, wavelet=‘db3’, mode=‘symmetric’, maxlevel=3)
print(wp.data) # [1 2 3 4 5 6 7 8 9]
print(wp.level) # 0 #分解级别为0
print(wp[‘ad’].maxlevel) # 3

# 访问小波包的子节点
# 第一层:
print(wp['a'].data)       # [ 4.52111203  1.54666942  2.57019338  5.3986205   8.20681003 11.18125264]
print(wp['a'].path)       # a

# 第2 层
print(wp['aa'].data)      # [ 3.63890166  6.00349136  2.89780988  6.80941869 15.41549196]
print(wp['ad'].data)      # [ 1.25531439 -0.60300027  0.36403471  0.59368086 -0.53821027]
print(wp['aa'].path)      # aa
print(wp['ad'].path)      # ad

# 第3 层时:
print(wp['aaa'].data)
print([node.path for node in wp.get_level(3, 'natural')])  # 获取特定层数的所有节点,第3层有8个
# ['aaa', 'aad', 'ada', 'add', 'daa', 'dad', 'dda', 'ddd']

# 依据频带频率进行划分
print([node.path for node in wp.get_level(3, 'freq')])
# ['aaa', 'aad', 'add', 'ada', 'dda', 'ddd', 'dad', 'daa']

# 从小波包中 重建数据
X = [1, 2, 3, 4, 5, 6, 7, 8]
wp = pywt.WaveletPacket(data=X, wavelet='db1', mode='symmetric', maxlevel=3)
print(wp['ad'].data)  # [-2,-2]

new_wp = pywt.WaveletPacket(data=None, wavelet='db1', mode='symmetric')
new_wp['a'] = wp['a']
new_wp['aa'] = wp['aa'].data
new_wp['ad'] = wp['ad'].data
new_wp['d'] = wp['d']
print(new_wp.reconstruct(update=False))
# new_wp['a'] = wp['a']  直接使用高低频也可进行重构
# new_wp['d'] = wp['d']
print(new_wp)  #: None
print(new_wp.reconstruct(update=True))  # 更新设置为True时。
print(new_wp)
# : [1. 2. 3. 4. 5. 6. 7. 8.]

# 获取叶子结点
print([node.path for node in new_wp.get_leaf_nodes(decompose=False)])
print([node.path for node in new_wp.get_leaf_nodes(decompose=True)])
# ['aa', 'ad', 'd']
# ['aaa', 'aad', 'ada', 'add', 'daa', 'dad', 'dda', 'ddd']

# 从小波包树中移除结点
dummy = wp.get_level(2)
for i in wp.get_leaf_nodes(False):
    print(i.path, i.data)
# aa [ 5. 13.]
# ad [-2. -2.]
# da [-1. -1.]
# dd [-1.11022302e-16  0.00000000e+00]
node = wp['ad']
print(node)  # ad: [-2. -2.]
del wp['ad']  # 删除结点
for i in wp.get_leaf_nodes(False):
    print(i.path, i.data)
# aa [ 5. 13.]
# da [-1. -1.]
# dd [-1.11022302e-16  0.00000000e+00]

print(wp.reconstruct())  # 进行重建
# [2. 3. 2. 3. 6. 7. 6. 7.]

wp['ad'].data = node.data  # 还原已删除的结点
print(wp.reconstruct())
# [1. 2. 3. 4. 5. 6. 7. 8.]

assert wp.a == wp["a"]
print(wp["a"])
# a: [ 2.12132034  4.94974747  7.77817459 10.60660172]

if name == ‘main’:
dwt_and_idwt()
wavelet_packets()