信號處理 - 小波


小波,就是很小的波,它的積分總是接近於 0;

小波 又分為 小波分解小波包分解

小波分解 只對 低頻部分 進行分解,對高頻部分不再分解,所以能夠過濾掉 高頻部分;

低頻部分 代表了 趨勢,也叫 近似信號;高頻部分 代表了 噪聲,也叫 細節信號;

 

小波包分解 則既對 低頻部分 進行分解,也對 高頻部分 進行分解;

 

對小波的理解

小波變換 就是把 一個波形 分解成 N個 低頻部分 和 M個 高頻部分 的 和; 

同一個小波基函數可以通過 平移和縮放 生成不同的小波基;

小波變換就是 把 原始信號 與 小波基函數 以及 尺度函數 進行內積運算,所以一個 小波基 和一個 尺度函數 就確定了一個小波變換;

 

類比理解:小波基 就相當於 一個 標准正交基;原始信號 與 小波基 作內積 相當於 向量在 標准正交基上做投影;

  

Python 小波用法 

CWT:連續的小波變換

DWT:離散的小波變換

 

安裝

pip install PyWavelets

 

查看所有小波族

import pywt

print(pywt.families())      # 查看所有小波基
# ['haar', 'db', 'sym', 'coif', 'bior', 'rbio', 'dmey', 'gaus', 'mexh', 'morl', 'cgau', 'shan', 'fbsp', 'cmor']
print(pywt.families(short=False))
# ['Haar', 'Daubechies', 'Symlets', 'Coiflets', 'Biorthogonal', 'Reverse biorthogonal', 'Discrete Meyer (FIR Approximation)', 'Gaussian', 'Mexican hat wavelet', 'Morlet wavelet', 'Complex Gaussian wavelets', 'Shannon wavelets', 'Frequency B-Spline wavelets', 'Complex Morlet wavelets']

 

離散 1D 小波變換 

1D 多階小波變換 wavedec

def wavedec(data, wavelet, mode='symmetric', level=None, axis=-1):
    """
    Multilevel 1D Discrete Wavelet Transform of data.
    wavelet : Wavelet object or name string    小波基
        Wavelet to use
    mode : str, optional    默認是對稱的
        Signal extension mode, see :ref:`Modes <ref-modes>`.
    level : int, optional
        Decomposition level (must be >= 0). If level is None (default) then it
        will be calculated using the ``dwt_max_level`` function.
    axis: int, optional
        Axis over which to compute the DWT. If not given, the last axis is used.

    Returns
    -------
    [cA_n, cD_n, cD_n-1, ..., cD2, cD1] : list

level 指定了 分解 階數 

返回的是 各層的小波系數     【也就是 特征值,一個 信號 分解為 多個 波形,每個 波形 對應一個 小波系數,計算 這個小波系數 的范數,就是這個 波形 對應的 能量】

 

示例

import numpy as np
from pywt import wavedec
import matplotlib.pylab as plt

np.random.seed(10)
data = np.random.random((100, ))
coeffs = wavedec(data, 'db1', level=2)     # 一維離散信號的小波變換
cA2, cD2, cD1 = coeffs      # 一個低頻,多個高頻,高頻數 取決於 level

plt.subplot(411); plt.title('original'); plt.plot(data)
plt.subplot(412); plt.title('ca2'); plt.plot(cA2)
plt.subplot(413); plt.title('cd2'); plt.plot(cD2)
plt.subplot(414); plt.title('cd1'); plt.plot(cD1)
plt.show()

 

1D 1 階小波分解    

level = 2 相當於 進行了 2 次 1階小波分解

def dwt(data, wavelet, mode='symmetric', axis=-1)

可以看到 沒有 level 參數,level 恆為 1

 

與 wavedec 進行比對,指定 wavedec level=2,結果相同

np.random.seed(10)
data = np.random.random((10, ))
coeffs = wavedec(data, 'db1', level=2)     # 一維離散信號的小波變換
cA2, cD2, cD1 = coeffs      # 一個低頻,多個高頻,高頻數 取決於 level
print(cA2)      # [1.08726236 0.84094862 0.25745065]
print(cD2)      # [-0.29518976 -0.11764496  0.        ]
print(cD1)      # [ 0.53073221 -0.08142734  0.19354246 -0.39772483  0.05711374]

### 一次 小波分解, level=1
a = data
ca = []  # 近似分量
cd = []  # 細節分量
for i in range(2):
    (a, d) = pywt.dwt(a, 'db1')  # 進行2階離散小波變換
    ca.append(a)
    cd.append(d)

print(ca)   # [array([0.5600799 , 0.97754127, 0.51145292, 0.67782802, 0.1820451 ]), array([1.08726236, 0.84094862, 0.25745065])]    ### 取最后一個 近似信號
print(cd)   # [array([ 0.53073221, -0.08142734,  0.19354246, -0.39772483,  0.05711374]), array([-0.29518976, -0.11764496,  0.        ])]

wavedec 相當於 dwt 的封裝 

 

離散 2D 小波變換 

用法 基本 等同於 1D

 

2D 1階小波變換 dwt2

def dwt2(data, wavelet, mode='symmetric', axes=(-2, -1)):
    returns (cA, (cH, cV, cD)) : tuple
       

要注意返回值,分別為低頻分量,水平高頻、垂直高頻、對角線高頻。高頻的值包含在一個tuple中

 

示例

import pywt
import pywt.data

# Load image
original = pywt.data.camera()

# Wavelet transform of image, and plot approximation and details
titles = ['Approximation', 'Horizontal detail', 'Vertical detail', 'Diagonal detail']
coeffs2 = pywt.dwt2(original, 'bior1.3')        # 2D 離散信號 小波分解
LL, (LH, HL, HH) = coeffs2
fig = plt.figure(figsize=(12, 3))
for i, a in enumerate([LL, LH, HL, HH]):
    ax = fig.add_subplot(1, 4, i + 1)
    ax.imshow(a, interpolation="nearest", cmap=plt.cm.gray)
    ax.set_title(titles[i], fontsize=10)
    ax.set_xticks([])
    ax.set_yticks([])

fig.tight_layout()
plt.show()

 

2D 多階小波變換 wavedec2

print(pywt.waverec2(coeffs, wavelet='db1',  level=3))

官網有 level 參數,我的版本沒有,應該是版本問題,暫未解決

 

信號重構

小波 經常用於 降噪,降完噪后 需要把 信號進行重構,生成無噪聲的信號,1D、2D 用法類似

def waverec(coeffs, wavelet, mode='symmetric', axis=-1)

 

示例

import numpy as np
import pywt
import matplotlib.pylab as plt

plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False

data = np.hstack([np.ones((1, 10)), np.ones((1, 50)) * 2])[0]
ca, cd2, cd1 = pywt.wavedec(data, 'db1', level=2)
plt.subplot(211)
plt.title('original')
plt.plot(data)

out = pywt.waverec([ca, cd2, cd1], 'db1')
plt.subplot(212)
plt.title('重構信號')
plt.plot(out)
plt.show()

 

小波 VS 傅里葉變換

小波變換還是比較復雜的,確切地說 如果想 徹底弄懂,基本不可能,我這里 只重點記錄下 學習心得

1. 傅里葉變換 的 基 只能是 正弦波,如果 原始波形 比較陡峭,需要無窮多的 正弦波 才能逼近 這種陡峭,計算量很大;小波基 則 比較 靈活,甚至可以自定義小波基;

2. 正弦波 會以 同樣的 幅度 在無窮大空間內做 無限震動,能量巨大;而 小波 是一個 很短的波,它的能力比較集中,而且集中在 某一點附近; 如下圖

  

之所以叫 小波,就是 跟 傅里葉的正弦波 比較起來 很小 

3. 小波 擅長 瞬時突變 信號的檢測,傅里葉變換無能為力 

 

小波 應用於 特征提取

 

代碼

#進行小波變換,提取樣本特征
wp = pywt.WaveletPacket(SingleSampleDataWavelet, wavelet='db3', mode='symmetric', maxlevel=3) #小波包三層分解
#print([node.path for node in wp.get_level(3, 'natural')])   #第3層有8個
#獲取第level層的節點系數
aaa = wp['aaa'].data #第1個節點
aad = wp['aad'].data #第2個節點
ada = wp['ada'].data #第3個節點
add = wp['add'].data #第4個節點
daa = wp['daa'].data #第5個節點
dad = wp['dad'].data #第6個節點
dda = wp['dda'].data #第7個節點
ddd = wp['ddd'].data #第8個節點
#求取節點的范數
ret1 = np.linalg.norm(aaa,ord=None) #第一個節點系數求得的范數/ 矩陣元素平方和開方
ret2 = np.linalg.norm(aad,ord=None)
ret3 = np.linalg.norm(ada,ord=None)
ret4 = np.linalg.norm(add,ord=None)
ret5 = np.linalg.norm(daa,ord=None)
ret6 = np.linalg.norm(dad,ord=None)
ret7 = np.linalg.norm(dda,ord=None)
ret8 = np.linalg.norm(ddd,ord=None)
#8個節點組合成特征向量
SingleSampleFeature = [ret1, ret2, ret3, ret4, ret5, ret6, ret7, ret8]

關鍵是 細節信號 的能量 計算,其實就是 系數(類似於特征值大小) 的 歸一化

 

 

 

參考資料:

https://www.cnblogs.com/shuimuqingyang/p/10919918.html  小波變換庫——Pywalvets 學習筆記

https://pywavelets.readthedocs.io/en/latest/ref/index.html    PyWavelets 官網

https://github.com/PyWavelets/pywt    PyWavelets git上的demo

https://blog.csdn.net/alwaystry/article/details/52756051  用法挺全的

https://zhuanlan.zhihu.com/p/44215123  小波變換完美通俗講解系列之 (一)    【原理就看這篇吧】

 

https://blog.csdn.net/zds13257177985/article/details/102896041?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase  小波包變換/能量特征提取/結果圖繪制-python代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM