简介:面向MATLAB使用者的小波分析学习资源,适合信号处理、图像分析初学者及需要快速上手小波工具箱的工程人员。内容围绕小波函数和尺度函数的核心性质展开,重点演示如何在MATLAB中调用wavemngr、wavfun等函数,生成小波并绘制对应曲线,帮助读者建立从构造、计算到可视化的整体认知。压缩包共2个文件,包含1个.m脚本和1个.fig图形文件,整体大小仅54KB;脚本用于套用常见小波基完成函数取值计算,fig文件则可直接查看小波函数与尺度函数波形,便于对照运行结果深化理解。已有1199人学习过该资源。借助包内案例,可快速认识Haar、Daubechies、Morlet等常用小波基的差异与特点;通过逐行运行脚本,也能直观理解尺度函数的构造过程,为后续在信号去噪、图像压缩、特征提取及多尺度分析等场景中的应用提供清晰的实践入口。
1. 小波函数与尺度函数:先看这对搭档,再打开MATLAB
小波变换和傅里叶变换最大的区别,在于它同时保留时域和频域信息。要做到这一点,靠的并不是一个函数,而是一对搭档。尺度函数负责抓信号里缓慢变化的趋势,小波函数负责抓突变和细节,两者通过多分辨率分析互相补充,共同构成小波变换的骨架。很多人能熟练使用dwt和wavedec,却不太清楚wfilters返回的四组滤波器到底是干什么的,也不知道wavefun画出来的波形代表什么分辨率。
这部分内容会把“小波函数、尺度函数”这两个概念落到MATLAB的具体函数和可执行代码上。你不必先把多分辨率分析的推导全部啃完,按顺序跑一遍wfilters、wavefun、dwt,再回头看二尺度方程,那些公式符号会发现就是手边的Lo_D和Hi_D。适合正在做信号去噪、故障诊断或时间序列预测的工程师,也适合准备把小波系数作为特征输入给神经网络的读者。
2. 多分辨率分析:尺度函数定骨架,小波函数补细节
2.1 尺度空间与小波空间:两个子空间如何拼出完整信号
多分辨率分析的出发点是构造一列嵌套子空间,记作V_j。V_j由尺度函数的整数平移族φ_{j,k}(t)=2^{j/2}φ(2^j t-k)张成,V_j随着j增大而扩大,且满足嵌套关系V_j⊂V_{j+1}。单纯用尺度函数逼近信号,能拿到越来越精细的近似,但两个相邻尺度之间还有“差”的部分没有表达,这部分就是由小波函数生成的子空间W_j。
形式化地看,V_{j+1}=V_j⊕W_j,也就是下一层尺度空间被拆成上一层尺度空间与细节空间的直和。直和的含义是,信号中的信息在每一层被划分成两个正交的分量:属于V_j的低频趋势,以及属于W_j的高频细节。把这种拆分由深到浅逐层做下去,就得到常见的小波分解树。工程上关心的是,上述抽象的“子空间逼近”最终都会被转化为两组离散滤波器系数,一组给尺度函数,一组给小波函数,这决定了你在MATLAB里操作的对象其实是滤波器向量而非连续函数。
所以,理解尺度函数和小波函数,重点并不是无穷迭代的数学定义,而是这三件事:两个函数对应两个子空间、两个子空间互不重叠、两层之间存在二尺度递推关系。下一节从这个递推关系直接跳进MATLAB的系数世界。
2.2 二尺度方程与滤波器系数:先用wfilters抓出h和g
两个子空间之间的递推关系由二尺度方程描述:
φ(t)=√2 Σ_n h(n) φ(2t-n) ψ(t)=√2 Σ_n g(n) φ(2t-n)
其中h是尺度函数对应的低通系数,g是小波函数对应的高通系数。MATLAB的wfilters返回的正是这两种系数以及它们的重构版本。下面用db2小波做一次完整读取:
% 读取 db2 小波的四组滤波器系数 [Lo_D, Hi_D, Lo_R, Hi_R] = wfilters('db2'); disp('分解低通 Lo_D:'); disp(Lo_D); disp('分解高通 Hi_D:'); disp(Hi_D);Lo_D和Hi_D分别对应二尺度方程里的h和g,用于分解信号;Lo_R和Hi_R用于重构,是把信号从系数域拼回时间域时使用的对偶滤波器。Lo表示低通,D是decomposition,R是reconstruction,命名规则直接告诉你在哪一个环节使用,Lo和Hi不能对调,D和R也不能混用。正交小波中Lo_R恰好是Lo_D的时间反转,Hi_D也可以由Lo_R推导出来,因此只需要存一半系数。
公式里的√2来自归一化约定,MATLAB的wfilters返回系数已经吸收了这部分因子,不需要自己再乘√2。如果从文献里手写系数,要先把约定核对清楚再交给dwt,这是新手很容易踩的坑。二尺度方程里的系数与MATLAB变量一一对应如下:
| 方程符号 | 含义 | MATLAB变量 | 用在哪个环节 |
|---|---|---|---|
| h(n) | 尺度函数的低通系数 | Lo_D | 分解出近似系数cA |
| g(n) | 小波函数的高通系数 | Hi_D | 分解出细节系数cD |
| h'(n) | 重构端低通系数 | Lo_R | 由cA重建低频分量 |
| g'(n) | 重构端高通系数 | Hi_R | 由cD重建高频分量 |
2.3 用wavefun算出来看一眼:两个函数长什么样
% 查看 db2 小波的尺度函数和小波函数时域波形 [phi, psi, xval] = wavefun('db2', 10); figure; subplot(2,1,1); plot(xval, phi, 'LineWidth', 1.5); % 尺度函数波形 title('db2 尺度函数'); grid on; subplot(2,1,2); plot(xval, psi, 'LineWidth', 1.5); % 小波函数波形 title('db2 小波函数'); grid on;wavefun的第二个参数是迭代次数。每次迭代相当于把内部生成函数的采样点加密一倍,数字越大,输出波形越接近真正的连续函数。工程画图用8~10次迭代即可,论文插图想要平滑曲线可以取12,但计算量也随之增大。输出xval是等间距采样横轴,phi和psi的纵轴幅度没有统一标准,haar这类特殊小波才是规整的±1,db族大部分值落在-2到2之间,直接用plot画,不需要手工缩放。
到这里,可以直观看到尺度函数是带支撑区的低通形状,小波函数是带振荡的高通形状,两者在时域上互补。这个认识会直接影响第4章里小波基的选择:细节信号明显时,优先关心小波函数的形状和消失矩。
3. MATLAB的小波函数与尺度函数入口:wfilters和wavefun的参数细节
3.1 wfilters返回的四组系数:分解与重构别混用
wfilters除了接受'db2'这样的名称外,也接受'sym4'、'coif3'、'bior3.5'等。下面的代码把sym4四组系数画成离散序列,能更清楚看到四个滤波器的长度和支持范围差异:
wname = 'sym4'; [Lo_D, Hi_D, Lo_R, Hi_R] = wfilters(wname); figure; subplot(2,2,1); stem(Lo_D); title('Lo\_D'); subplot(2,2,2); stem(Hi_D); title('Hi\_D'); subplot(2,2,3); stem(Lo_R); title('Lo\_R'); subplot(2,2,4); stem(Hi_R); title('Hi\_R');对正交小波,Lo_R是Lo_D的时间反转,Hi_D与Lo_R之间满足调制关系,所以四组系数并不独立。双正交小波则不同,四组滤波器都要单独保存,这也是wfilters在bior族上返回更特殊结构的原因。如果写错小波名,先执行waveinfo('db')、waveinfo('bior')查看支持列表,再核对括号里的族名和序号。
3.2 wavefun的调用方式:正交小波和双正交小波返回值不同
正交小波调用wavefun时用三个输出:[phi, psi, xval]。双正交小波在分解端和重构端各有一套尺度函数和小波函数,因此要接收五个输出:
% 双正交小波返回两套尺度函数 [phi1, psi1, phi2, psi2, xval] = wavefun('bior3.5', 8); figure; plot(xval, phi1, 'b', xval, phi2, 'r', 'LineWidth', 1.2); legend('分解端 \phi', '重构端 \phi'); title('bior3.5 的两套尺度函数');phi1和psi1对应分解端的尺度函数与小波函数,phi2和psi2对应重构端。因为双正交小波不再要求两个子空间严格正交,而是要求分解和重构这对对偶系统满足完全重构条件,所以会出现两套函数。图像处理里bior族更常见,正是因为它有线性相位,能避免重构时边缘相位畸变。
3.3 小波族选型速查:db、sym、bior各管一摊
| 小波族 | wname示例 | 正交性 | 线性相位 | 典型场景 |
|---|---|---|---|---|
| haar | 'haar' | 正交 | 有 | 入门演示、快速验证 |
| daubechies | 'db4' | 正交 | 无 | 通用信号去噪、故障诊断 |
| symlets | 'sym4' | 正交 | 近似线性 | 需要减少相位失真时 |
| coiflets | 'coif3' | 正交 | 无 | 平衡支撑长度与光滑性 |
| biorthogonal | 'bior3.5' | 双正交 | 有 | 图像处理、信号重构 |
选型顺序我一般这样走:先看是否需要线性相位,需要就去bior族;不需要,再比较消失矩和支撑长度,db4到db8是常用的折中区间;最后用同样的阈值去噪流程跑一遍,比较输出信噪比,而不是只看曲线形状。MATLAB里通过waveinfo可以查看每个族消失矩、支撑长度的官方说明,比在网上找二手对比表更可靠。
4. 小波分解重构与去噪:从dwt到waverec的参数设定
4.1 dwt/idwt一层分解:先看系数怎么拆、怎么拼
用一个叠加了50 Hz正弦、300 Hz正弦和随机噪声的信号做单层分解:
fs = 1000; t = (0:999) / fs; x = sin(2*pi*50*t) + 0.2*sin(2*pi*300*t) + 0.05*randn(1, 1000); % 单层小波分解:cA 是近似,cD 是细节 [cA, cD] = dwt(x, 'db4'); % 直接重构,验证信息是否完整 xr = idwt(cA, cD, 'db4'); fprintf('最大重构误差: %.3e\n', max(abs(x - xr)));dwt的输出cA和cD长度约为输入信号的一半,精确长度由信号长度、滤波器长度和边界延拓模式共同决定,不要假设一定是floor(N/2)。idwt能把系数还原成和x等长的序列。如果重构误差明显偏离机器精度,优先检查边界模式和信号长度,而不是怀疑小波函数选错了。
4.2 wavedec/waverec多层分解:层数和每层频带怎么对应
N = 4; [C, L] = wavedec(x, N, 'db4'); % 取出第 4 层近似和第三层细节的时间序列 A4 = wrcoef('a', C, L, 'db4', 4); D3 = wrcoef('d', C, L, 'db4', 3);wavedec把所有层的系数拼在一维数组C里,L记录每段分界点,通常不需要手工解析。wrcoef按类型和层号直接把系数恢复成与x等长的时间序列,A4是第4层近似,D3是第3层细节。N的上限由信号长度决定,理论上不能超过floor(log2(length(x))),工程上取到目标频段所在层即可。以fs=1000为例,各层分量对应的频带近似如下:
| 分量 | 频带(fs=1000 Hz) |
|---|---|
| D1 | 250 ~ 500 Hz |
| D2 | 125 ~ 250 Hz |
| D3 | 62.5 ~ 125 Hz |
| D4 | 31.25 ~ 62.5 Hz |
| A4 | 0 ~ 31.25 Hz |
这是理想滤波器组下的划分,真实小波滤波器存在过渡带,跨层会有轻微重叠。机械振动诊断里常用这个表反推:知道故障特征频率落在哪一段,就取对应层数分解,再做包络谱。
4.3 小波阈值去噪:thselect和wthresh怎么配合
thr = thselect(C, 'sqtwolog'); % 选择阈值 Cd = wthresh(C, 's', thr); % 软阈值收缩 xd = waverec(Cd, L, 'db4'); % 重构去噪thselect的四种阈值规则适用于不同噪声强度,最小化风险规则适合弱噪声,固定阈值规则最常见,但噪声强时容易过度平滑。sorh参数决定收缩方式,'s'软阈值会把所有系数向零压缩,'h'硬阈值保留超过阈值的原值,硬阈值重构的信号更锐利,但会在断点处留下毛刺。工程上可以先跑一组不同规则的对比,用去噪后信号的均方根误差和峰度两个指标一起判断。
| 规则 | 含义 |
|---|---|
| rigrsure | Stein无偏风险估计,适合弱噪声 |
| heursure | 启发式混合规则,兼顾强、弱噪声 |
| sqtwolog | 固定阈值,噪声较强时常用 |
| minimaxi | 极小极大准则,保留更多细节 |
小波基和阈值的搭配没有固定答案。同一个信号,db4加sqtwolog可能比sym8加rigrsure更合适。建议把阈值规则、小波族、分解层数三个变量做成循环,在验证集上选最优组合,而不是依赖经验拍板。
5. 进阶:自定义滤波器组、边界模式与Elman网络特征提取
5.1 自定义滤波器组:检查正交条件后再交给dwt
MATLAB的小波函数库不是封闭的,dwt允许直接传入滤波器系数。系数必须满足正交条件,最常用的一组验证是:直流增益sum(h)/sqrt(2)接近1,且偶数位自相关接近0。下面用db2的系数做示例,实际使用时替换成你自己设计的h:
h = [0.482962913144534, 0.836516303737808, ... 0.224143868042013, -0.129409522551260]; Lo_D = h; Hi_D = fliplr(h) .* (-1).^(0:length(h)-1); Lo_R = fliplr(Lo_D); Hi_R = fliplr(Hi_D); fprintf('直流增益 = %.6f\n', sum(h) / sqrt(2)); [cA, cD] = dwt(x, Lo_D, Hi_D); xr = idwt(cA, cD, Lo_R, Hi_R);高通由低通翻转调制得到,这是正交小波的通用构造方式。若直流增益明显偏离1,重构误差会立刻放大。先跑重构误差,误差接近机器精度,再把这些系数用于后续特征提取。
5.2 边界模式:用dwtmode和最大重构误差验证
边界延拓会直接影响重构误差。dwtmode('per')做周期延拓,对本来就近似周期的信号效果好;dwtmode('sym')做对称延拓,对一般实测信号更常用。对比代码:
dwtmode('per'); [ca_p, cd_p] = dwt(x, 'db4'); xr_p = idwt(ca_p, cd_p, 'db4'); dwtmode('sym'); [ca_s, cd_s] = dwt(x, 'db4'); xr_s = idwt(ca_s, cd_s, 'db4'); fprintf('per 误差: %.3e\n', max(abs(x - xr_p))); fprintf('sym 误差: %.3e\n', max(abs(x - xr_s)));注意dwtmode修改的是全局设置,调试完要恢复默认模式,否则后续脚本都可能被影响。
5.3 把分解系数做成Elman网络特征:四个验证点
小波分解配合Elman网络做时间序列预测是一类常见组合,特征通常取各层细节系数的能量统计量:
[C, L] = wavedec(x, 4, 'db4'); feat = zeros(1, 5); for k = 1:4 d = wrcoef('d', C, L, 'db4', k); feat(k) = sum(d.^2) / length(d); end feat(5) = sum(wrcoef('a', C, L, 'db4', 4).^2);接模型之前做四个验证:一是重构误差基准,用rng(0)、randn(1,512)固定输入,把最大重构误差压到1e-12以下;二是特征归一化到同一量级;三是按时间段切分训练集和测试集,避免随机抽样破坏时间相关性;四是对比做与不做阈值去噪两种特征的效果,小波去噪带来的提升有时在特征层面已经体现。前两步过关后,再讨论网络结构才有意义。
本文还有配套的精品资源,点击获取