手动实现一维离散数据小波分解与重构

前言

本文集中前面主要介绍了离散数据的傅里叶变换,并且得到了较好的效果!那既然有了傅里叶变换这个工具,为什么还需要小波变换呢?因为:傅里叶变换只能告诉你原始信号中有哪些频率,但不能告诉你这些频率的信号出现在什么时间!也就说明:如果信号是"时变"的(频率随着时间是改变的),那么单纯用傅里叶变换所能反映的信息就十分有限了!因此,针对时变信号,我们使用小波变换。图1展示"时变信号"与"时不变信号"区别:

手动实现一维离散数据小波分解与重构_第1张图片
图1:时不变信号与时变信号

时不变与时变的区别,看下面的实现的代码就很轻易理解:

x = 0:0.001:1;

% 4个频率: 
f1 = 50; f2 = 80; f3 = 110; f4 = 20;

% 时不变信号: 多频
y1 = sin(2*pi*f1*x) + sin(2*pi*f2*x) + sin(2*pi*f3*x) + sin(2*pi*f4*x);
% 时变信号: 多频 
y2 = sin(2*pi*f1*x).*(x<=0.3) + sin(2*pi*f2*x).*(x>0.3 & x<=0.6)+...
     sin(2*pi*f3*x).*(x>0.6 & x<=0.8) + sin(2*pi*f4*x).*(x>0.8);

figure(1);

subplot(2,1,1);
plot(y1);
grid on;
xlabel('采样点'); ylabel('振幅');
axis([0 1000 -inf inf]);
title('时不变信号');

subplot(2,1,2);
plot(y2);
grid on;
xlabel('采样点'); ylabel('振幅');
axis([0 1000 -inf inf]);
title('时变信号')

本文同样考虑的是离散数据的小波变换使用。通过手动matlab编程实现小波变换"塔式分解"与"重构"来深刻了解小波变换实现的内在含义。之后,借助matlab自带的一系列相关小波变换程序来实现"时频分析"和"小波去噪"。

说明:本文更加侧重详细介绍matlab自带各种小波功能函数的使用!除了小波分解与重构的程序我们手动实现外,其他的各种操作都建议用自带函数实现。

小波分解:

小波分解的流程总结为:先将信号对半分解成"低频近似"与"高频细节"2个部分;同样的操作每次将上一次的"低频近似"部分再分成低频近似和高频细节部分,逐次细分(最多分解到每个部分只有1个点)。每次分出的高频细节部分不做分解。因此:每次分出低频近似部分相当于对本次信号做"低通滤波",分出的高频细节部分相当于对本次信号做"高通滤波"。所以:每次小波分解就是用1个低通滤波器和1个高通滤波器对本次信号做1次低通滤波和1次高通滤波而已。

由上述说明可得:小波分解的关键在于2个(一组)滤波器。对于现实的离散数据而言,滤波器看上去很高大上其实就是很简单的数字而已,滤波听起来很难,其实就是做"点乘相加"而已。离散小波分解中最简单的一组滤波器为:

低通滤波器:;高通滤波器:。

下面举例说明如何用上面这一组最简单滤波器对离散数据进行小波分解:

假设我们的离散数据为:

(1) 第一级分解:

低通滤波:

得到低频近似部分:

高通滤波:

得到高频细节部分:

(2)第二级分解:

分解上一次分解得到的低频近似部分,高频细节不动。即待分解信号为:

低通滤波:

得到的低频近似部分为:

高通滤波:

得到的高频细节部分为:

(3)第3级分解:

同理,待分解信号是上一次分解得到的低频近似部分:

低通滤波:

得到的低频近似部分为:

高通滤波:

得到的高频细节部分为:

到此为止,例子中给出的原始离散信号就达到了其最大分解级数(分解到元素只有1个)。整个过程很简单,只需注意每次点乘求和元素是无重合的。整个的多级分解过程如图2所示:

手动实现一维离散数据小波分解与重构_第2张图片
图2:离散信号小波多级分解示意图

注意:不同组的高通和低通滤波中都有这样的一个规律:两者的区别只是高通滤波器第2个值负数而已;数都是一样的。

小波多级分解清楚了,那怎么"重构/恢复"回去呢?塔式分解的逆向合成而已。根据滤波器的规律,我们可以设:

以2级分解到3级为例,我们知道:

那么逆过程就是,我们知道了3级低通近似和高通细节的值,我们还知道滤波器的数值(a已知),然后反推2级低通近似和高通细节数值,即:

所以:

这样我们就得到了2级低通近似和2解高通细节,然后逐级往上递推即可实现重构/恢复~ so easy.

整个分解过程我们清楚了,现在我们引入一些专业的名词:在离散数据中,一组低通高通滤波器,其实就是"小波基函数"!取不同的小波基函数其实就是滤波器里面的数值不同而已。最常用的"haar小波基"。下面我们就利用haar小波基,在matlab里手动实现小波分解与重构:

matlab手动实现小波分解程序:

clc ; clear;

% 每次修改这里的原始数据, 个数最好是2^n
% x = [9 7 3 5];
 x = [2 5 8 9 7 4 -1 1];
% x = [2 5 8 9 7 4 -1 1 2 1 8 3 8 0 3 1];

order_max = log(length(x))/log(2);
fprintf('当前数据最多分解%d阶\n',order_max);
order = double(input('自定义分解阶数( order

matlab手动实现小波重构/恢复程序:

clc ; clear;

% 每次修改这里的原始数据, 个数最好是2^n
% x = [9 7 3 5];
 x = [2 5 8 9 7 4 -1 1];
% x = [2 5 8 9 7 4 -1 1 2 1 8 3 8 0 3 1];

order_max = log(length(x))/log(2);
fprintf('当前数据最多分解%d阶\n',order_max);
order = double(input('自定义分解阶数( order

你可能感兴趣的:(手动实现一维离散数据小波分解与重构)