数字图像处理——第七章(小波变换和多分辨率处理)

小波变换和小波包变换

  • 一、基础
    • 1.1 图像金字塔
    • 1.2 子带编码
    • 1.3 哈尔变换(Haar)
  • 二、多分辨率展开
    • 2.1 级数展开
    • 2.2 尺度函数
    • 2.3 小波函数
  • 三、小波变换
    • 3.1 一维小波变换
      • 3.1.1 小波级数展开
      • 3.1.2 离散小波变换
      • 3.1.3 连续小波变换
    • 3.2 快速小波变换
      • 3.2.1 一维情况
    • 3.3 二维小波变换
    • 3.4 快速小波变换的实现
      • 3.4.1 使用小波工具箱的快速小波变换
      • 3.4.2 不使用小波工具箱的快速小波变换
    • 3.5 小波分解结构的处理
      • 3.5.1 用于执行变换分解向量C的小波工具箱函数
      • 3.5.2 不使用小波工具箱编辑(提取、置零或修改)小波分解系数
      • 3.5.3 显示小波分解系数(显示小波变换处理后的结果)
    • 3.6 快速小波反变换的实现
  • 四、小波在图像处理中的应用
  • 五、小波包

所谓的小波的小是针对傅里叶波而言,傅里叶波指的是在时域空间无穷震荡的正弦(或余弦波)。
“小波”(wavelet)是一种“尺度”很小的波动,并具有时间和频率特性。
小波函数必须满足以下两个条件:
(1)小波必须是振荡的;
(2)小波是能量在时域非常集中的波,它的能量有限,都集中在某一点附近,即振幅只能在一个很短的一段区间上非0,即是局部化的,且积分的值为零。如下图所示
数字图像处理——第七章(小波变换和多分辨率处理)_第1张图片
可参考: 通俗易懂讲解小波变换

傅里叶变换和小波变换的区别:
■傅里叶变换:基础函数是正弦(或余弦)函数。反映的是图像的整体特征, 其频域分析具有很好的局部性,但空间(时间)域上没有局部化功能。傅立叶变换是将信号完全的放在频率域中分析,但无法给出信号在每一个时间点的变化情况,并且对时间轴上任何点的突变都会影响整个频率的信号。
■小波变换:基函数是小波,具有变化的频率和有限的持续时间。是空间(时间)和频率的局部变换,它通过伸缩平移运算对信号逐步进行多尺度细化,最终达到高频处时间细分,低频处频率细分,能自动适应时频信号分析的要求,从而可聚焦到信号的任意细节。是多分辨率理论的分析基础。
多分辨率理论:将多种学科的技术有效地统一在一起,其优势很明显,某种分辨率下所无法发现的特性在另一种分辨率下将很容易被发现。
数字图像处理——第七章(小波变换和多分辨率处理)_第2张图片
小波的性质

  • 可分离性、尺度可变性、平移性
  • 多分辨率的一致性
  • 正交性

一、基础

图像通常是由相似纹理和灰度级连成的区域,它们相结合就形成了物体。

  • 若物体的尺寸较小或对比度较低,通常以较高的分辨率进行研究
  • 若物体的尺寸较大或对比度较高,粗略的观察就已足够
  • 若较大物体和较小物体同时存在时,以不同的分辨率来研究它们将更具优势,即多分辨率分析。

以下将介绍与多分辨率分析相关的三种图像处理技术。

1.1 图像金字塔

是以多分辨率来表示图像的一种结构,结构非常有效,且概念简单。是一系列以金字塔形状排列的、分辨率逐步降低的图像集合。
金字塔底部是待处理图像的高分辨率表示,顶部则包含低分辨率的近似。向金字塔上层移动时,尺寸和分辨率逐步降低。
数字图像处理——第七章(小波变换和多分辨率处理)_第3张图片
基础级:大小为2J x 2J 或 N x N
顶点级:大小为1x1(单个像素)
第j级大小为2j x 2j ,0 <= j <= J。
但通常金字塔会截短到P+1级,即将级别限制到P来降低原图像的分辨率近似,也就是说不会到金字塔靠近顶端的位置。

第j-1级近似输出用来建立近似值金字塔;作为金字塔基级的原始图像和它的P级减少的分辨率近似都能直接获取并调整;
第j级的预测残差输出用于建立预测残差金字塔;近似值和预测残差金字塔都通过迭代计算获得。迭代算法如下:
1、初始化,原始图象大小,j=J
2、j-1级,以2为步长进行子抽样,计算输入图像减少的分辨率近似值—j-1级近似值,生成子抽样金字塔。
3、对j-1 级近似值进行步长为2的内插,并进行过滤,生成与输入图像等分辨率的预测图像。
4、输入图像和预测图像之间的差异,产生预测残差金字塔。
5、重复2、3、4步骤。
数字图像处理——第七章(小波变换和多分辨率处理)_第4张图片
金字塔低分辨率级别用于分析较大的结构或图像的整体内容;高分辨率图像适合于分析单个物体的特性。

1.2 子带编码

一幅图像被分解为一组频带受限的分量,称为子带。
■ 子带可以重组在一起无失真地重建原始图象
■ 每个子带通过对输入进行带通滤波而得到
■ 子带带宽小于原始图像带宽,子带可以进行无信息损失的抽样
■ 原始图象的重建可以通过内插、滤波、和叠加单个子带来完成
数字图像处理——第七章(小波变换和多分辨率处理)_第5张图片
该系统由两组滤波器组构成,h0(n)和h1(n)是半波段滤波器,它们的理想传递特性为H0和H1,用于将输入序列分成两个半长序列flp(n)和fhp(n),表示输入的子带。

分析滤波器组即为分解,综合滤波器组即为重构

对图像处理来说:分解就是通过下采样提取图像的低频(近似)和高频(细节)信息。每一层(尺度)的分解都是对上一层分解中的低频信息进行再分解。重构是通过上采样将分解的低频和高频信息再合并为分解前的图像的近似。

h0(n)为低通滤波器,其输出flp(n)称为f(n)的近似;h1(n)为高通滤波器,其输出flp(n)称为高频部分或细节部分
综合滤波器g0(n)和g1(n)将flp(n)和fhp(n)合并。
子带编码的目的:选择h0(n)、h1(n)、g0(n)、g1(n),以便使子带编码和解码系统的输入和输出是相同的,完成这一任务时,可以说最终系统采用了完美重建滤波器

一维滤波器用于图像处理的二维可分离滤波器。首先用于一个维度( 如垂直方向),再应用于另一个维度(如水平方向),两个阶段都执行下采样(其中一次是在第二个滤波操作之前执行的)。
数字图像处理——第七章(小波变换和多分辨率处理)_第6张图片
2↓表示以2为基进行下采样。输出的a(m,n),dV(m,n),dH(m,n),dD(m,n)分别称为输入图像的近似子带、垂直细节子带、水平字节子带和对角线细节子带。这些子带可分为4个更小的子带,更小的子带还可再分。[a为approximation的首字母,d为detail的首字母]

使用上图所示的编码系统对花瓶进行4子带分离。
数字图像处理——第七章(小波变换和多分辨率处理)_第7张图片

1.3 哈尔变换(Haar)

哈尔变换的基函数是已知的最古老、也是最简单的正交小波。
哈尔变换可用如下矩阵形式表示:
在这里插入图片描述
F是一个N x N图像矩阵,H是一个N x N哈尔变换矩阵,T是一个N x N变换结果。
H包含哈尔基函数hk(z),z∈[0,1],k = 0,1,2,…,N-1,其中N = 2n。要生成矩阵H,要定义整数k,k = 2p + q - 1,其中0<= p <= n-1,当p = 0时,q = 0或1;当p≠0时,1<= q <= 2n
数字图像处理——第七章(小波变换和多分辨率处理)_第8张图片
N x N哈尔变换矩阵的第i行包含了元素hi(z),其中z = 0/N,1/N,2/N,…,(N-1)/N。
如2 x 2的哈尔变换矩阵为:
在这里插入图片描述
当N = 4时,且假设k,p,q的值如下:
数字图像处理——第七章(小波变换和多分辨率处理)_第9张图片
时,4 x 4的变换矩阵H4为:
数字图像处理——第七章(小波变换和多分辨率处理)_第10张图片
H2的行可用于定义一个2抽头完美重建滤波器组(见子带编码)的分析滤波器h0(n)和h1(n),以及最简单且最古老的小波变换的缩放比例和小波向量。

二、多分辨率展开

在多分辨率分析(MRA)中,尺度函数被用于建立一个函数或一幅图像的一系列近似,相邻两近似之间的分辨率相差2倍。使用称为小波的附加函数来对相邻近似之间的差进行编码。

2.1 级数展开

一个信号或函数f(x)可展开为函数的线性组合:
在这里插入图片描述
k为有限和或无限和的整数下标,αk为展开系数,φk(x)为展开函数。
展开唯一,即任意给定的f(x)只有一组αk与之对应。则φk(x)称为基函数,集合{φk(x)}称为可表示这样一类函数的
可展开的函数形成了一个函数空间,称为展开集合的闭合跨度,表示如下:
在这里插入图片描述
对任意函数空间V及相应的展开集合{φk(x)},都有一个表示为{φk ̃(x)}的对偶函数集合。展开系数αk即是对偶函数φk ̃(x)和函数f(x)的内积。
在这里插入图片描述

2.2 尺度函数

考虑由实、平方可积函数φ(x)的整数平移和二值尺度组成的展开函数集合{φj,k(x)}
在这里插入图片描述
其中φj,k(x)对所有的j,k∈Z(整数集)和φ(x)属于L2(R)都成立(L2(R)表示度量的、平方可积的一维函数集合,R为实数集)。
整数平移k决定了φj,k(x)沿x轴的位置;尺度j决定了φj,k(x)的宽度;2j/2控制函数的幅度。
因为φj,k(x)的形状随j发生变化,故φ(x)称为尺度函数
选择适当的φ(x),可使{φj,k(x)}张成L2(R)。
对任意的j,将k上张成的子空间表示为:
在这里插入图片描述
增加j就会增加Vj的大小,进而允许子空间中包含具有更小变量或更细细节的函数。因为随着j的增大,用于表示子空间函数的φj,k(x)会变窄,且x有较小变化就可以分开。
在这里插入图片描述
hφ(n)为小波函数系数,hφ为小波向量。

2.3 小波函数

满足MRA要求的尺度函数被定义为小波函数ψ(x),它与其整数平移及二值尺度一起,跨越了任意连个相邻尺度子空间Vj和Vj+1之间的差。
数字图像处理——第七章(小波变换和多分辨率处理)_第11张图片
对跨越图中Wj空间的所有k∈Z,定义小波集合{ψj,k(x)}
在这里插入图片描述
使用尺度函数,可以写出:
在这里插入图片描述
如果f(x)∈Wj,则
在这里插入图片描述
尺度函数和小波函数子空间由下式联系起来
在这里插入图片描述
⨁表示空间并集,Vj+1中Vj的正交补集是Wj,且Vj中的所有成员与Wj中的所有成员都正交。故
在这里插入图片描述
所有可度量的、平方可积的函数空间可以表示为
数字图像处理——第七章(小波变换和多分辨率处理)_第12张图片
若f(x)是V1而非V0的元素,则(1)式的展开包含使用V0尺度函数的f(x)的近似;来自W0的小波将对这种近似于实际函数之间的差进行编码。故可推广:
在这里插入图片描述
j0是任意开始尺度。
因为小波空间存在于由相邻较高分辨率尺度函数跨越的空间中,故小波函数可表示成平移后的双倍分辨率尺度函数的加权和,表示如下:
在这里插入图片描述
hψ(n)为小波函数系数,hψ为小波向量。
利用小波跨越正交补集空间和整数小波平移是正交的条件,可得hψ(n)和hφ(n)按下述方式相关:
在这里插入图片描述

三、小波变换

3.1 一维小波变换

3.1.1 小波级数展开

与小波ψ(x)和尺度函数φ(x)相关的函数f(x)∈L2(R)的小波级数展开如下:
在这里插入图片描述
j0是任意的开始尺度,cj0(k)和dj(k)分别是尺度函数和小波函数下的展开系数αk的改写形式。cj0(k)称为近似和/或尺度系数,dj(k)称为细节和/小波系数。
哈哈啊
在这里插入图片描述
即为被展开的函数和展开函数的内积。

3.1.2 离散小波变换

上一小节的小波系数展开将一个连续变量函数映射为一系列系数。若待展开的函数是离散的(即数字序列),则得到的系数就称为离散小波变换(DWT)。则序列f(n)的正向DWT系数(类似于上一节的cj0(k)和dj(k))如下:
数字图像处理——第七章(小波变换和多分辨率处理)_第13张图片
其中φj0,k(n)ψj,k(n)是基函数φj0,k(x)ψj,k(x)的取样形式,n = 0,1,2,…,M-1。所以f(n)的展开如下:
在这里插入图片描述

3.1.3 连续小波变换

离散小波变换的自然延伸是连续小波变换(CWT),连续小波变换将一个连续函数变换为两个连续变量(平移和尺度)的高冗余度函数。得到的变换易于解释并且对于时间-频率分析是有价值的。我们感兴趣的是离散图像,此处只是为了完整性。
连续平方可积函数f(x)的连续小波变换与实数值小波ψ(x)的关系定义如下:
在这里插入图片描述
其中
在这里插入图片描述
s和τ分别为尺度参数和平移参数
f(x)可由连续小波反变换求得:
在这里插入图片描述
其中
在这里插入图片描述
式中Ψ(μ)是ψ(x)的傅里叶变换。

3.2 快速小波变换

快速小波变换(FWT)是一种实现离散小波变换(DWT)的高效计算。类似于2子带的子带编码方案。

正变换,即分解
先定义尺度函数和小波函数,再计算尺度j的近似和细节系数。

3.2.1 一维情况

由前面描述的尺度函数和小波函数
数字图像处理——第七章(小波变换和多分辨率处理)_第14张图片
其中hφ(n)为尺度函数系数,hφ为尺度向量;hψ(n)为小波函数系数,hψ为小波向量。
用2j对x进行尺度化,用k对它进行平移,并令m = 2k + n,则
尺度函数:
数字图像处理——第七章(小波变换和多分辨率处理)_第15张图片
小波函数
在这里插入图片描述
近似系数和细节系数如下:
数字图像处理——第七章(小波变换和多分辨率处理)_第16张图片
hφ(-n) = h0(n)(2带子带编码和解码系统中的分析部分),hψ(-n) = h1(n)
在这里插入图片描述
数字图像处理——第七章(小波变换和多分辨率处理)_第17张图片
反变换,即重构
快速小波反变换
反变换即综合滤波器,综合滤波器和分析滤波器之间的顺序是相反的。
g0(n) =h0(-n) = hφ(n) =,g1(n) = h1(-n) = hψ(n)
在这里插入图片描述
数字图像处理——第七章(小波变换和多分辨率处理)_第18张图片

3.3 二维小波变换

在二维情况下,需要一个二维尺度函数φ(x,y)和三个二维小波ψH(x,y),ψV(x,y),ψD(x,y)。每个二维小波都是两个一维函数的乘积。排除产生一维结果的乘积,如φ(x)ψ(x),4个剩下的乘积可产生尺度函数
在这里插入图片描述
和可分的“方向敏感”小波
数字图像处理——第七章(小波变换和多分辨率处理)_第19张图片
这些小波度量函数的变化——图像的灰度变化——沿不同方向的变化:ψH度量沿列方向的变化(如水平边缘),ψV响应沿行方向的变化(如垂直边缘),ψD度量对应对角线方向的变化。
定义尺度和平移基函数:
在这里插入图片描述
故大小为M*N的图像f(x,y)的离散小波变换是:
数字图像处理——第七章(小波变换和多分辨率处理)_第20张图片
通常令j0 = 0,并选择N = M = 2J,故j = 0,1,2,…,J-1和m = n = 0,1,2,…,2j-1。
f(x,y)可通过离散小波反变换得到:
数字图像处理——第七章(小波变换和多分辨率处理)_第21张图片
数字图像处理——第七章(小波变换和多分辨率处理)_第22张图片
数字图像处理——第七章(小波变换和多分辨率处理)_第23张图片

3.4 快速小波变换的实现

3.4.1 使用小波工具箱的快速小波变换

wfilters 小波滤波器

[Lo_D,Hi_D,Lo_R,Hi_R] = wfilters(wname)

输出Lo_D,Hi_D,Lo_R和Hi_R是行向量,分别返回与wname相关低通分解、高通分解、低通重构和高通重构滤波器。wname是正交或双正交小波的名字,决定返回的滤波器系数,下表中一一列出
在这里插入图片描述

[F1,F2] = wfilters(wname,type)

返回一对与wname相关的type类型滤波器。type可取’d’、‘r’、‘l’、‘h’四种值。
分解或低通滤波器在F1中返回,重构或高通滤波器放在F2中。
如:wfilters(‘db6’,‘h’) 返回一对与db6相关的高通滤波器(包括高通分解和高通重建)
数字图像处理——第七章(小波变换和多分辨率处理)_第24张图片
waveinfo 查看小波家族(即wname中的内容)

waveinfo(wfamily)

wavefun 小波和尺度函数

[phi,psi,xval] = wavefun(wname,iter)
% 对正交变换。返回与wname相关的小波和尺度函数的近似向量phi和psi,近似向量是在网格点xval处估计的。正整数iter控制计算的迭代次数,可决定近似值的精度。
[phi1,psi1,phi2,psi2,xval] = wavefun(wname,iter)
% 对双正交变换。phi1和psi1对应分解函数,phi2和psi2对应重构函数。
[psi,xval] = wavefun(wname,iter)
% 对没有尺度函数的小波,如Morlet小波、Mexcian小波、Gaussian derivatives小波和复小波。

% 二维小波和尺度函数(只用于正交小波)
[S,W1,W2,W3,XYVAL] = wavefun2('wname',ITER)   % S为尺度函数,W1,W2,W3为三个“方向敏感”的小波函数
[S,W1,W2,W3,XYVAL] = wavefun2('wname',ITER,'plot')  % 计算并画出函数图像

dwt2 二维离散小波变换(单尺度)

[cA,cH,cV,cD]=dwt2(X,'wname')   %使用指定的小波基函数对矩阵X进行二维离散小波变换
[cA,cH,cV,cD]=dwt2(X,Lo_D,Hi_D)  %使用指定的低通滤波器Lo_D和高通滤波器Hi_D分解信号
                                 % cA--近似分量(低频分量) cH--水平方向细节分量 cV--垂直方向细节分量;cD--对角方向细节分量

示例

A=imread('C:\Users\win\Desktop\girl.jpg');
[cA,cH,cV,cD]=dwt2(A,'haar');%使用haar小波
figure,imshow(A);title('原图');
figure,subplot(2,2,1);imshow(cA/255);title('低频分量');
subplot(2,2,2),imshow(cH),title('水平细节分量');
subplot(2,2,3),imshow(cV),title('垂直细节分量');
subplot(2,2,4),imshow(cD),title('对角线细节分量');

数字图像处理——第七章(小波变换和多分辨率处理)_第25张图片
数字图像处理——第七章(小波变换和多分辨率处理)_第26张图片
wavedec2 二维多尺度分解

wavedec2  可直接处理彩色图像
[C,S] = wavedec2(X,N,wname)  % 对图像X用wname小波基函数实现N尺度(级数)分解。
[C,S] = wavedec2(X,N,Lod,Hid) % 用特定的低通和高通滤波器(Lod和Hid)进行小波分解。

对第一种情况进行解析
经过小波分解之后得到的所有图像都被称为小波系数。C为小波分解向量,即各层分解系数,S为各层分解系数长度,也就是大小.。
C的结构:
C=[A(N)|H(N)|V(N)|D(N)|H(N-1)|V(N-1)|D(N-1)|H(N-2)|V(N-2)|D(N-2)|…|H(1)|V(1)|D(1)]
C是一个行向量,即:1*(size(X)),(e.g,X=256256,then c大小为:1(256256)=165536)
A(N)代表第N层低频系数,即图像第N层的近似,尺度最小,在金字塔中就是每层的下采样的图像,在金字塔中,在第N-1层下采样到N层,N层的图像维度(尺度)变小了,也就意味着在下采样过程中丢失了信息,丢失的信息实质是高频信息,这些信息在小波分解中可以通过HVD这些高频分量来保存。
H(N)|V(N)|D(N)代表第N层高频系数,分别是水平,垂直,对角高频,以此类推,到H(1)|V(1)|D(1).故C包含3N+1个部分。
每一次的小波分解都是在近似图像上进行分解。a为近似图像
数字图像处理——第七章(小波变换和多分辨率处理)_第27张图片
(l)LL子带是图像的近似表示。
(2)HL子带是水平子带
(3)LH子带是垂直子带
(4)HH子带是对角子带
S的结构:
S是一个大小为(N+2)*2的记录数组,储存各层分解系数大小。其形式为:
S = [sa(N,:) sd(N,:) sd(N-1,:) … sd(1,:) sX]
sa(N,:) sd(i,:) sX分别包含第N级的近似矩阵A(N)的水平和垂直维数,第i尺度的细节(水平、垂直和对角线)和原图像X的大小。
即第一行是A(N)的大小,第二行是H(N)|V(N)|D(N)|的大小,第三行是 H(N-1)|V(N-1)|D(N-1)的大小,倒数第二行是H(1)|V(1)|D(1)大小,最后一行是X的大小。S中的元素是以列向量的形式组织的。
示例

X=imread('C:\Users\win\Desktop\girl.jpg');
[c,s]=wavedec2(X,2,'db1');%进行2尺度二维离散小波分解。分解小波函数:db1
[cH1,cV1,cD1]=detcoef2('all',c,s,1);%尺度1的所有方向的高频系数
[cH2,cV2,cD2]=detcoef2('all',c,s,2);%尺度2的所有方向的高频系数
cA1=appcoef2(c,s,'db1',1);%尺度1的低频系数
cA2=appcoef2(c,s,'db1',2);%尺度2的低频系数

figure;
subplot(2,2,[1,2]),imshow(X);title('原图');
subplot(2,2,3),imshow(uint8(cA1));title('尺度1的低频系数图像');
subplot(2,2,4),imshow(uint8(cA2));title('尺度2的低频系数图像');
figure;
subplot(2,3,1),imshow(uint8(cH1));title('尺度1水平方向高频系数');
subplot(2,3,2),imshow(uint8(cV1));title('尺度1垂直方向高频系数');
subplot(2,3,3),imshow(uint8(cD1));title('尺度1斜线方向高频系数');
subplot(2,3,4),imshow(uint8(cH2));title('尺度2水平方向高频系数');
subplot(2,3,5),imshow(uint8(cV2));title('尺度2垂直方向高频系数');
subplot(2,3,6),imshow(uint8(cD2));title('尺度2斜线方向高频系数');

数字图像处理——第七章(小波变换和多分辨率处理)_第28张图片
数字图像处理——第七章(小波变换和多分辨率处理)_第29张图片
快速小波 变换可能会导致边界失真,为了将失真减到最小,需要对边界进行填充扩展。可使用dwtmode(离散小波变换扩展模式)来扩展及填充待处理的图像。

dwtmode(mode)  % 设置离散小波变换和小波包变换的图像扩展模式
st = dwtmode('status') % 显示当前模式并返回到st
st = dwtmode('status','nodisp')  % 返回当前模式st,并且在MATLAB命令窗口中不显示任何状态或警告文本。
dwtmode('save',mode)  % 保存mode作为新的默认模式

数字图像处理——第七章(小波变换和多分辨率处理)_第30张图片
例: [cA,cH,cV,cD] = dwt2(x,‘db4’,‘mode’,‘per’);

3.4.2 不使用小波工具箱的快速小波变换

将使用wavefilter和wavefast函数来代替小波工具箱函数wfilters和wavedec2函数。
wavefilter.m

function [varargout] = wavefilter(wname,type)
% wavefilter 生成小波分解和重构滤波器
% 返回分解和/或重构滤波器
% [ld,hd,lr,hr] = wavefilter('haar') 得到基于haar小波的低和高分解滤波器(ld,hd)和重构滤波器(lr,hr)
% [ld,hd] = wavefilter('haar','d') 得到分解滤波器
% [lr,hr] = wavefilter('haar','r') 得到重构滤波器
% type:d(分解)和r(重构)

% 检查输入和输出参数
narginchk(1,2); % narginchk 来检查输入参数的个数在期望的范围内.输入参数nargin个数小于1或大于2则产生错误
if (nargin == 1 && nargout ~= 4) || (nargin ==2 && nargout ~= 2)
    error('输出参数数量无效')
end
if nargin == 1 && ~ischar(wname)
    error('wname必须是字符串');
end
if nargin == 2 && ~ischar(type)
    error('type必须是字符串');
end

% 生成滤波器
switch lower(wname)
    case {'haar','db1'}   % 标准正交滤波器
        ld = [1 1] / sqrt(2);
        hd = [-1 1] /sqrt(2);
        lr = ld;
        hr = -hd;
    case'db4' % 标准正交滤波器
        ld=[-1.059740178499728e-002 3.288301166698295e-00 ...
            3.084138183598697e-002 -1.870348117188811e-001...
            -2.79837641698385e-002 6.308807679295904-001 ...
            7.148465705525415e-001 2.303778133088552e-001];
        t=(0:7);
        hd=ld; hd(end:-1:1)=cos(pi*t).*ld;
        lr=ld; lr(end:-1:1)=ld;
        hr=cos(pi*t).*ld;
        
    case'sym4'  % 标准正交滤波器
        ld=[-7.576571478927333e-002 -2.963552764599851e-002...
            4.976186676320155e-001 8.037387518059161e-001...
            2.978577956052774e-001 -9.921954357684722e-002...
            -1.260396726203783e-002 3.222310060404270e-002];
        t=(0:7);
        hd=ld; hd(end:-1:1)=cos(pi*t).*ld;
        lr=ld; lr(end:-1:1)=ld;
        hr=cos(pi*t).*ld;
        
    case'bior6.8'  % 双正交滤波器
        ld=[0 1.908831736481291e-003 -1.914286129088767e-003...
            -1.699063986760234e-002 1.193456527972926e-002...
            4.973290349094079e-002 -7.726317316720414e-002...
            -9.405920439573646e-002 4.207962846098268e-001...
            8.259229974584023e-001 4.207962846098268e-001...
            -9.405920920349573646e-002 -7.726317316720414e-002...
            4.973290349094079e-002 1.19345652792926e-002...
            -1.699063986760234e-002 -1.914286129088767e-003...
            1.908831736481291e-003];
        hd=[0 0 0 1.442628250562444e-002 -1.446750489679015e-002...
            -7.872200106262882e-002 4.036797903033992e-002...
            4.178491091502746e-001 -7.589077294536542e-001...
            4.178491091502746e-001 4.036797903033992e-002...
            -7.872200106262882e-002 -1.446750489679015e-002...
            1.442628250562444e-002 0 0 0 0];
        t=(0:17);
        lr=cos(pi*(t+1)).*hd;
        hr=cos(pi*t).*ld;
        
    case'jpeg.7'  % 双正交滤波器
        ld=[0 0.2674875741080976 -0.01686411844287495...
            -0.07822326652898785 0.2668641184428723...
            0.6029490182363579 0.2668641184428723...
            -0.07822326652898785 -0.01686411844287495...
            0.02674875741070976];
        hd=[0 -0.9127176311424948 0.05754352622849957...
            0.5912717631142470 -1.115087052456994...
            0.5912717631142470 0.05754352622849957...
            -0.09127176311424948 0 0];
        t=(0:9);
        lr=cos(pi*(t+1).*hd);
        hr=cos(pi*t).*ld;
        
    otherwise
        error('未识别小波名称');
end

%输出需要的滤波器
if (nargin==1)
    varargout(1:4)={ld,hd,lr,hr};
else 
    switch lower(type(1))
        case'd'
            varargout={ld,hd};
        case'r'
            varargout={lr,hr};
        otherwise
            error('未识别滤波器类型.');
    end
end  

wavefast.m
注: wavefast用于处理灰度图像

function [c,s] = wavefast(x,n,varargin)
% wavefast 多尺度2维快速小波变换(即小波分解)
% [C,L] = wavefast(x,n,lp,hp) 基于分解滤波器lp和hp,图像x的二维n尺度下的快速小波变换
% [C,L] = wavefast(x,n,wname) 小波wname使用wavefilter得到的分解滤波器(lp和hp)
% n必须小于或等于图像的尺寸最大值的log2.滤波器的lp和hp必须是偶数
% 为减少边界失真,x是对称扩展的。若x = [c1 c2 c3 … cn](1维情况下),则对称扩展为[… c3 c2 c1 c1 c2 c3 … cn cn cn-1 cn-2 …]
% 输出:
% 矩阵C是一个系数分解向量   C = [a(n) h(n) v(n) d(n) h(n-1) … v(1) d(1)]
% a,h,v,d分别是近似、水平、竖直和对角线系数。C有3n+1部分,其中n是小波分解数
% 矩阵S是一个(n + 2) * 2 的记录矩阵
% S = [sa(n,:);sd(n,:);sd(n-1,:);… sd(1,:);sx] 其中sa和sd是近似和细节尺寸

% 检查输入参数的合理性
narginchk(3,4);
if nargin == 3
    if ischar(varargin{1}) % 判断wname是否是字符串
        [lp,hp] = wavefilter(varargin{1},'d');
    else
        error('错误的小波名称');
    end
else
    lp = varargin{1};hp = varargin{2};
end
fl = length(lp);sx = size(x);
if (ndims(x) ~= 2)||(min(sx) < 2)|| ~isreal(x)|| ~isnumeric(x)  % ndims:数组维度数目
    error('x必须是实数矩阵');
end
if (ndims(lp) ~= 2)|| ~isreal(lp)|| ~isnumeric(lp)...
        || (ndims(hp) ~= 2)|| ~isreal(hp)|| ~isnumeric(hp)...
        || (f1 ~= length(hp))|| rem(fl,2) ~= 0     % rem(x,y):求整除x/y的余数
    error('lp和hp必须是偶数并且长度相等, ... 数值型滤波器向量.');
end
if ~isreal(n)||~isnumeric(n)||(n<1)||(n > log2(max(sx)))
    error('n必须是个实数标量介于1到 ... log2(max(size(x)))');
end

% 设置初始输出数据结构和初始近似值
c = [];s = sx;app = double(x);
% 对于每个分解
for i = 1:n
    % 对称地扩展近似值
    [app,keep] = symextend(app,fl);
    % 用hp和下采样计算卷积行。然后用hp和lp得到的卷积列去获取对角线和垂直的系数。
    rows = symconv(app,hp,'row',fl,keep);
    coefs = symconv(rows,hp,'col',fl,keep);
    c = [coefs(:)' c]; s = [size(coefs);s];
    coefs = symconv(rows,lp,'col',fl,keep);
    c = [coefs(:)' c];
    % 用hp和采样率计算卷积行。然后用hp和lp得到的卷积列去获取垂直的和下一个近似的系数。
    rows=symconv(app,lp,'row',fl,keep);
    coefs=symconv(rows,hp,'col',fl,keep);
    c=[coefs(:)' c];
    app=symconv(rows,lp,'col',fl,keep);
end

%追加最后的近似值结构
c=[app(:)' c]; s=[size(app);s];

%---------------------------------------------------------------%
function [y,keep] = symextend(x,fl)
% 计算卷积和下采样后的系数放在keep中,然后在两个维度上扩展x
keep = floor((fl + size(x) - 1) / 2);
y = padarray(x,[(fl - 1) (fl - 1)],'symmetric','both'); 
    % fp = padarray(f,[r,c],method,direction)对图像进行填充 
    % f为输入图像,fp为填充后的图像,[r,c]给出填充f的行数和列数,method表示填充方法,direction表示填充的方向
    % 若参数中不包括direction,则默认为'both'(在每一维的第一个元素前和最后一个元素后填充)
%----------------------------------------------------------------%
function y = symconv(x,h,type,fl,keep)
% 用h和下采样,卷积x的行或列,并提取对称扩展的中心部分 
if strcmp(type,'row')
    y = conv2(x,h); % conv2 :二维卷积
    y = y(:,1:2:end); % 抛弃偶数索引行或列(即以2下取样)
    y = y(:,fl / 2 + 1:fl / 2 + keep(2)); % 提取每行或列的中心keep元素
else
    y = conv2(x,h');
    y = y(1:2:end,:);
    y = y(fl / 2 + 1:fl / 2 + keep(1),:);
end

当产生实际上相同的结果时,自定义函数wavefast的速度要比对应的wavedec2函数几乎快两倍。

3.5 小波分解结构的处理

3.5.1 用于执行变换分解向量C的小波工具箱函数

>> X = magic(8);
>> [C,S] = wavedec2(X,3,'haar');
>> size(C)
ans =
     1    64
>> S
S =
     1     1
     1     1
     2     2
     4     4
     8     8

使用函数wavedec2进行3尺度haar小波分解。C的大小为1 x 64,S的大小为5 x 2。因为是N = 3级(尺度)分解,故C中会有3N + 1 = 10个近似和细节子矩阵的元素。基于S,这些子矩阵包括:(a)分解级别3:一个大小为1 x 1的近似矩阵和3个大小为1 x 1的细节矩阵;(b)分解级别2:3个大小为2 x 2的细节矩阵;©分解级别1:3个大小为4 x 4的细节矩阵。最后一行包含了原图像X的尺寸大小。

appcoef2 提取二维近似(低频)系数

A = appcoef2(C,S,wname) % 使用二维小波分解结构和wname指定的小波,提取近似系数
A = appcoef2(C,S,LoR,HiR) % 使用低通重构和高通重构滤波器提取近似系数
A = appcoef2(___,N) % 返回第N尺度的近似系数

detcoef2 提取二维细节(高频)系数

D = detcoef2(O,C,S,N)  % 从小波分解结构中提取水平、竖直或对角线细节系数,O = ‘h’(或'v'或'd'),N为尺度,必须是整数,且1≤N≤size(S,1)-2。
[H,V,D] = detcoef2('all',C,S,N)  % 返回N尺度上的水平、竖直和对角线细节系数。等同于detcoef2('a',C,S,N)
D = detcoef2('compact',C,S,N)  % 返回N尺度上的细节系数,并以行的形式存储。

wthcoef2 二维小波系数阈值化

NC = wthcoef2(type,C,S,N,T,SORH)  % type为近似系数‘a’或细节系数‘h’、‘v’、‘d’。N是分解等级的一个向量,该向量将基于向量T中的相应阈值进行阈值处理。SORH针对软硬阈值处理分别设置为's'或'h'。若省略T,则所有满足type和N规范的系数都将赋值为零。

3.5.2 不使用小波工具箱编辑(提取、置零或修改)小波分解系数

wavework.m

function [varargout] = wavework(opcode,type,c,s,n,x)
% wavework 用于编辑小波分解系数
% 通过type和尺度n获取分解系数,基于opcode进行访问或修改

% opcode      
% 'copy'     [varargout] = Y  获得需要的类型type第n尺度的系数矩阵
% 'cut'      [varargout] = [NC,Y]  将type类型下c中的分解系数Y置零,保存在新的分解向量NC中
% 'paste'    [varargout] = [NC]   % 用x的元素代替type类型下c中的分解系数,并将新的分解结构放到NC中

% type   近似系数'a'或细节系数'h','v','d'
% [c,s]  是小波工具箱分解结构
% n      是分解尺度(分解级数)(若type = 'a'则忽略)
% x      是用于复制的二维系数矩阵

% 检查输入参数的合理性
narginchk(4,6);

if (~ismatrix(c)) || (size(c,1)~=1)
    error('C必须是一个行向量.')
end

if (~ismatrix(s) || ~isreal(s) || ~isnumeric(s) || (size(s,2)) ~=2)
    error('S必须是一个实数数值型的两列数组');
end

elements=prod(s,2); %c的每个系数子矩阵中的元素数。 prod:数组元素的乘积,结果为包含每一行乘积的列向量
if (length(c)=elements(end))
    error(['[c,s] 必须是一个标准的小波分解' '结构.']);
end

if nargin<5
    n=1;%默认尺度(分级)为1
end
nmax=size(s,1)-2; % 在[c,s]下最大尺度(分级)
aflag=(lower(type(1))=='a');
if ~aflag && (n>nmax)
    error('N超过了[c,s]下的分解.'); % 尺度大过了分解的最大尺度
end

switch lower(type(1))  %指向type和n的相关系数的一对指针
    case 'a' 
        nindex=1;
        start=1; % 开始索引
        stop=elements(1); %结束索引 近似矩阵中的元素的数量
        ntst=nmax;
    case{'h','v','d'}
        switch type
            case 'h',offset=0; %细节的补偿值
            case 'v',offset=1;
            case 'd',offset=2;
        end
        nindex=size(s,1)-n; %索引到详细信息
        start=elements(1)+3*sum(elements(2:nmax-n+1))+...
               offset*elements(nindex)+1;
        stop=start+elements(nindex)-1;
        ntst=n;
    otherwise
        error('TYPE 必须是 ''a'',''h'',''v'',或''d''.');
end

switch lower(opcode)    %执行opcode要求的操作
    case{'copy','cut'}  % copy:提取type类型下的c的分解系数并复制到y中; cut:提取type类型下c的分解系数,将其置零并复制到y中。而y是一个已预分配好的二维矩阵,其大小由s决定
        y=repmat(0,s(nindex,:));
        y(:)=c(start:stop);nc=c;
        if strcmpi(opcode(1:3),'cut')
            nc(start:stop)=0;varargout={nc,y};
        else
            varargout={y};
        end
    case'paste' 
        if numel(x) ~= elements(end-ntst)
            error('X is not sized for the requested paste.');
        else
            nc=c;nc(start:stop)=x(:);varargout={nc};
        end
    otherwise
        error('不能识别OPCODE.')
end

wavecopy、wavecut和wavepaste分别使用wavework处理(提取,置零或修改)小波分解结构中的C

wavecopy.m

function y = wavecopy(type,c,s,n)
% wavecopy 获取第n尺度(级别)小波分解结构的系数矩阵
% 返回基于type和n的系数矩阵
% type  :近似系数'a'或细节系数'h','v,'d'
% [c,s]  是小波分解结构
% n是分解尺度(级数)(若type = 'a'则忽略)

% 检查输入参数的合理性
narginchk(3,4);
if nargin == 4
    y = wavework('copy',type,c,s,n);
else
    y = wavework('copy',type,c,s);
end

wavecut.m

function [nc,y] = wavecut(type,c,s,n)
% wavecut 小波分解结构中的零系数
% 返回细节或近似系数矩阵y置零的新的分解向量nc(基于type和n)。
% type  :近似系数'a'或细节系数'h','v,'d'
% [c,s]  是小波分解结构
% n是分解尺度(级数)(若type = 'a'则忽略)

% 检查输入参数的合理性
narginchk(3,4);
if nargin == 4
    [nc,y] = wavework('cut',type,c,s,n);
else
    [nc,y] = wavework('cut',type,c,s);
end

wavepast.m

function nc = wavepaste(type,c,s,n,x)
% wavepaste 将type类型的系数矩阵x复制于小波分析结构的c中
% 基于type和n,将x复制到c里面,然后返回一个新的分解结构
% type  :近似系数'a'或细节系数'h','v,'d'
% [c,s]  是小波分解结构
% n是分解尺度(级数)(若type = 'a'则忽略)
% x 是一个二维近似或细节系数矩阵,矩阵的维度适合于分解尺度(级别)n

narginchk(5,5);
nc = wavework('paste',type,c,s,n,x);

再次说明:
wavecopy:通过type和尺度n获取小波分解结构C中对应的分解系数
wavecut:通过type和尺度n获得小波分解结构C中对应的分解系数y之后,将其置零,然后返回新的小波分解结构NC和y
wavepaste:通过type和尺度n获得小波分解结构C中对应的分解系数,然后使用x对其进行替换,返回新的小波分解结构NC

示例

>> f = magic(8);
>> [c1,s1] = wavedec2(f,3,'haar');  % 获得小波分解结构
>> approx = wavecopy('a',c1,s1)  % 提取近似系数
approx =
  260.0000 
>> horizdet2 = wavecopy('h',c1,s1,2)  % 提取水平细节系数
horizdet2 =
   1.0e-13 *
         0   -0.2842
         0         0
>> [newc1,horizdet2] = wavecut('h',c1,s1,2);  % 将水平细节系数置零,并返回到新的小波分解结构newc1中
>> horizdet2
horizdet2 =
   1.0e-13 *
         0   -0.2842
         0         0
>>  newhorizdet2 = wavecopy('h',newc1,s1,2)  % 提取newc1中的水平细节系数
newhorizdet2 =
     0     0
     0     0

3.5.3 显示小波分解系数(显示小波变换处理后的结果)

wave2gray 用于显示小波分解系数。小波分解系数就是不同尺度n下的分解图像。
wave2gray.m

function w = wave2gray(c,s,scale,border)
%wave2gray 显示小波分解系数
%   显示并返回一个小波系数图像
%	例子:
%			wave2gray(c,s);						显示w或默认值
%			foo = wave2gray(c,s);				显示并返回
%			foo = wave2gray(c,s,4);				放大细节
%			foo = wave2gray(c,s,-4);			放大的绝对值
%			foo = wave2gray(c,s,1,'append');	存储边界值

%	[c,s] 小波分解结构
%
%	scale			细节系数的比例
%--------------------------------------------------------------------
%	0 or 1         最大值范围 (默认)
%	2, 3...        通过比例因子放大默认值
%	-1, -2...      通过abs(scale)放大绝对值
%
%	border			小波分解间的边界
%--------------------------------------------------------------------
%	'absorb'		边界替代图像(默认)
%	'append'		边界增加图像的宽度
%
%	Image w:	    ------- ------ -------------- -------------------
%					|      |      |              |
%					| a(n) | h(n) |              |
%					|      |      |              |
%					------- ------     h(n-1)    |
%					|      |      |              |
%					| v(n) | d(n) |              |      h(n-2)
%					|      |      |              |
%					------- ------ --------------
%					|             |              |
%					|    v(n-1)   |    d(n-1)    |
%					|             |              |
%					-------------- -------------- -------------------
%					|                            |
%					|           v(n-2)           |      d(n-2)
%					|                            |

% 检查输入参数的合理性
narginchk(2,4);

if (~ismatrix(c)) || (size(c, 1) ~= 1)
	error('C必须是一个行向量.'); 
end

if (~ismatrix(s)) || ~isreal(s) || ~isnumeric(s) || (size(s, 2) ~= 2)
	error('S必须是一个实数数值型的两列数组.');
end

elements = prod(s, 2);

if (length(c) < elements(end)) ||   ...
		~(elements(1) + 3 * sum(elements(2:end - 1)) >= elements(end))
	error(['[C S] 必须是一个标准小波 ' ...
				'分解结构.']);
end

if (nargin > 2) && (~isreal(scale) || ~isnumeric(scale))
	error('SCALE必须是一个实数、数值型标量.');
end

if (nargin > 3) && (~ischar(border))
	error('BORDER必须是字符串.');
end

if  nargin == 2
	scale =1;    % 默认比例.
end

if nargin < 4
	border = 'absorb'; %默认边界.
end

%比例系数并确定填充量.
absflag = scale < 0;
scale = abs(scale);
if scale == 0
	scale = 1;
end

[cd, w] = wavecut('a', c, s);  w = mat2gray(w); % mat2gray 将矩阵转换为灰度图像
cdx = max(abs(cd(:))) / scale;
if absflag
	cd = mat2gray(abs(cd), [0, cdx]); fill = 0;
else
	cd = mat2gray(cd, [-cdx, cdx]); fill = 0.5;
end

% 一次建立一个灰度图像的分解
for i = size(s, 1) - 2:-1:1
	ws = size(w);
	h = wavecopy('h', cd, s, i);
	pad = ws - size(h);    frontporch = round(pad / 2);
	h = padarray(h, frontporch, fill, 'pre');
	h = padarray(h, pad - frontporch, fill, 'post');
	v = wavecopy('v',   cd,   s,   i);
	pad = ws - size(v);            frontporch = round(pad  /  2);
	v = padarray(v,   frontporch,   fill,   'pre');
	v = padarray(v,  pad - frontporch,  fill,   'post');
	d = wavecopy('d',   cd,   s,   i);
	pad = ws - size(d);            frontporch = round(pad  /  2);
	d = padarray(d,   frontporch,   fill,   'pre');
	d = padarray(d,   pad - frontporch,   fill,   'post');
   % 加一像素的白色边框
	switch  lower(border)
		case   'append'
			w =  padarray(w,   [1   1],   1,   'post');
			h = padarray(h,   [1   0],   1,   'post');
			v = padarray(v,   [0  1],   1,   'post');
		case   'absorb'
			w(:,   end)   =  1;         w(end,   :)   =  1;
			h(end,   :)   =  1;          v(:,   end)   =  1;
		otherwise
			error('无法识别边界参数.');
		end
	w = [w h; v d];                                          % 级联.
end

if nargout   == 0
	imshow(w);                                               % 显示结果
end

示例:使用wave2gray显示变换系数

img = imread('C:\Users\win\Desktop\sunflower.jpg');
img = rgb2gray(img);  % wavefast用于处理灰度图像,故要进行图像转换
[c,s] = wavefast(img,2,'haar');
figure;wave2gray(c,s);title('小波分解系数(自动缩放)');
figure;wave2gray(c,s,8);title('小波分解系数(细节8倍放大)');
figure;wave2gray(c,s,-8);title('小波分解系数(细节8倍放大的绝对值)');

结果:
数字图像处理——第七章(小波变换和多分辨率处理)_第31张图片
数字图像处理——第七章(小波变换和多分辨率处理)_第32张图片
数字图像处理——第七章(小波变换和多分辨率处理)_第33张图片

3.6 快速小波反变换的实现

将wfilters(小波工具箱自带函数)和wavefilter(非自带函数)中的参数type的值设置为“r”,即可得到重构滤波器(高通重构和低通重构)。
在小波工具箱中,wavedec2表示二维尺度分解,得到小波分解结构[C,S]。其对应的waverec2二维小波重构,用来计算小波分解结构[C,S]的快速小波反变换。语法如下:

g = waverec2(C,S,wname)   % g是重构后的二维图像(double类)
g = waverec2(C,S,Lo_R,Hi_R)  

当小波工具箱不可用时,可用waveback来实现二维小波重构。
waveback.m

 function [varargout] = waveback(c, s, varargin)  
%  waveback  多尺度二维快速小波反变换 
%   [VARARGOUT] = WAVEBACK(C, S, VARARGIN) 计算分解结构的二维N尺度的部分或完全小波重构 
%   
%   Y = WAVEBACK(C, S, 'WNAME');     
%   Y = WAVEBACK(C, S, LR, HR);   
%   用低通和高通重构滤波器(LR和HR)或通过wavefilter的参数'wname'获得的滤波器,输出快速小波反变换矩阵Y
%
%   [NC, NS] = WAVEBACK(C, S, 'WNAME', N);     
%   [NC, NS] = WAVEBACK(C, S, LR, HR, N);   
%
%   在N尺度重构后,输出新的小波分解结构
%   See also WAVEFAST and WAVEFILTER.   

%  检查输入输出参数的合理性 
narginchk(3, 5);  
narginchk(1, 2);  

if (~ismatrix(c)) || (size(c, 1) ~= 1)  
  error('C必须是行向量.');     
end  

if (~ismatrix(s)) || ~isreal(s) || ~isnumeric(s) || (size(s,2) ~= 2)  
  error('S 必须是实数型的两列数组.');     
end  

elements = prod(s, 2);  
if (length(c) < elements(end)) || ...  
      ~(elements(1) + 3 * sum(elements(2:end - 1)) >= elements(end))  
  error(['[C S] 必须是标准小波分解结构.']);   
end  

% [C, S]上的最大尺度.  
nmax = size(s, 1) - 2;          
% 获得第三个输入参数并初始化检查flags 
wname = varargin{1};  filterchk = 0;   nchk = 0;      

switch nargin  
case 3  
   if ischar(wname)     
      [lp, hp] = wavefilter(wname, 'r');   n = nmax;  
   else   
      error('未定义滤波器.');    
   end  
   if nargout ~= 1   
      error('输出参数个数有误.');    
   end  
case 4  
   if ischar(wname)  
      [lp, hp] = wavefilter(wname, 'r');     
      n = varargin{2};    nchk = 1;  
   else  
      lp = varargin{1};   hp = varargin{2};     
      filterchk = 1;   n = nmax;  
      if nargout ~= 1   
         error('输出参数个数有误.');    
      end  
   end  
case 5  
    lp = varargin{1};   hp = varargin{2};   filterchk = 1;  
    n = varargin{3};    nchk = 1;  
otherwise  
    error('输入参数个数不当.');       
end  

fl = length(lp);  
if filterchk                                        % 检查滤波器.  
  if (~ismatrix(lp)) || ~isreal(lp) || ~isnumeric(lp) ...  
        || (~ismatrix(hp)) || ~isreal(hp) || ~isnumeric(hp) ...  
        || (fl ~= length(hp)) || rem(fl, 2) ~= 0  
      error('LP 和 HP必须是偶数并且是长度相等的实数滤波器向量.');   
  end  
end  

if nchk && (~isnumeric(n) || ~isreal(n))          % 检查 N 
    error('N 必须是实数.');   
end  
if (n > nmax) || (n < 1)  
   error('请求重建的数量(N)无效.');      
end  
if (n ~= nmax) && (nargout ~= 2)   
   error('输出参数不够.');   
end  

nc = c;    ns = s;    nnmax = nmax;             % 初始化分解 
for i = 1:n  
   % 计算新的近似
   a = symconvup(wavecopy('a', nc, ns), lp, lp, fl, ns(3, :)) + ...  
       symconvup(wavecopy('h', nc, ns, nnmax), ...  
                 hp, lp, fl, ns(3, :)) + ...  
       symconvup(wavecopy('v', nc, ns, nnmax), ...  
                 lp, hp, fl, ns(3, :)) + ...  
       symconvup(wavecopy('d', nc, ns, nnmax), ...  
                 hp, hp, fl, ns(3, :));  

    % 更新分解 
    nc = nc(4 * prod(ns(1, :)) + 1:end);     nc = [a(:)' nc];  
    ns = ns(3:end, :);                       ns = [ns(1, :); ns];  
    nnmax = size(ns, 1) - 2;  
end  

% 对完全重建,将输出格式化为二维
if nargout == 1  
    a = nc;   nc = zeros(ns(1, :));     nc(:) = a;      
end  

varargout{1} = nc;  
if nargout == 2   
   varargout{2} = ns;    
end  

%-------------------------------------------------------------------%  
function z = symconvup(x, f1, f2, fln, keep)  
% 上采样行并用f1列卷积,上采样列并用f2行卷积,然后提取中心(假设对称扩展)

y = zeros([2 1] .* size(x));      y(1:2:end, :) = x;  
y = conv2(y, f1');  
z = zeros([1 2] .* size(y));      z(:, 1:2:end) = y;  
z = conv2(z, f2);  
z = z(fln - 1:fln + keep(1) - 2, fln - 1:fln + keep(2) - 2);  

示例:使用waveback进行图像的重构

f = imread ( 'C:\Users\win\Desktop\sunflower.jpg' ) ;  
f = rgb2gray(f);
[C,S] = wavefast( f,4,'haar') ;  % 4层小波分解
wave2gray(C,S,8); % 显示处理后的小波系数
f = wavecopy ('a',C,S) ;  % f 是第4层分解后的近似系数
figure; subplot(2,3,1);imshow(mat2gray(f)) ; title('4层分解后的近似图像');  % 显示第4层分解后的近似图像

[C,S] = waveback(C,S,'haar',1) ;   % 一次重构
f = wavecopy ('a',C,S) ;   %  f 是第3层分解后的近似图像
subplot(2,3,2); imshow (mat2gray(f)) ; title('3层分解后的近似图像'); % 显示第3层分解后的近似图像

[C,S] = waveback(C,S,'haar',1) ; % 二次重构
f = wavecopy ('a',C,S) ;  %  f 是第2层分解后的近似系数
subplot(2,3,3); imshow(mat2gray(f)) ; title('2层分解后的近似图像') % 显示第2层分解后的近似图像

[C,S]= waveback(C, S,'haar',1);   %三次重构
f = wavecopy('a',C,S);    %f是第1层分解后的近似函数
subplot(2,3,4); imshow(mat2gray(f)); title('1层分解后的近似图像')%显示第1层分解后的近似图像

[C, S]= waveback(C,S,'haar',1); %四次重构
f = wavecopy('a',C,S);  %f是最终重构后的图像
subplot(2,3,[5,6]); imshow(mat2gray(f)); title('重构后的最终图像')%显示重构后的最终图像

结果
数字图像处理——第七章(小波变换和多分辨率处理)_第34张图片
数字图像处理——第七章(小波变换和多分辨率处理)_第35张图片
wrcoef2 用二维小波系数重构某一层级的系数

% 其实就是根据小波分解之后的系数c来重建其对应的图像。重建好的图像的尺度与原始图像一致。即无论你要重构哪个层的系数,最终它的维度都是和原始图像的尺度一致。
X = wrcoef2('type',C,S,wname,N)  % 基于小波分解结构[C,S],计算N尺度上的重构系数
X = wrcoef2('type',C,S,Lo_R,Hi_R,N)   % Lo_R,Hi_R可通过wfilters或wavefilter得到

X = wrcoef2('type',C,S,wname)  % 未明示N的值时,此时计算最大尺度N上的重建系数
X = wrcoef2('type',C,S,Lo_R,Hi_R)

示例

img  = imread('C:\Users\win\Desktop\sunflower.jpg');
% 对图像进行3层的小波分解
[c,s] = wavedec2(img,3,'db1');

% 对各层的近似图像a进行重构
a1 = wrcoef2('a',c,s,'db1',1);
a2 = wrcoef2('a',c,s,'db1',2);
a3 = wrcoef2('a',c,s,'db1',3);

figure(1);
subplot(2,2,1); imshow(img); title('原图');
subplot(2,2,2); imshow(a1); title('1层重构近似系数');
subplot(2,2,3); imshow(a2); title('2层重构近似系数');
subplot(2,2,4); imshow(a3); title('3层重构近似系数');

结果:
数字图像处理——第七章(小波变换和多分辨率处理)_第36张图片

四、小波在图像处理中的应用

基于小波的图像处理的基本方法如下:
1、计算一幅图像的二维小波变换
2、修改变换系数
3、计算反变换

小波的方向性和边缘检测

f=imread('C:\Users\win\Desktop\sunflower.jpg');
f = rgb2gray(f);
figure;
imshow(f);
title('原图');
[c,s]=wavefast(f,1,'sym4'); %快速小波变换
figure;
wave2gray(c,s,-6); 
title('显示小波系数(细节放大6倍绝对值)');

[nc,y]=wavecut('a',c,s);%近似系数置0
figure;
wave2gray(nc,s,-6);  
title('显示小波系数(将近似系数置0,细节放大6倍绝对值)');
edges=abs(waveback(nc,s,'sym4'));% 快速小波反变换,边缘重构

figure;
imshow(mat2gray(edges));
title('图像的边缘')

结果
数字图像处理——第七章(小波变换和多分辨率处理)_第37张图片
数字图像处理——第七章(小波变换和多分辨率处理)_第38张图片
数字图像处理——第七章(小波变换和多分辨率处理)_第39张图片
数字图像处理——第七章(小波变换和多分辨率处理)_第40张图片
基于小波的图像平滑
为进行流线型的平滑处理,引入wavezero函数
wavezero.m

function [nc, g8] = wavezero(c, s, l, wname)  
%  wavezero 将小波变换的细节系数置零  
%   [NC, G8] = WAVEZERO(C, S, L, WNAME) 
%   将L尺度上的小波分解结构[C,S]的细节系数置零,并计算WNAME小波的反变换

[nc, foo] = wavecut('h', c, s, l);  
[nc, foo] = wavecut('v', nc, s, l);  
[nc, foo] = wavecut('d', nc, s, l);  
i = waveback(nc, s, wname);  
g8 = im2uint8(mat2gray(i));  
figure; imshow(g8);  

示例

f=imread('C:\Users\win\Desktop\sunflower.jpg');
f = rgb2gray(f);
[c,s] = wavefast(f,3,'sym4');
wave2gray(c,s,20);
[c,g8] = wavezero(c,s,1,'sym4');  % 将第一级细节系数置为零
[c,g8] = wavezero(c,s,2,'sym4');  % 将第二级细节系数置为零
[c,g8] = wavezero(c,s,3,'sym4');  % 将第三级细节系数置为零

结果
数字图像处理——第七章(小波变换和多分辨率处理)_第41张图片
数字图像处理——第七章(小波变换和多分辨率处理)_第42张图片
数字图像处理——第七章(小波变换和多分辨率处理)_第43张图片
数字图像处理——第七章(小波变换和多分辨率处理)_第44张图片
参考:小波的选择和小波的分类

五、小波包

由于正交小波变换只对信号的低频(近似)信息做进一步分解,而对高频(细节)信息不再继续分解,使得它的频率分辨率随频率升高而降低。所以小波变换能够很好地表征一大类以低频信息为主要成分的信号,但它不能很好地分解和表示包含大量细节信息(细小边缘或纹理)的信号,如非平稳机械振动信号、遥感图象、地震信号和生物医学信号等。与之不同的是,小波包变换可以对高频部分提供更精细的分解,而且这种分解既无冗余,也无疏漏,所以对包含大量中、高频信息的信号能够进行更好的时频局部化分析。
一个三层的小波包分解如下:
数字图像处理——第七章(小波变换和多分辨率处理)_第45张图片
式中 A 表示低频部分,D 表示高频部分,末尾的序号表示小波包分解的层数(即尺度数)。如果分解的是二维的图像,每一层的每个节点的分解系数就代表着一张图像,该图像亦或来自上一层近似系数的分解,亦或来自上一层细节系数的分解。

小波包分解
wpdec 一维小波包分解
参考:wpdec 一维小波包分解

T = wpdec(X,N,wname,E,P)   % 一维小波包分解函数,X为要分解的信号,N为分解级数(尺度数),wname为小波类型,E为熵的类型,默认的熵为‘shannon’,P为熵所对应的参数

示例

% 加载信号
load noisdopp;  % noisdopp是小波工具箱自带的信号,直接加载即可
x = noisdopp;
wpt = wpdec(x,3,'db1','shannon');
% 画对应的小波包树
plot(wpt)

结果
数字图像处理——第七章(小波变换和多分辨率处理)_第46张图片
点击图中左侧的不同节点,右侧会显示对应节点的信号信息。

wpdec2 二维小波包分解
示例

X = imread('C:\Users\win\Desktop\photo\peach.jpg');
t = wpdec2(X,2,'db1'); 
plot(t)

结果
数字图像处理——第七章(小波变换和多分辨率处理)_第47张图片
小波包重构
wprec 一维重构
示例

load noisdopp;  % noisdopp是小波工具箱自带的信号,直接加载即可
x = noisdopp;

wpt = wpdec(x,3,'db1','shannon');
% 一维重构
y = wprec(wpt);
plot(abs(x - y));
title('重构后的信号和原信号的差值');

结果
数字图像处理——第七章(小波变换和多分辨率处理)_第48张图片
注意看纵坐标的单位是乘以10-15,所以差异还是比较小的。

wprec2 二维重构
示例

X = imread('C:\Users\win\Desktop\photo\peach.jpg');
t = wpdec2(X,2,'db1'); 
Y = wprec2(t);
figure;
subplot(1,2,1); imshow(X); title('原图');
subplot(1,2,2); imshow(Y); title('小波包重构后的图像');

结果
数字图像处理——第七章(小波变换和多分辨率处理)_第49张图片
获取小波包树上某个节点的小波包系数
wpcoef 获取小波包树某节点的系数 (一维或二维)

X = wpcoef(T,N)  % 返回小波包树某个节点N对应的小波包系数
X = wpcoef(T)  % 相当于 X = wpcoef(T,0)  即获得原始信号节点(小波包树的根节点)的小波包系数 

示例

load noisdopp; 
x = noisdopp;

% 获得小波包树
wpt = wpdec(x,3,'db1');

% 获得[2,1]节点的系数
cfs = wpcoef(wpt,[2 1]);

% 显示
figure(1); subplot(211); 
plot(x); title('原始信号');

subplot(212); 
plot(cfs); title('节点[2,1]处的系数');

数字图像处理——第七章(小波变换和多分辨率处理)_第50张图片
wprcoef 获取小波包树某节点的重构系数(一维或二维)

X = wprcoef(T,N) %计算小波包树T的节点N的重构系数

示例

load noisdopp; x = noisdopp;
t = wpdec(x,3,'db1','shannon');
% 重构小波包结点(2,1)
rcfs = wprcoef(t,[2 1]);
figure(1); subplot(211);  plot(x); title('原始信号');
subplot(212); plot(rcfs); title('重构小波包结点(2,1)');

结果
数字图像处理——第七章(小波变换和多分辨率处理)_第51张图片
将小波包树上的节点进一步分解
wpsplt 分解小波包(一维或二维)

T1 = wpsplt(T,N)   % T是小波包树,N为小波包树上的节点

示例

load noisdopp;
x = noisdopp;

wpt = wpdec(x,3,'db1');
plot(wpt);
wpt1 = wpsplt(wpt,9);  % 对小波包树wpt的第9个节点进行进一步分解,此处可以写9,也可以写[3,2]
plot(wpt1);

数字图像处理——第七章(小波变换和多分辨率处理)_第52张图片
数字图像处理——第七章(小波变换和多分辨率处理)_第53张图片
注: 小波包树的节点数是从0开始的,即树的根节点是第0个节点。

将小波包树上的某些节点重组
wpjoin 重组小波包某节点 (一维或二维)

T = wpjoin(T,N)   % 将小波包树第N个节点以下的分支合并。N为0或者不给出N,都表示合并到根节点

示例

load noisdopp;
x = noisdopp;

wpt = wpdec(x,3,'db1');
plot(wpt);
wpt1 = wpjoin(wpt,[1,1]);
plot(wpt1);

数字图像处理——第七章(小波变换和多分辨率处理)_第54张图片
计算最优的小波包树
besttree 获得最优小波包树(一维或二维)

T = besttree(T)

示例

load noisdopp;
x = noisdopp;

wpt = wpdec(x,3,'db1');
plot(wpt);
wpt1 = besttree(wpt);
plot(wpt1);

结果
数字图像处理——第七章(小波变换和多分辨率处理)_第55张图片
计算小波包树的最优层数
beatlevt 计算最优层数(一维或二维)

T = bestlevt(T)

示例

load noisdopp; 
x = noisdopp;
wpt = wpdec(x,3,'db1'); 

wpt = wpsplt(wpt,[3 0]);
plot(wpt);
% 计算最优层数
blt = bestlevt(wpt);
plot(blt);

结果
数字图像处理——第七章(小波变换和多分辨率处理)_第56张图片
wpcutree 剪小波包树(一维或二维)

T = wpcutree(T,L)  % 剪掉小波包树的第L层

示例

load noisdopp; 
x = noisdopp;
wpt = wpdec(x,3,'db1'); 
plot(wpt);
% 剪掉wpt的第二层
newpt = wpcutree(wpt,2);
plot(newpt);

数字图像处理——第七章(小波变换和多分辨率处理)_第57张图片
wp2wtree 从小波包树提取小波树(一维或二维)

T = wp2wtree(T)  % 计算对应于小波包分解树的修改后的小波包树T

示例

load noisdopp; x = noisdopp;
wpt = wpdec(x,3,'db1');
% 画出小波包树
plot(wpt);
% 提取小波树
wt = wp2wtree(wpt);
% 画出小波树
plot(wt);

结果
数字图像处理——第七章(小波变换和多分辨率处理)_第58张图片

你可能感兴趣的:(matlab,数字图像处理)