【圖像處理】沃爾什變換與 python 實現


離散沃爾什變換(DWT)與DHT的實現思路其實是一致的,只是變換核需要經過一個變換,這里記錄下原理和實現方法。

哈達瑪變換核

哈達瑪變換核具有遞推性,也就是\(H_{2N}\)可以由\(H_{N}\)得到:

\[H_{2N}=\frac{1}{\sqrt{2}} \left[ \begin{array}{cc} H_{N} & H_{N} \\\\ H_{N} & -H_{N} \end{array} \right] \]

哈達瑪變換核的另一個特點是,變號次數亂序,以\(H_4\)為例,每行的變號次數分別如下:

\[H_4 = \frac{1}{2} \left[ \begin{array}{cccc} 1&1&1&1 \\ 1 &-1& 1 &-1 \\ 1 &1 &-1& -1 \\ 1 &-1 &-1 &1 \end{array} \right] \begin{array}{cccc} 0\\ 3 \\ 1 \\ 2 \end{array} \]

沃爾什變換核

沃爾什變換核可以從與哈達瑪變換核間接得到,只需將DHT的變換核按變號次序遞增重新排列即可

\[W_4 = \frac{1}{2} \left[ \begin{array}{cccc} 1&1&1&1 \\ 1 &1 &-1& -1 \\ 1 &-1 &-1 &1 \\ 1 &-1& 1 &-1 \\ \end{array} \right] \begin{array}{cccc} 0\\ 1 \\ 2 \\ 3 \end{array} \]

程序實現

生成DHT變換核

在scipy.linalg這個庫中,已經實現了DHT的變換核生成,我們可以通過以下語句調用

from scipy.linalg import hadamard
H4 = hadamard(4)

生成DWT變換核

要得到沃爾什變換核,我們要先得到DHT變換核每一行的變號次數,然后按照變號次數排列,具體實現上我采用的方法如下:

  1. 生成變號次數向量invTimes
    要獲取H矩陣的變號次數,可以對H矩陣的每行取差分,然后取絕對值求和再除2(稍微一想就明白,這里不解釋了哈),這些操作在numpy 中都有相應的函數
    diffMat = np.abs(np.diff(H))/2
    invTimes = np.sum(diffMat,axis = 1)
    
  2. 對invTimes進行排序
    對invTImes這個列向量排序並不難,問題是我們要在排序時或者排序后能對H矩陣做相同的排序操作,這里我想了很久發現可以通過numpy數組的花式索引來解決
    numpy 排序方法不止一種,但我們想要的不是排序好的數組,而是排序的過程,也即是原數組每一行排序后在哪個位置,好在 ndarray 對象有 argsort() 方法能滿足我們的需求,它返回的是原數組排序后的索引。
    #對invTImes排序會是這樣,因為argsort()返回的是索引
    invTImes[invTImes.argsort()]
    
  3. 對H矩陣做相同的排序操作
    有了以上的鋪墊,我們做相同的排序就會很簡單了
    #用invTImes的排序方法對H矩陣的行排序
    H[invTimes.argsort(),:]
    

以上過程封裝后

def hada2wal(H):
    diffMat = np.abs(np.diff(H))/2
    invTimes = np.sum(diffMat,axis = 1)
    W = H[invTimes.argsort(),:]
    return W

效果對比

H W

驗證正確性

從結果的圖來看,實現基本上是正確了,但如何確定實現正確了呢,這里用一下DWT的性質
DWT是正交變換,其變換矩陣是實正交對稱陣,也就是說,其每一行做內積的結果是0,只有與自己內積時才有非零值
因此用W矩陣與其自身做矩陣乘法
W@W
得到對角陣,驗證了結果是正交的,我們可以確定得到的沃爾什變換核是正確的


免責聲明!

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



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