C代码小波变换与解释

时间:2014-04-08 20:26:55

标签: c numerical-methods wavelet

我正在尝试在C中实现小波变换,我以前从未这样做过。我已经阅读了一些关于Wavelets的内容,并了解了不断增长的子空间。想法,以及Mallat的单面滤波器组基本上是一样的想法。

然而,我仍然坚持如何实际实现Mallat的快速小波变换。这是我到目前为止所理解的:

  1. 高通滤波器h(t)为您提供细节系数。对于给定的标度j,它是母小波W(t)的反射,扩张和标准化版本。

  2. g(t)是组成差异的低通滤波器。它应该是h(t)

  3. 的正交镜
  4. 要获得细节系数或第j级的近似系数,您需要分别将信号块与h(t)或g(t)进行卷积,并将信号下采样2 ^ {j} (即取每2 ^ {j}值)

  5. 然而,这些是我的问题:

    1. 当我知道h(t)时如何找到g(t)?

    2. 如何计算此变换的倒数?

    3. 你有可以参考的任何C代码吗? (是的,我在维基上发现了一个,但它没有帮助)

      我想要一些代码说:

      一个。这是过滤器

      B中。这是变换(非常明确) C.)这是逆变换(再次为假人)

      感谢您的耐心等待,但似乎并不是一个Step1 - Step2 - Step3 - 等指导那里有明确的例子(因为所有的系数都是1而且没有令人困惑的事情。)

2 个答案:

答案 0 :(得分:3)

fwt的Mallat配方非常简单。如果您查看matlab代码,例如Jeffrey Kantor的script,所有步骤都很明显。

在C中它的工作量稍微多一些,但主要是因为你需要处理自己的声明和分配。

首先,关于你的总结:

  1. 通常过滤器 h 是低通滤波器,代表缩放功能(父亲)
  2. 同样, g 通常是代表小波(母亲)的高通滤波器
  3. 您无法在1个过滤+下采样步骤中执行 J 级别分解。在每个级别,您可以通过使用 h 和下采样进行过滤来创建近似信号 c ,并通过使用 g进行过滤来创建详细信号 d 和下采样,并在下一级重复此操作(使用当前 c
  4. 关于您的问题:

    1. 对于正交小波基的滤波器 h ,[h_1 h_2 .. h_m h_n],QMF为[h_n -h_m .. h_2 -h_1],其中 n < / em>是偶数, m == n -1
    2. 逆变换与fwt的反面相反:在每个级别,它上传采样细节 d 和近似 c ,将 d 进行卷积> g c h ,并将信号加在一起 ​​- 请参阅相应的matlab script
    3. 使用此信息,并给出x lendouble类型点的信号h,缩放g和小波f过滤器{{1}系数(也是类型double)和分解级别lev,这段代码实现了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);
      

      它使用了一个额外的阵列:工作区&#39; t要复制近似值c(输入信号x开始),以便进行下一次迭代。

      请参阅此示例C program,您可以使用gcc -std=c99 -fpermissive main.cpp进行编译并使用./a.out运行。

      倒数也应该是这些方面的东西。祝你好运!

答案 1 :(得分:0)

唯一缺少的是过滤操作的一些填充。 行

y[j]     +=t[2*j+k]*h[k];      
        y[j+len2]+=t[2*j+k]*g[k];

在第一次迭代期间超过t阵列的边界,并且在随后的迭代期间超过阵列的近似部分。必须在t阵列的开头添加(f-1)个元素。

double *t=calloc(len+f-1, sizeof(double));
memcpy(&t[f], x, len*sizeof(double));        
for (int i=0; i<lev; i++) {
memset(t, 0, (f-1)*sizeof(double));        
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[f], y, len*sizeof(double));    
}