一维小波变换

本文详细介绍了基于Mallat算法的一维小波变换原理,通过使用Daubechies正交小波基对输入信号进行卷积操作,实现尺度系数和小波系数的提取。并提供了具体的C++代码实现,通过实际测试展示了变换前后信号的特点,适用于信号处理领域的深入理解与实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、题目:一维小波变换

 

2、原理:Mallat算法,用Daubechies正交小波基作为卷积核对输入信号作卷积,对结果进行重排可得一维小波变换后的尺度系数和小波系数。可参见《实用小波分析入门》(刘涛、曾祥利、曾军主编,国防工业出版社,2006年4月第一看看版)第105~106页。

 

3、代码:

 

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

 

4、测试结果:

输入信号x(i)为:

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

图1 输入信号x(i)

 

一维小波变换后的信号如图2和图3所示:

图2 一维小波变换后的信号,尺度系数和小波系数混在一起

图3 一维小波变换后的信号,尺度系数和小波系数分开,左半部分为尺度系数,右半部分为小波系数

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值