1、小波閾值去噪理論
小波閾值去噪就是對信號進行分解,然后對分解后的系數進行閾值處理,最后重構得到去噪信號。該算法其主要理論依據是:小波變換具有很強的去數據相關性,它能夠使信號的能量在小波域集中在一些大的小波系數中;而噪聲的能量卻分布于整個小波域內。因此,經小波分解后,信號的小波系數幅值要大于噪聲的系數幅值。可以認為,幅值比較大的小波系數一般以信號為主,而幅值比較小的系數在很大程度上是噪聲。于是,采用閾值的辦法可以把信號系數保留,而使大部分噪聲系數減小至零。小波閾值收縮法去噪的具體處理過程為:將含噪信號在各尺度上進行小波分解,設定一個閾值,幅值低于該閾值的小波系數置為0,高于該閾值的小波系數或者完全保留,或者做相應的“收縮(shrinkage)”處理。最后將處理后獲得的小波系數用逆小波變換進行重構,得到去噪后的信號.
2、小波閾值去噪c語言程序
此程序是用于信號處理分析,突出奇異值的前段處理,對信號進行小波包分解,用C語言實現的,僅供參考。
#include
#include
#include
#include
#defineLENGTH4096//信號長度
#defineDB_LENGTH8//Daubechies小波基緊支集長度
/******************************************************************
* 一維卷積函數
* 說明:循環卷積,卷積結果的長度與輸入信號的長度相同
* 輸入參數:data[],輸入信號;core[],卷積核;cov[],卷積結果;
*n,輸入信號長度;m,卷積核長度。
******************************************************************/
/*voidCovlution(doubledata[],doublecore[],doublecov[],intn,intm)
{
inti=0;
intj=0;
intk=0;
//將cov[]清零
for(i=0;i《n;i++)
{
cov[i]=0;
}
//前m/2+1行
i=0;
for(j=0;j《m/2;j++,i++)
{
for(k=m/2-j;k《m;k++)
{
cov[i]+=data[k-(m/2-j)]*core[k];//k針對core[k]
}
for(k=n-m/2+j;k《n;k++)
{
cov[i]+=data[k]*core[k-(n-m/2+j)];//k針對data[k]
}
}
//中間的n-m行
for(i=m/2;i《=(n-m)+m/2;i++)
{
for(j=0;j《m;j++)
{
cov[i]+=data[i-m/2+j]*core[j];
}
}
//最后m/2-1行
i=(n-m)+m/2+1;
for(j=1;j《m/2;j++,i++)
{
for(k=0;k《j;k++)
{
cov[i]+=data[k]*core[m-j-k];//k針對data[k]
}
for(k=0;k《m-j;k++)
{
cov[i]+=core[k]*data[n-(m-j)+k];//k針對core[k]
}
}
}
*/
//定義一個線性卷積
voidCovlution(doubledata[],doublecore[],doublecov[],intn,intm)
{
inti=0;
intj=0;
intt=0;
//將cov[]清零
for(j=0;j《n+m-1;j++)
{
cov[j]=0;
}
for(j=0;j《m+n-1;j++)
{
if(j《=m-1)//前面m行
{
for(i=0,t=j;t》=0;i++,t--)
cov[j]+=data[i]*core[t];
}
elseif(j《=n-1)//中間n-m行
{
for(i=j-m+1,t=m-1;t》=0;i++,t--)
cov[j]+=data[i]*core[t];
}
else//后面m行
{
for(i=j-m+1,t=m-1;i《n;i++,t--)
cov[j]+=data[i]*core[t];
}
}
}
/******************************************************************
* 一維小波變換函數
* 說明:一維小波變換,只變換一次
* 輸入參數:input[],輸入信號;output[],小波變換結果,包括尺度系數和
* 小波系數兩部分;temp[],存放中間結果;h[],Daubechies小波基低通濾波器系數;
* g[],Daubechies小波基高通濾波器系數;n,輸入信號長度;m,Daubechies小波基緊支集長度。
******************************************************************/
voidDWT1D_1(doubleinput[],doubleoutput0[],doubleoutput1[],doubletemp[],doubleh[],
doubleg[],intn,intm)
{
//doubletemp[LENGTH]={0};//?????????????
inti=0;
/*
//尺度系數和小波系數放在一起
Covlution(input,h,temp,n,m);
for(i=0;i《n;i+=2)
{
output[i]=temp[i];
}
Covlution(input,g,temp,n,m);
for(i=1;i《n;i+=2)
{
output[i]=temp[i];
}
*/
//尺度系數和小波系數分開
Covlution(input,h,temp,n,m);
for(i=0;i《n+m-1;i+=2)
{
output0[i/2]=temp[i];//尺度系數,進行了2抽值,即尺度空間,低頻概貌部分
}
Covlution(input,g,temp,n,m);
for(i=1;i《n+m-1;i+=2)
{
//output[i]=temp[i];
output1[(i-1)/2]=temp[i];//小波系數,已經進行了2抽取,即高頻細節部分
}
}
voidDWT1D_2(doubleinput[],doubleAA2[],doubleDA2[],doubleAD2[],doubleDD2[],doubletemp0[],doubletemp1[],doubletemp[],doubleh[],
doubleg[],intn,intm)
{
DWT1D_1(input,temp0,temp1,temp,h,g,n,m);
inta1=(m+n)/2;
DWT1D_1(temp0,AA2,DA2,temp,h,g,a1,m);
intd1=(n+m-4)/2;
DWT1D_1(temp1,AD2,DD2,temp,h,g,d1,m);
}
voidDWT1D_3(doubleinput[],doubleAAA3[],doubleDAA3[],doubleADA3[],doubleDDA3[],doubleAAD3[],doubleDAD3[],doubleADD3[],doubleDDD3[],
doubletemp0[],doubletemp1[],doubletemp2[],doubletemp3[],doubletemp00[],doubletemp11[],doubletemp[],doubleh[],doubleg[],intn,intm)
{
DWT1D_2(input,temp0,temp1,temp2,temp3,temp00,temp11,temp,h,g,n,m);
intaa2=(m+n)/4;
DWT1D_1(temp0,AAA3,DAA3,temp,h,g,aa2,m);
intda2=(n+3*m-8)/4;
DWT1D_1(temp1,ADA3,DDA3,temp,h,g,da2,m);
intad2=(n+3*m-4)/4;
DWT1D_1(temp2,AAD3,DAD3,temp,h,g,ad2,m);
intdd2=(n+3*m-12)/4;
DWT1D_1(temp3,ADD3,DDD3,temp,h,g,dd2,m);
}
voidmain()
{
doubledata[LENGTH];//輸入信號
doubletemp0[(LENGTH+DB_LENGTH)/4];//先定義了一個中間結果
doubletemp1[(LENGTH+DB_LENGTH*3-8)/4];
doubletemp2[(LENGTH+DB_LENGTH*3-4)/4];
doubletemp3[(LENGTH+DB_LENGTH*3-12)/4];
doubletemp00[(LENGTH+DB_LENGTH)/2];
doubletemp11[(LENGTH+DB_LENGTH-4)/2];
doubletemp[LENGTH+DB_LENGTH-1];
doubleAAA3[(LENGTH+DB_LENGTH*5)/8];//一維小波變換后的結果
doubleDAA3[(LENGTH+DB_LENGTH*5-16)/8];
doubleADA3[(LENGTH+DB_LENGTH*7-8)/8];
doubleDDA3[(LENGTH+DB_LENGTH*7-24)/8];
doubleAAD3[(LENGTH+DB_LENGTH*7-4)/8];
doubleDAD3[(LENGTH+DB_LENGTH*7-20)/8];
doubleADD3[(LENGTH+DB_LENGTH*7-12)/8];
doubleDDD3[(LENGTH+DB_LENGTH*7-28)/8];
intaaa3=(LENGTH+DB_LENGTH*5)/8;//一維小波變換后的結果數組的長度
intdaa3=(LENGTH+DB_LENGTH*5-16)/8;
intada3=(LENGTH+DB_LENGTH*7-8)/8;
intdda3=(LENGTH+DB_LENGTH*7-24)/8;
intaad3=(LENGTH+DB_LENGTH*7-4)/8;
intdad3=(LENGTH+DB_LENGTH*7-20)/8;
intadd3=(LENGTH+DB_LENGTH*7-12)/8;
intddd3=(LENGTH+DB_LENGTH*7-28)/8;
intn=0;//輸入信號長度
intm=8;//Daubechies正交小波基長度
inti=0;
chars[32];//從txt文件中讀取一行數據
/*//DB3
staticdoubleh[]={.332670552950,.806891509311,.459877502118,-.135011020010,
-.085441273882,.035226291882};
staticdoubleg[]={.035226291882,.085441273882,-.135011020010,-.459877502118,
.806891509311,-.332670552950};
*/
//DB4
staticdoubleh[]={0.2303778133088964,0.7148465705529154,0.6308807679398587,-0.0279837694168599,-0.1870348117190931,0.0308413818355607,0.0328830116668852,-0.0105974017850690};//h[],Daubechies小波基低通濾波器系數;
staticdoubleg[]={-0.0105974017850690,-0.0328830116668852,0.0308413818355607,0.1870348117190931,-0.0279837694168599,-0.6308807679398587,0.7148465705529154,-0.2303778133088964};//g[],Daubechies小波基高通濾波器系數
//讀取輸入信號
FILE*fp;
FILE*fp0,*fp1,*fp2,*fp3,*fp4,*fp5,*fp6,*fp7;
fp=fopen(“heb1.txt”,“r”);
if(fp==NULL)//如果讀取失敗
{
printf(“錯誤!找不到要讀取的文件hea1.txt/n”);
exit(1);//中止程序
}
while(fgets(s,32,fp)!=NULL)//讀取長度n要設置得長一點,要保證讀到回車符,這樣指針才會定位到下一行?回車符返回的是零值?是,非數字字符經過atoi變換都應該返回零值
{
//fscanf(fp,“%d”,&data[count]);//一定要有“&”啊!!!最后讀了個回車符!適應能力不如atoi啊
data[n]=atof(s);
n++;
}
//一維小波變換
//DWT1D(data,data_output,temp,h,g,n,m);
DWT1D_3(data,AAA3,DAA3,ADA3,DDA3,AAD3,DAD3,ADD3,DDD3,
temp0,temp1,temp2,temp3,temp00,temp11,temp,h,g,n,m);
//一維小波變換后的結果寫入txt文件
fp0=fopen(“data_output_db4_aaa3.txt”,“w”);
fp1=fopen(“data_output_db4_daa3.txt”,“w”);
fp2=fopen(“data_output_db4_ada3.txt”,“w”);
fp3=fopen(“data_output_db4_dda3.txt”,“w”);
fp4=fopen(“data_output_db4_aad3.txt”,“w”);
fp5=fopen(“data_output_db4_dad3.txt”,“w”);
fp6=fopen(“data_output_db4_add3.txt”,“w”);
fp7=fopen(“data_output_db4_ddd3.txt”,“w”);
//打印一維小波變換后的結果
for(i=0;i《aaa3;i++)
{//if(i==0)
printf(“%s\n”,“AAA3”);
printf(“%f\n”,AAA3[i]);
fprintf(fp0,“%f\n”,AAA3[i]);
//}
//else
//{
//printf(“%f\n”,AAA3[i]);
//fprintf(fp0,“%f\n”,AAA3[i]);
//}
}
for(i=0;i《daa3;i++)
{//if(i==0)
printf(“%s\n”,“DAA3”);
printf(“%f\n”,DAA3[i]);
fprintf(fp1,“%f\n”,DAA3[i]);
//}
//else
//{
//printf(“%f\n”,DAA3[i]);
//fprintf(fp1,“%f\n”,DAA3[i]);
//}
}
for(i=0;i《ada3;i++)
{//if(i==0)
printf(“%s\n”,“ADA3”);
printf(“%f\n”,ADA3[i]);
fprintf(fp2,“%f\n”,ADA3[i]);
//}
//else
//{
//printf(“%f\n”,ADA3[i]);
//fprintf(fp2,“%f\n”,ADA3[i]);
//}
}
for(i=0;i《dda3;i++)
{//if(i==0)
printf(“%s\n”,“DDA3”);
printf(“%f\n”,DDA3[i]);
fprintf(fp3,“%f\n”,DDA3[i]);
//}
//else
//{
//printf(“%f\n”,DDA3[i]);
//fprintf(fp3,“%f\n”,DDA3[i]);
//}
}
for(i=0;i《aad3;i++)
{//if(i==0)
printf(“%s\n”,“AAD3”);
printf(“%f\n”,AAD3[i]);
fprintf(fp4,“%f\n”,AAD3[i]);
//}
//else
//{
//printf(“%f\n”,AAD3[i]);
//fprintf(fp4,“%f\n”,AAD3[i]);
//}
}
for(i=0;i《dad3;i++)
{//if(i==0)
printf(“%s\n”,“DAD3”);
printf(“%f\n”,DAD3[i]);
fprintf(fp5,“%f\n”,DAD3[i]);
//}
//else
//{
//printf(“%f\n”,DAD3[i]);
//fprintf(fp5,“%f\n”,DAD3[i]);
//}
}
for(i=0;i《add3;i++)
{//if(i==0)
printf(“%s\n”,“ADD3”);
printf(“%f\n”,ADD3[i]);
fprintf(fp6,“%f\n”,ADD3[i]);
//}
//else
//{
//printf(“%f\n”,ADD3[i]);
//fprintf(fp6,“%f\n”,ADD3[i]);
//}
//
}
for(i=0;i《ddd3;i++)
{//if(i==0)
printf(“%s\n”,“DDD3”);
printf(“%f\n”,DDD3[i]);
fprintf(fp7,“%f\n”,DDD3[i]);
//}
//else
//{
//printf(“%f\n”,DDD3[i]);
//fprintf(fp7,“%f\n”,DDD3[i]);
//}
}
//關閉文件
fclose(fp);
fclose(fp0);
fclose(fp1);
fclose(fp2);
fclose(fp3);
fclose(fp4);
fclose(fp5);
fclose(fp6);
fclose(fp7);
}
/*runthisprogramusingtheconsolepauseroraddyourowngetch,system(“pause”)orinputloop*/
/*嘗試不對
doubleA1[(LENGTH+DB_LENGTH)/2];
doubleD1[(LENGTH+DB_LENGTH)/2];
inta1=(LENGTH+DB_LENGTH)/2;
intd1=(LENGTH+DB_LENGTH)/2;
doubleAA2[(LENGTH+DB_LENGTH)/4];
doubleDA2[(LENGTH+DB_LENGTH)/4];
inta2=(LENGTH+DB_LENGTH)/4;
intd2=(LENGTH+DB_LENGTH)/4;
doubleAAA3[(LENGTH+DB_LENGTH)/8];
doubleDAA3[(LENGTH+DB_LENGTH)/8];
inta3=(LENGTH+DB_LENGTH)/8;
intd3=(LENGTH+DB_LENGTH)/8;
doubleAAAA4[(LENGTH+DB_LENGTH)/16];
doubleDAAA4[(LENGTH+DB_LENGTH)/16];
Covlution(input,h,temp,n,m);
for(i=0;i《n+m-2;i+=2)
{
A1[i/2]=temp[i];//一層分解的低頻部分,進行了2抽值,即尺度空間,低頻概貌部分
}
Covlution(input,g,temp,n,m);
for(i=0;i《n+m-2;i+=2)
{
D1[i/2]=temp[i];//一層分解的高頻部分,已經進行了2抽取,即高頻細節部分
}
Covlution(A1,h,temp,a1,m);
for(i=0;i《a1+m-2;i+=2)
{
AA2[i/2]=temp[i];//一層分解的低頻部分,進行了2抽值,即尺度空間,低頻概貌部分
}
Covlution(A1,g,temp,a1,m);
for(i=0;i《a1+m-2;i+=2)
{
DA2[i/2]=temp[i];//一層分解的低頻部分,進行了2抽值,即尺度空間,低頻概貌部分
}
Covlution(AA2,h,temp,a2,m);
for(i=0;i《a2+m-2;i+=2)
{
AAA3[i/2]=temp[i];//一層分解的低頻部分,進行了2抽值,即尺度空間,低頻概貌部分
}
Covlution(AA2,g,temp,a2,m);
for(i=0;i《a2+m-2;i+=2)
{
DAA3[i/2]=temp[i];//一層分解的低頻部分,進行了2抽值,即尺度空間,低頻概貌部分
}
Covlution(AAA3,h,temp,a3,m);
for(i=0;i《a3+m-2;i+=2)
{
AAAA4[i/2]=temp[i];//一層分解的低頻部分,進行了2抽值,即尺度空間,低頻概貌部分
}
Covlution(AAA3,g,temp,a3,m);
for(i=0;i《a3+m-2;i+=2)
{
DAAA4[i/2]=temp[i];//一層分解的低頻部分,進行了2抽值,即尺度空間,低頻概貌部分
}
for(i=0;i《4116;i++)
{
if(i《=259)
output[i]=AAAA4[i];
elseif(i《=519)
output[i]=DAAA4[i-260];
elseif(i《=1035)
output[i]=DAA3[i-520];
elseif(i《=2064)
output[i]=DA2[i-1036];
else
output[i]=DA2[i-2065];
}
*/
評論