【2DWT:2维离散小波变换(附Pytorch代码)】
二維離散小波變換
- 一、相關基礎
- 1.小波變換基礎函數
- 2.小波變換
- 二、原理
- 三、基本小波基:哈爾小波
- 四、代碼實現
- 參考:
圖像信號具有非平穩特性,無法使用一種確定的數學模型來描述,而小波變換的多分辨率分析特性很好地解決了這個問題。小波變化的多分辨率特性使其既可以高效描述圖像的平坦區域(低頻信息、全局信息),也可以有效處理圖像信號的局部突變(高頻信息,即圖像的邊緣輪廓等部分)。小波變換在空域和頻域同時具有良好的局部性,使其可以很好地聚焦到圖像的任意細節。
一、相關基礎
1.小波變換基礎函數
二維小波變換的基礎函數為:
其中φ(x,y)為一個可分離二維尺度函數,φ(x)為一維尺度函數;ψ1(x,y)、ψ2(x,y)、ψ3(x,y)均為“方向敏感”可分離二維小波函數,且分別表示沿著列的水平方向、行的垂直方向以及對角線方向邊緣的灰度變化 ,ψ(x)為一維小波函數。對一維離散小波變換進行推廣即可得到二維離散小波變換。
2.小波變換
對圖像每進行一次小波變換,會分解產生一個低頻子帶(LL:行低頻、列低頻)和三個高頻子帶(垂直子帶LH:行低頻、列高頻;水平子帶HL:行高頻、列低頻;對角子帶HH:行高頻、列高頻),后續小波變換基于上一級低頻子帶LL進行,依次重復,可完成對圖像的i級小波變換,其中i=(1,2,3,…I)。A圖、B圖分別為i=1時的一級小波變換分布,i=2時的二級小波變換分布,每個子帶分別包含各自對應的小波系數。可以看到,其實每次小波變換可以看做對圖像的行水平方向、列垂直方向分別進行隔點采樣,如此空間分辨率每次變為1/2,因此第i級小波變換后,其子帶空間分辨率為原圖的1/2i。
二、原理
利用二維Mallat算法,采用可分離的濾波器進行小波變換,實質上是利用一維濾波器分別對圖像數據的行和列進行一維小波變換。
小波分解實現原理如下:
原圖利用一維濾波器先進行行濾波得到L1、H1;然后進行列濾波得到四個子帶LL1、LH1、HL1、HH1。
小波變換是可逆的,進行小波分解得到的子圖可通過組合重構原圖,其實現原理如下:
1.舉個例子
假設輸入圖像I大小為M×N,且M=2m、N=2n,對其進行一級小波分解過程如下:
(1)利用一維濾波器h和g分別對輸入圖像I進行行濾波,丟棄奇數行,得到大小為M/2×N的中間輸出IL和IH;
(2)一維濾波器h和g分別對中間輸出IL和IH進行列濾波,丟棄奇數列,得到大小為M/2×N/2的分解輸出ILL、ILH和IHL、IHH;
三、基本小波基:哈爾小波
哈爾(Haar)小波是最常用的小波基,公式定義如下:
其對應的尺度函數為:
哈爾小波具有最短的支集,支集長度為1,濾波器長度為2,具有正交性和對稱性,其圖示如下:
1.舉例說明
對于一維哈爾小波變換來說,其一維高通濾波器FH=[1,-1]、一維低通濾波器FL=[1,1],假設輸入向量X[6]=[2,4,6,8,5,9],對其進行一維哈爾小波變換過程如下(圖中藍色填充表示濾波器的移動過程,黃色表示輸入數據,綠色表示對應輸出):
1)高通濾波,求相鄰元素之間差值的平均值,存儲輸入數據的細節信息:
比如輸出中的第一個元素為-1=(1×2-1×4)/2
2)低通濾波,求相鄰元素的平均值,存儲輸入數據的粗略近似信息:
比如輸出中的第一個元素為3=(1×2+1×4)/2
前面提到,二維變換只不過是將輸入的二維數據依次進行行濾波和列濾波(其實先行后列或者先列后行不影響),在此過程中行濾波和列濾波均進行一維小波變換,假設輸入圖像大小為M×N:
- 行濾波分別采用一維高通濾波器、一維低通濾波器得到對應的兩個輸出,輸出大小均為M/2×N;
- 列濾波對于行濾波的兩個輸出,同樣采用一維高通濾波器、一維低通濾波器得到對應的四個輸出,輸出大小均為M/2×N/2;
將一維哈爾小波變換推廣,進一步可得到二維哈爾小波變換的實現過程,對應的四個濾波器分別為:
假設輸入如下圖HR,左上角ABCD四個元素構成一個局部區域,依次使用上述四個濾波器對該局部區域進行計算即可得到小波分解后對應子帶中的一個元素,依次類推,計算公式如下:
四、代碼實現
def dwt_init(x):x01 = x[:, :, 0::2, :] / 2x02 = x[:, :, 1::2, :] / 2x1 = x01[:, :, :, 0::2]x2 = x02[:, :, :, 0::2]x3 = x01[:, :, :, 1::2]x4 = x02[:, :, :, 1::2]x_LL = x1 + x2 + x3 + x4x_HL = -x1 - x2 + x3 + x4x_LH = -x1 + x2 - x3 + x4x_HH = x1 - x2 - x3 + x4return torch.cat((x_LL, x_HL, x_LH, x_HH), 1)def iwt_init(x):r = 2in_batch, in_channel, in_height, in_width = x.size()# print([in_batch, in_channel, in_height, in_width])out_batch, out_channel, out_height, out_width = in_batch, int(in_channel / (r ** 2)), r * in_height, r * in_widthx1 = x[:, 0:out_channel, :, :] / 2x2 = x[:, out_channel:out_channel * 2, :, :] / 2x3 = x[:, out_channel * 2:out_channel * 3, :, :] / 2x4 = x[:, out_channel * 3:out_channel * 4, :, :] / 2h = torch.zeros([out_batch, out_channel, out_height, out_width]).float().cuda()h[:, :, 0::2, 0::2] = x1 - x2 - x3 + x4h[:, :, 1::2, 0::2] = x1 - x2 + x3 - x4h[:, :, 0::2, 1::2] = x1 + x2 - x3 - x4h[:, :, 1::2, 1::2] = x1 + x2 + x3 + x4return hclass DWT(nn.Module):def __init__(self):super(DWT, self).__init__()self.requires_grad = Falsedef forward(self, x):return dwt_init(x)class IWT(nn.Module):def __init__(self):super(IWT, self).__init__()self.requires_grad = Falsedef forward(self, x):return iwt_init(x)1.分解案例
dwt_module=DWT() x=Image.open('./iu.png') # x=Image.open('./mountain.png') x=transforms.ToTensor()(x) x=torch.unsqueeze(x,0) x=transforms.Resize(size=(256,256))(x) subbands=dwt_module(x)title=['LL','HL','LH','HH']plt.figure() for i in range(4):plt.subplot(2,2,i+1)temp=torch.permute(subbands[0,3*i:3*(i+1),:,:],dims=[1,2,0])plt.imshow(temp)plt.title(title[i])plt.axis('off') plt.show()分解結果:
2.重構案例
重構結果:
從視覺效果或者結構相似度值來看,小波變換整個過程是封閉的、無損的。
計算結構相似度SSIM值的方法可參考https://blog.csdn.net/qq_43665602/article/details/127041832,這里有詳細的說明。
參考:
(1)《數字圖像處理》,作者李俊山等。
(2)https://github.com/lpj-github-io/MWCNNv2/blob/master/MWCNN_code/model/common.py
總結
以上是生活随笔為你收集整理的【2DWT:2维离散小波变换(附Pytorch代码)】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 资金申报项目管理系统 - 功能介绍篇
- 下一篇: OJ题——狐狸算卦