一维小波变换,可多次分解

来源:互联网 发布:网络位置类型怎么设置 编辑:程序博客网 时间:2024/04/30 10:21

1、题目:一维小波变换,可多次分解

2、原理:卷积核变为Daubechies正交小波基h[]和g[]的交替形式。增加了多次分解的功能。

3、代码:

view plaincopy to clipboardprint?
  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3. #include <math.h> 
  4. #define LENGTH 4096//信号长度 
  5. /*****************************************************************
  6. * 一维卷积函数
  7. *
  8. * 说明: 循环卷积,卷积结果的长度与输入信号的长度相同
  9. *
  10. * 输入参数: data[],输入信号; h[],Daubechies小波基低通滤波器系数;
  11. *            g[],Daubechies小波基高通滤波器系数; cov[],卷积结果;
  12. *            n,输入信号长度; m,卷积核长度.
  13. *
  14. * 李承宇, lichengyu2345@126.com
  15. *
  16. *  2010-08-22  
  17. *****************************************************************/
  18. void Covlution(double data[], double h[], double g[], double cov[] 
  19.                , int n, int m) 
  20.     int i = 0; 
  21.     int j = 0; 
  22.     int k = 0; 
  23.     //将cov[]清零 
  24.     for(i = 0; i < n; i++) 
  25.     { 
  26.         cov[i] = 0; 
  27.     } 
  28.     //**************************************************** 
  29.     //奇数行用h[]进行卷积 
  30.     //**************************************************** 
  31.     //前m/2+1行 
  32.     i = 0; 
  33.     for(j = 0; j < m/2; j+=2, i+=2) 
  34.     { 
  35.         for(k = m/2-j; k < m; k++ ) 
  36.         { 
  37.             cov[i] += data[k-(m/2-j)] * h[k];//k针对core[k] 
  38.         } 
  39.         for(k = n-m/2+j; k < n; k++ ) 
  40.         { 
  41.             cov[i] += data[k] * h[k-(n-m/2+j)];//k针对data[k] 
  42.         } 
  43.     } 
  44.     //中间的n-m行 
  45.     for( ; i <= (n-m)+m/2; i+=2) 
  46.     { 
  47.         for( j = 0; j < m; j++) 
  48.         { 
  49.             cov[i] += data[i-m/2+j] * h[j]; 
  50.         } 
  51.     } 
  52.     //最后m/2-1行 
  53. //  i = ( (n - m) + m/2 + 1 )/2*2;//********** 
  54.     for(j = 1; j <= m/2; j+=2, i+=2) 
  55.     { 
  56.         for(k = 0; k < j; k++) 
  57.         { 
  58.             cov[i] += data[k] * h[m-j-k];//k针对data[k] 
  59.         } 
  60.         for(k = 0; k < m-j; k++) 
  61.         { 
  62.             cov[i] += h[k] * data[n-(m-j)+k];//k针对core[k] 
  63.         } 
  64.     } 
  65.     //**************************************************** 
  66.     //偶数行用g[]进行卷积 
  67.     //**************************************************** 
  68.     //前m/2+1行 
  69.     i = 1; 
  70.     for(j = 0; j < m/2; j+=2, i+=2) 
  71.     { 
  72.         for(k = m/2-j; k < m; k++ ) 
  73.         { 
  74.             cov[i] += data[k-(m/2-j)] * g[k];//k针对core[k] 
  75.         } 
  76.         for(k = n-m/2+j; k < n; k++ ) 
  77.         { 
  78.             cov[i] += data[k] * g[k-(n-m/2+j)];//k针对data[k] 
  79.         } 
  80.     } 
  81.     //中间的n-m行 
  82.     for( ; i <= (n-m)+m/2; i+=2) 
  83.     { 
  84.         for( j = 0; j < m; j++) 
  85.         { 
  86.             cov[i] += data[i-m/2+j] * g[j]; 
  87.         } 
  88.     } 
  89.     //最后m/2-1行 
  90. //  i = ( (n - m) + m/2 + 1 ) ;//********* 
  91.     for(j = 1; j <= m/2; j+=2, i+=2) 
  92.     { 
  93.         for(k = 0; k < j; k++) 
  94.         { 
  95.             cov[i] += data[k] * g[m-j-k];//k针对data[k] 
  96.         } 
  97.         for(k = 0; k < m-j; k++) 
  98.         { 
  99.             cov[i] += g[k] * data[n-(m-j)+k];//k针对core[k] 
  100.         } 
  101.     } 
  102. /***************************************************************** 
  103. *   排序函数 
  104. *   将卷积后的结果进行排序,使尺度系数和小波系数分开 
  105. *****************************************************************/ 
  106. void Sort(double data[], double sort[], int n) 
  107.     for(int i = 0; i < n; i+=2) 
  108.     { 
  109.         sort[i/2] = data[i]; 
  110.     } 
  111.     for(i = 1; i < n; i+=2) 
  112.     { 
  113.         sort[n/2+i/2] = data[i]; 
  114.     } 
  115. /*****************************************************************
  116. * 一维小波变换函数
  117. *
  118. * 说明: 一维小波变换,可进行多次分解 
  119. *
  120. * 输入参数: input[],输入信号; output[],小波变换结果,包括尺度系数
  121. * 和小波系数两部分; temp[],存放中间结果;h[],Daubechies小波基低通滤
  122. * 波器系数;g[],Daubechies小波基高通滤波器系数;n,输入信号长度; m,
  123. * Daubechies小波基紧支集长度; nStep,小波变换分解次数
  124. *
  125. * 李承宇, lichengyu2345@126.com
  126. *
  127. *  2010-08-22  
  128. *****************************************************************/ 
  129. void DWT1D(double input[], double output[], double temp[], double h[],  
  130.            double g[], int n, int m, int nStep) 
  131.     int i = 0; 
  132.     for(i = 0; i < n; i++) 
  133.     { 
  134.         output[i] = input[i]; 
  135.     } 
  136.     for(i = 0; i < nStep; i++) 
  137.     { 
  138.         Covlution(output, h, g, temp, n, m); 
  139.         Sort(temp, output, n); 
  140.         n = n/2; 
  141.     } 
  142. void main() 
  143.     double data[LENGTH];//输入信号 
  144.     double temp[LENGTH];//中间结果 
  145.     double data_output[LENGTH];//一维小波变换后的结果 
  146.     int n = 0;//输入信号长度 
  147.     int m = 6;//Daubechies正交小波基长度 
  148.     int nStep = 6;//分解级数 
  149.     int i = 0;  
  150.     char s[32];//从txt文件中读取一行数据 
  151.     static double h[] = {.332670552950, .806891509311, .459877502118,  
  152.         -.135011020010, -.085441273882, .035226291882}; 
  153.     static double g[] = {.035226291882, .085441273882, -.135011020010,  
  154.         -.459877502118, .806891509311, -.332670552950}; 
  155.     //读取输入信号 
  156.     FILE *fp; 
  157.     fp=fopen("data.txt","r"); 
  158.     if(fp==NULL) //如果读取失败 
  159.     { 
  160.         printf("错误!找不到要读取的文件/"data.txt/"/n"); 
  161.         exit(1);//中止程序 
  162.     } 
  163.     while( fgets(s, 32, fp) != NULL )//读取长度n要设置得长一点,要保证读到回车符,这样指针才会定位到下一行?回车符返回的是零值?是,非数字字符经过atoi变换都应该返回零值 
  164.     { 
  165.     //  fscanf(fp,"%d", &data[count]);//一定要有"&"啊!!!最后读了个回车符!适应能力不如atoi啊 
  166.         data[n] = atof(s); 
  167.         n++; 
  168.     } 
  169.     //一维小波变换 
  170.     DWT1D(data, data_output, temp, h, g, n, m, nStep); 
  171.     //一维小波变换后的结果写入txt文件 
  172.     fp=fopen("test.txt","w"); 
  173.     //打印一维小波变换后的结果 
  174.     for(i = 0; i < n/pow(2,nStep-1); i++)///pow(2,nStep-1) 
  175.     { 
  176.         printf("%f/n", data_output[i]); 
  177.         fprintf(fp,"%f/n", data_output[i]); 
  178.     } 
  179.     //关闭文件 
  180.     fclose(fp); 

4、测试结果:

输入信号x(i)为:

取f1 = 5, f2 = 10, f0 = 320, n = 512。x(i)如图1所示:

图1 输入信号

各级分解的结果如图2~图7所示,左半部分为尺度系数,右半部分为小波系数:

图2 1级分解结果

图3 2级分解结果

图4 3级分解结果

图5 4级分解结果

图6 5级分解结果

图7 6级分解结果

图8是各级小波系数和第6级尺度系数的完整结果:

图8 第6级尺度系数和各级小波系数的完整结果

 

http://blog.csdn.net/lichengyu/article/details/5829785#

原创粉丝点击