
简介这是一份面向信号处理与图像分析场景的MATLAB小波提升算法源码资源适合工程师、研究者和相关专业学生学习提升框架下的分解、重构与滤波器设计。压缩包共五十六个文件以三十三个脚本为主体并配套C源码、头文件、Visual Studio工程文件及编译好的dll动态库整体仅五十九KB便于快速下载和二次开发。已有二百四十三人学习浏览内含小波提升变换核心函数如perform_lifting_transform等并提供完整实现、多组测试脚本和mex编译接口。借助这些代码可直观理解上采样、滤波、决策、下采样等提升步骤并直接应用于信号去噪、图像压缩、故障诊断或金融时间序列分析等实际问题。此外资源包还覆盖经典Haar与7-9小波的对照测试能帮助读者对比不同提升系数的影响也可作为算法教学或毕业设计的参考实现。1. 从卷积到三步操作小波提升算法在 MATLAB 里的真正价值小波提升算法Lifting Scheme和 MATLAB 里经典的wavedec/dwt走的是两条路经典小波把信号通过一高一低两个卷积滤波器再做降采样而提升算法把变换拆成“分裂、预测、更新”三步所有数据都在原始信号邻域内做运算。对做信号去噪、图像无损压缩、或者准备把算法搬到嵌入式和 FPGA 上的工程师来说提升算法的意义不只是换个写法它能做到整数到整数的可逆变换并且每一步都能在原数组上就地更新内存占用远小于滤波器组实现。这篇内容从提升算法的数学结构讲起然后给出可以在 MATLAB 里直接跑的 5/3 整数提升变换完整代码、9/7 浮点提升参数、边界处理和多级分解写法最后落到无损验证和去噪应用上。2. 小波提升算法的三步原理分裂、预测、更新2.1 为什么提升比卷积更适合 MATLAB 矩阵环境Mallat 算法早期在 MATLAB 中的实现方式是把信号和低通滤波器做卷积再隔点抽样得到近似系数和高通滤波器卷积后降采样得到细节系数。这个流程有两个隐藏成本。第一卷积输出长度大于输入长度需要处理延展区域边缘策略复杂第二浮点滤波器的系数不是整数重构时无法保证完全无误差。提升算法的设计思路是绕开滤波器的频率响应直接在空间域构造可逆的变换规则。任何提升步骤都满足一个简单性质先算出一个预测值再算出预测误差最后用误差去修正另一个子集因为每一步的修正量都可以在逆变换时原样减回去所以理论上能做到完全重构。更重要的是预测器和更新器不必来自小波滤波器可以人为设计成非线性甚至取整操作这就是整数提升小波的来由。2.2 分裂懒小波只是一个奇偶抽样提升的第一步是分裂Split把长度为偶数的信号 (x(n)) 按奇偶下标拆成两组偶数序列 (e(k) x(2k))奇数序列 (o(k) x(2k1))在 MATLAB 里这个操作就是e x(1:2:end); o x(2:2:end);这个简单的奇偶重排有时被称为“懒小波lazy wavelet”因为它只是重新组织数据没有做任何滤波也没有消除冗余。但它是后续预测和更新的基础。逆变换时把两个子序列交错合并就可以恢复原始信号因此懒小波本身是严格可逆的。分裂这一步要注意长度问题。如果输入长度为奇数最后会多出一个样本无法配对所以大多数提升小波实现要求输入长度是偶数或者先做边缘延展。2.3 预测让奇数被偶数“猜”出来猜不中就是细节第二步是预测Predict用偶数序列去预测奇数序列。由于相邻样本之间高度相关最简单的预测器是取左右两边偶数的平均值[ P(e)_k \frac{e(k-1)e(k)}{2} ]细节系数定义为预测误差[ d(k) o(k) - P(e)_k ]如果信号局部平滑那么 (d(k)) 会非常接近零如果信号在奇数位置发生高频跳变(d(k)) 就会出现明显的峰值。因此预测器的输出压缩了信号中的高频信息这就是小波细节系数的本质。预测器的选择决定了小波基的形状。5/3 小波使用上面这个线性预测器9/7 小波则把预测和更新步骤拆成四轮级联使用更高阶的多项式插值。预测器可以是非线性的只要在逆变换时用完全相同的规则计算出同一个预测值变换依然是可逆的。这是提升算法的核心优势也是它和线性滤波器组最根本的分歧。2.4 更新用细节修正偶数保住低通信息如果只做分裂和预测偶数序列是直接从原始信号里抽样出来的整体均值仍然保留但会出现频率混叠问题。为了让偶数序列真正成为平滑的近似信号需要引入更新Update步骤[ a(k) e(k) U(d)_k ]对于 5/3 小波更新器取相邻细节系数的平均值[ U(d)_k \frac{d(k-1)d(k)}{4} ]更新操作的目的是补偿分裂带来的子采样误差使近似序列 (a(k)) 的均值与原始信号一致。细节的局部高能量会通过更新调整偶数样本的值这样经过多级分解后近似系数能够保留信号低频能量细节系数则体现局部变化。预测器和更新器通常成对出现。5/3 小波的浮点形式就是著名的 CDF(2,2) 小波被用在 JPEG2000 无损模式而 9/7 浮点小波则是有损压缩模式的标准选择。下面的表格给出了常见系数对应关系方便在 MATLAB 里直接替换小波类型预测器更新器典型用途5/3 整数(o-\lfloor(e_pe_n)/2\rfloor)(e\lfloor(d_pd_n2)/4\rfloor)无损图像压缩5/3 浮点(o-(e_pe_n)/2)(e(d_pd_n)/4)快速去噪9/7 浮点四轮级联插值四轮级联修正JPEG2000 有损压缩2.5 逆变换反着做一遍就是完全重构提升小波的逆变换不是解方程而是把正向每一步的顺序倒过来执行。先撤销更新用当前近似系数和保存的细节系数恢复出偶数序列% 逆更新恢复偶数序列 e e a - U(d);再撤销预测用恢复出的偶数序列计算原始奇数序列% 逆预测恢复奇数序列 o o d P(e);最后将 e 和 o 交错合并就得到原始信号。整个过程不需要矩阵求逆也不依赖滤波器系数唯一的条件是预测器和更新器必须是同样的规则。整数版本的取整操作只要保证取整规则在正反方向一致就能做到完全无损重构这一点在后面的 MATLAB 代码里会实际验证。3. 用 MATLAB 从零实现小波提升算法5/3 整数变换的完整代码3.1 输入端口的检查与奇偶分裂在写提升函数时我习惯先处理输入约束再进入分裂步骤。下面的Lifting53_exact实现的是 5/3 整数提升小波输入是行向量长度必须是偶数。function [ca, cd] Lifting53_exact(x) % Lifting53_exact 5/3整数提升小波分解行向量输入 % 输入 x长度偶数的原始信号 % 返回 ca近似系数cd细节系数 len length(x); if mod(len, 2) ~ 0 error(输入信号长度必须是偶数); end % 分裂懒小波偶数下标和奇数下标 e x(1:2:end-1); o x(2:2:end); n len / 2; cd zeros(1, n); ca zeros(1, n);检查长度的原因是奇偶分裂要求两个子序列长度一致。x(1:2:end-1)取的是第一个、第三个、直到倒数第二个样本x(2:2:end)取的是第二个、第四个直到最后一个样本保证两个序列长度都是 (n)。如果输入为偶数长度这种取法不会丢失数据。3.2 预测和更新步骤的循环实现接下来是预测步骤。使用周期边界延拓用 MATLAB 的mod索引实现% 预测相邻偶数平均取整保证整数到整数 for k 1:n ePrev e(mod(k-2, n) 1); eNext e(mod(k, n) 1); cd(k) o(k) - floor((ePrev eNext) / 2); end % 更新相邻细节平均把均值偏差修正回偶数序列 for k 1:n dPrev cd(mod(k-2, n) 1); dNext cd(mod(k, n) 1); ca(k) e(k) floor((dPrev dNext 2) / 4); end end循环里的mod(k-2, n) 1在k1时取到n也就是上一级序列的最后一个样本mod(k,n)1在kn时取到1。这构成周期延拓。周期延拓实现简单但会在信号两端引入一次“伪突变”后面会用对称延拓改进。floor是整数提升的关键。预测部分直接取floor((ePreveNext)/2)得到整数预测值更新部分floor((dPrevdNext2)/4)中的2是对除法结果做四舍五入的补偿避免整数除法偏向负无穷。这个补偿让正反变换严格互逆。3.3 逆变换代码与无损验证逆变换函数必须和正向函数使用完全相同的取整规则否则恢复出来的信号会产生 ±1 的偏差。function xr ILifting53_exact(ca, cd) % ILifting53_exact 5/3整数提升小波重构 n length(ca); e zeros(1, n); o zeros(1, n); % 逆更新恢复偶数序列 for k 1:n dPrev cd(mod(k-2, n) 1); dNext cd(mod(k, n) 1); e(k) ca(k) - floor((dPrev dNext 2) / 4); end % 逆预测恢复奇数序列 for k 1:n ePrev e(mod(k-2, n) 1); eNext e(mod(k, n) 1); o(k) cd(k) floor((ePrev eNext) / 2); end % 合并重新交错排列 xr zeros(1, 2*n); xr(1:2:end) e; xr(2:2:end) o; end验证脚本可以用随机整数信号x0 randi(100, 1, 16); [ca, cd] Lifting53_exact(x0); x1 ILifting53_exact(ca, cd); isequal(x0, x1)运行结果会返回逻辑值1说明整数矩阵完全无损。这里要注意isa(x0,int8)的整数类型也可以但 MATLAB 默认randi返回double取整后仍然是双精度浮点数只是值等于整数用isequal验证不会出现浮点误差。3.4 5/3、9/7 与 CDF 系列参数对照实际使用中需要根据“无损还是有损”来切换提升参数。下表整理了常见参数直接替换函数中预测和更新的算术表达式即可方案预测步骤更新步骤重构精度5/3 整数o - floor((e_pe_n)/2)e floor((d_pd_n2)/4)完全无损5/3 浮点o - (e_pe_n)/2e (d_pd_n)/4浮点误差9/7 浮点三轮预测后加归一化三轮修正后加归一化浮点误差5/3 浮点和整数版本的差异只在有无取整。浮点版本用于去噪时阈值处理更平滑整数版本用于压缩场景。如果要做无损压缩必须保留整数方案如果只做特征提取浮点方案能避免舍入噪声。4. 工程化进阶小波提升算法的多级分解、边界策略与性能4.1 9/7 浮点提升系数的级联步骤9/7 小波是 JPEG2000 有损压缩的核心它不能像 5/3 一样一步预测一步更新而是用四轮级联构造更高阶的插值。下面是标准提升系数α、β、γ、δ 分别控制四轮中的权重最后用 (K) 和 (1/K) 做能量归一化alpha -1.586134342059924; beta -0.052980118572961; gamma 0.882911075530934; delta 0.443506852043971; K 1.1496043988602418;用周期边界的向量化写法整个正向分解可以压缩成寥寥几行function [ca, cd] Lifting97_periodic(x) % 9/7浮点提升周期边界向量化实现 e x(1:2:end); o x(2:2:end); n length(e); % 四轮提升 o o alpha * (e circshift(e, 1)); e e beta * (o circshift(o, 1)); o o gamma * (e circshift(e, 1)); e e delta * (o circshift(o, 1)); % 归一化 ca e / K; cd o * K; endcircshift(e,1)将序列向右平移一位让第 (k) 个样本与第 (k-1) 个样本对齐等价于循环边界下的邻域取值。这里每一轮更新后的序列边界需要重新计算circshift天然做到这一点。需要提醒的是周期边界与 JPEG2000 中使用的对称边界会有细微差别若要做到完全兼容 JPEG2000边界延拓方式也要换成对称扩展。4.2 多级分解循环与小波树单级提升只能把信号分成一层近似和一层细节。多级分解会对每一级的近似系数重复做提升function coeffs multiLift53(x, level) % multiLift53 多级5/3整数提升分解 % 返回 coeffs{1..level} 为各级细节系数coeffs{level1} 为最终近似系数 coeffs cell(1, level); tmp x; for j 1:level [tmp, cd] Lifting53_exact(tmp); coeffs{j} cd; end coeffs{level1} tmp; end重构时从最后一层开始先恢复上一级的近似系数再逐层恢复原始信号。这种存储方式对应小波树结构和 MATLAB 自带wavedec返回的C数组相比用 cell 数组管理多级系数更直观也更容易调试。分解层级level的上限取决于信号长度每级近似系数长度减半所以2^level不能超过信号长度。4.3 边界处理对称扩展与周期扩展周期扩展在信号首尾直接首尾相接实现简单但如果信号两端值差异较大会在边界产生虚假高频成分。对称扩展更平滑做法是把输入信号按边界镜面反射后再分解。MATLAB 小波工具箱提供了wextend可以这样用x_ext wextend(1D, sym, x, 4); [ca, cd] Lifting53_exact(x_ext);信号长度被对称扩展后需要根据扩展长度裁剪掉多余的边界系数。手动实现时关键是镜像索引公式扩展样本x(ni)对应原始样本x(n-i)MATLAB 里可以写[x fliplr(x)]得到最简单的半采样对称扩展。选择哪种扩展对后续重构没有影响只要逆变换使用相同的扩展策略。但在多级分解中每一级的信号长度会变化对称扩展的参数需要跟着调整这是工程实现中最容易出错的地方。4.4 向量化改写和运行时间对比上面的循环版 5/3 提升可读性好但在 MATLAB 中循环效率不高。如果信号长度比较大建议把预测和更新改成向量化版本function [ca, cd] Lifting53_vec(x) % 向量化5/3整数提升周期边界 e x(1:2:end); o x(2:2:end); cd o - floor((circshift(e, 1) e) / 2); ca e floor((circshift(cd, 1) cd 2) / 4); end这个版本和循环版的数学完全一致区别是circshift(e,1)一次性取出所有前一个样本。在大信号上向量化版本的时间消耗约为循环版的四分之一但还是不如 MATLAB 内置 MEX 实现快。提升算法在 MATLAB 中的价值主要不是绝对速度而是得到一段容易转换为 C 语言的整数运算代码。下表反映了三种形态的相对定位实现形态相对耗时代码可读性Coder 生成质量内置dwt/wavedec1 倍差黑盒不支持直接生成循环版提升8 倍左右最好可生成但代码长向量化提升2.5 倍左右中等可生成适合嵌入式5. 小波提升算法的落地技巧无损恢复、去噪和 C 代码导出准备5.1 用 isequal 核对完全重构在做无损压缩之前先确认正向提升和逆向提升是否完全互逆。强烈建议用比max(abs(x-x1))更严格的isequal来验证整数方案[ca, cd] Lifting53_exact(x); x1 ILifting53_exact(ca, cd); assert(isequal(x, x1), 重构失败);对于浮点 9/7isequal通常返回假这时应改用norm(x-x1, inf)检查误差量级。只要误差小于 (10^{-10})说明提升系数和边界处理都没有写错。5.2 软阈值去噪的完整流水线整数 5/3 提升的细节系数是整数去噪时如果阈值设置不合适容易产生阶跃性的量化误差。更稳妥的做法是使用浮点 5/3 或 9/7 进行去噪。一层分解已经足够处理短信号[ca, cd] Lifting97_periodic(x_noisy); th 0.4 * median(abs(cd)); % 鲁棒阈值估计 cd wthresh(cd, s, th); x_denoised ILifting97_periodic(ca, cd);median(abs(cd))是 Donoho 阈值公式中的噪声估计方式。软阈值wthresh(...,s,th)会把系数绝对值压缩保留信号的连续变化比硬阈值更适合振动信号和生物电信号。对于更高维的二维图像可以按行做一次提升再按列做一次提升等效于二维可分离小波。5.3 面向 Coder 和嵌入式设备的整数运算核如果要把提升算法部署到嵌入式设备建议将 5/3 整数提升中的floor((ab)/2)改写成移位运算(ab)1更新步骤的floor((ab2)/4)改写成(ab2)2。整形移位速度快且行为可预测但要注意 C 语言对负数的右移是算术右移结果与 MATLAB 的floor并不完全一致。移植前需要单独测试负数值的边界条件这是整数提升落地时最容易埋坑的地方。MATLAB Coder 可以直接把Lifting53_vec和ILifting53_exact转成 C 代码前提是所有函数内部不使用动态改变大小的数组。上面的实现里zeros(1,n)已经预先分配了输出满足 Coder 的静态长度要求。生成的代码可以继续用于 Verilog 或 VHDL 的硬件模型对照测试最终在 FPGA 上实现一个没有乘法器的小波变换核。本文还有配套的精品资源点击获取