Haar小波变换是小波变换中最简单的一种,也是最早被广泛使用的一种小波变换方法。它能够将任何信号分解成数个均匀的子信号,将高频和低频分开,被广泛应用于图像和信号处理、压缩等领域。
一、小波变换基本概念
小波变换有点类似于傅里叶变换,但又与之有所不同。前者可以将信号分解成一组基函数,而这些基函数只在有限区间内存在,因此它可以更好地处理时变信号。而后者则将信号分解成一组不同频率的正弦和余弦函数,因此适用于处理稳定的信号。
小波变换可以用于信号的时频分析,同时也可用于信号的压缩和去噪。小波分解后的低频信号表示信号的大致趋势,高频信号则表示细节信息。在实际应用中,选择合适的小波基函数非常重要。因为各种小波基函数的分解效果不同,其优势各有千秋,Haar小波变换是其中之一。
二、Haar小波基函数
Haar小波变换的基本思想是将一个长度为$2^k$的序列分解成长度为$2^{k-1}$的两个子序列,这两个子序列可以表示成均值和差值的形式,前者称为低频分量,后者称为高频分量。
Haar小波有两个基函数:$h(x)$和$g(x)$,分别对应于低频分量和高频分量。具体定义如下:
h(x) = 1, 0<=x<1/2 -1, 1/2<=x<1 0, 其他情况 g(x) = 1, 0<=x<1/2 1, 1/2<=x<1 0, 其他情况
在Haar小波基函数的定义中,$h(x)$表示均值函数或低频部分,$g(x)$表示差值函数或高频部分。我们可以通过将它们进行重复和调整,构造出一组哈尔小波基函数:
φ(x)=h(x), 0<=x<1 φ_{j,k}(x)={ 2^{j/2}h(2^jx-k) , 2^{j-1}<=k<2^j -2^{j/2}h(2^jx-k) , 2^{j-1}<=k<2^j 0, otherwise } ψ_{j,k}(x)={ 2^{j/2}g(2^jx-k) , 2^{j-1}<=k<2^j -2^{j/2}g(2^jx-k) , 2^{j-1}<=k<2^j 0, otherwise }
其中,$j$表示小波变换的尺度或层数,$k$表示小波的平移因子,$x$是时间索引。$φ(x)$和$ψ(x)$分别对应于Haar小波的低频部分和高频部分,也叫做近似分量和细节分量。
三、Haar小波变换算法
Haar小波变换的算法包含两个步骤:分解和重构。分解将信号分解成低频部分和高频部分,重构则将两部分重组为原始信号。
(一)分解算法
假设输入的信号为$f(x)$,其长度为$N=2^k$,这里以4位数据为例子:$f(x)=[a_0,a_1,a_2,a_3]$。根据Haar小波变换的基本思想,我们需要将这个信号分解为长度为2的子序列,然后进行处理。
首先,将输入信号的长度减半,得到长度为2的子序列$[a_0,a_2]$和$[a_1,a_3]$,将它们分别处理成平均值和差值,得到:
d_1 = (a_0-a_2)/\sqrt{2} d_2 = (a_1-a_3)/\sqrt{2} a_1 = (a_0+a_2)/\sqrt{2} a_2 = (a_1+a_3)/\sqrt{2}
其中,$d_1$和$d_2$表示高频分量,$a_1$和$a_2$表示低频分量。最终,我们将处理好的高频分量和低频分量合并起来,得到长度为4的信号$[a_1,d_1,a_2,d_2]$。
对于长度为$2^k$的序列,我们可以通过递归地多次进行上述操作,最终得到小波变换的所有系数。下面是Haar小波变换的分解算法示例代码:
def haarWaveletTransform(signal): N = len(signal) if N == 1: return signal else: signal1 = signal[0:N:2] signal2 = signal[1:N:2] mean = [(signal1[i] + signal2[i])/np.sqrt(2) for i in range(N//2)] diff = [(signal1[i] - signal2[i])/np.sqrt(2) for i in range(N//2)] cA = haarWaveletTransform(mean) cD = haarWaveletTransform(diff) return np.concatenate((cA, cD))
(二)重构算法
通过Haar小波变换,我们可以将信号分解成多个低频分量和高频分量。接下来,我们需要将这些分量合并起来,重构成原始信号。
假设我们已知原始信号的细节分量和近似分量,那么可以通过一系列的加减操作来反向计算原始信号:
N = len(coef) a = [0]*N for i in range(N//2): a[2*i] = (coef[i]+coef[N//2+i])/np.sqrt(2) a[2*i+1] = (coef[i]-coef[N//2+i])/np.sqrt(2)
上述代码中,$coef$数组保存着小波变换的系数,其中前一半表示近似分量,后一半表示细节分量。通过迭代地进行平均和差分运算,我们可以逐步还原出原始的信号。最终,变换后的信号并原信号是相同的。
四、应用实例
Haar小波变换在图像处理、信号压缩等领域有着广泛的应用。下面我们以图像压缩为例,介绍Haar小波变换的具体应用。
(一)图像压缩
图像压缩是指将原始图像压缩成更小的尺寸,以便于存储和传输。Haar小波变换可以将图像分解成多个小波系数,然后根据数据的特征选取部分高频小波系数并舍弃部分低频小波系数,从而实现图像压缩。
具体来说,我们可以将原始图像分解成多个小波系数,在这些系数中选择部分高频系数并将其舍弃。舍弃后再通过逆变换来重建图像。
下面是Haar小波变换在图像压缩方面的实现:
import cv2 def haarWaveletTransform2D(image): rows, cols = image.shape temp = np.zeros((rows,cols), dtype=float) for i in range(rows): temp[i,:] = haarWaveletTransform(image[i,:]) for j in range(cols): temp[:,j] = haarWaveletTransform(temp[:,j]) return temp def haarWaveletTransform2DInv(coef): rows, cols = coef.shape temp = np.zeros((rows,cols), dtype=float) for j in range(cols): temp[:,j] = haarWaveletTransformInv(coef[:,j]) for i in range(rows): temp[i,:] = haarWaveletTransformInv(temp[i,:]) return temp def compressImage(image, alpha=0.5): coef = haarWaveletTransform2D(image) threshold = np.percentile(abs(coef), alpha*100) coef_abs = abs(coef) # 只保留系数的绝对值 coef[coef_abs < threshold] = 0 # 软阈值 image_inv = haarWaveletTransform2DInv(coef) return image_inv
上述代码中,我们实现了二维Haar小波变换和相应的逆变换,然后使用软阈值法对小波系数进行筛选,保留一部分高频系数。
(二)示例
下面我们给出一个图像压缩的示例:
这是一张尺寸为512x512的彩色图像,我们可以将其转化为灰度图像,然后进行压缩。以下是Python代码:
import cv2 # 加载图像 img = cv2.imread("lena.png") gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) # 压缩 alpha = 0.5 compressed = compressImage(gray, alpha) # 显示原始图像和压缩后的图像 cv2.imshow("Original Image", gray) cv2.imshow("Compressed Image", compressed.astype(np.uint8)) cv2.waitKey(0) cv2.destroyAllWindows()
其中,$alpha$参数表示保留系数的比例,这里我们选择了50%。运行代码后,可以得到以下结果:
可以看到,压缩后的图像失去了一些细节信息,但基本上保留了原始图像的特征,体积缩小了约4倍。
五、小结
Haar小波变换是最基础的小波变换之一,它通过将信号分解成低频分量和高频分量,将信号在时域和频域上分解开,具有良好的时频定位特性。Haar小波变换具有计算简单、可逆性强等优点,被广泛应用于图像和信号处理、压缩等领域。
本文介绍了Haar小波变换的基本概念、Haar小波基函数、Haar小波变换算法以及其应用实例。通过使用Haar小波变换和软阈值法,我们可以将图像压缩到较小的尺寸,同时基本保留了图像的特征信息。