我正在尝试用 C 实现小波变换,但我以前从未做过。我读过一些关于小波的文章,理解“增长子空间”的想法,以及 Mallat 的单边滤波器组本质上是相同的想法。
但是,我对如何实际实现 Mallat 的快速小波变换一头雾水。这是我目前的理解:
高通滤波器 h(t) 为您提供细节系数。对于给定的尺度 j,它是母小波 W(t) 的反射、扩张和归一化版本。
g(t) 就是弥补差异的低通滤波器。应该是h(t)的正交镜
要获得第 j 级的细节系数或近似系数,您需要分别将信号 block 与 h(t) 或 g(t) 进行卷积,然后将信号下采样 2^{j} (即取每2^{j}个值)
但是这些是我的问题:
当我知道 h(t) 时,如何找到 g(t)?
如何计算此变换的逆?
你有任何我可以引用的 C 代码吗? (是的,我在 wiki 上找到了,但没有用)
我想用一些代码来表达的是:
一个。这是过滤器
B.这是转换(非常明确) C.) 这是逆变换(同样适用于傻瓜)
感谢您的耐心等待,但似乎没有第 1 步 - 第 2 步 - 第 3 步等带有明确示例的指南(这不是 HAAR,因为所有系数都是 1,这让事情变得困惑)。
最佳答案
fwt 的 Mallat 配方非常简单。如果您查看 matlab 代码,例如 script通过 Jeffrey Kantor,所有步骤都很明显。
在 C 中,工作量要多一些,但这主要是因为您需要处理自己的声明和分配。
首先,关于您的总结:
- 通常滤波器h是低通滤波器,代表缩放函数(父)
- 同样,g通常是代表小波(母)的高通滤波器
- 您无法在 1 个过滤+下采样步骤中执行 J 级分解。在每个级别,您通过使用 h 和下采样进行过滤来创建近似信号 c,通过使用 g 进行过滤来创建细节信号 d 和下采样,并在下一级别重复此操作(使用当前的 c)
关于您的问题:
- 对于正交小波基 [h_1 h_2 .. h_m h_n] 的滤波器 h,QMF 为 [h_n -h_m .. h_2 -h_1],其中 n 是偶数,m==n-1
- 逆变换与 fwt 相反:在每个级别上采样细节 d 和近似值 c,将 d 与 g 和 c 与 h,并将信号加在一起——参见相应的 matlab script .
使用此信息,并给定 len
个double
类型的信号 x
,缩放 h
和f
系数(也是 double
类型)的小波 g
滤波器,以及分解级别 lev
,这 block 代码实现 Mallat fwt:
double *t=calloc(len+f-1, sizeof(double));
memcpy(t, x, len*sizeof(double));
for (int i=0; i<lev; i++) {
memset(y, 0, len*sizeof(double));
int len2=len/2;
for (int j=0; j<len2; j++)
for (int k=0; k<f; k++) {
y[j] +=t[2*j+k]*h[k];
y[j+len2]+=t[2*j+k]*g[k];
}
len=len2;
memcpy(t, y, len*sizeof(double));
}
free(t);
它使用一个额外的数组:一个“工作区”t
来复制近似值 c
(输入信号 x
开始)下一次迭代。
请参阅此示例 C program ,您可以使用 gcc -std=c99 -fpermissive main.cpp
编译并使用 ./a.out
运行。
逆向也应该遵循这些思路。祝你好运!
关于C代码小波变换及解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22947469/