/************************************************************
离散小波变化函数
*************************************************************/
/************************************************************
参数说明:
g —— 双精度实型一维数组,长度为wlen。尺度系数。
h —— 双精度实型一维数组,长度为wlen。小波系数。
wlen —— 整形变量。小波长度。
c —— 双精度实型一维数组。
d —— 与c相同。
m —— 整形变量。小波分解的级数目。
sca —— 双精度实型一维数组,长度为(m+1)。存放小波分解时每级的
数据长度,sca[0]是原信号的长度,sca[i]是小波分解时第i
级的数据长度。
*************************************************************/
void dwt(g,h,wlen,c,d,m,sca)
int m,wden,sca[];
double c[],d[],g[],h[];
{
int i,j,k,mid,flag[20];
double p,q;
for(flag[0]=0,i=0;i=sca[j-1])
mid = mid - sca[j-1];
p = p + h[k]*c[flag[j-1]+mid];
q = q + g[k]*c[flag[j-1]+mid];
}
c[flag[j] + i] = p;
d[flag[j] + i] = q;
}
}
Re:【求助】谁可以提供C语言编写的DB8小波变换程序???
#include <stdio.h>
#include <stdlib.h>
#include<math.h>
#include<malloc.h>
#include <memory.h>
#include <string.h>
#define DIM 1024
int I_m ,I_n,i;
#define pi 3.14159265359
//double D4[]={0.482962913145, 0.836516303738, 0.224143868042, -0.129409522551 };
//double D6[]={0.332670552950, 0.806891509311, 0.459877502118, -0.135011020010, -0.085441273882, 0.035226291882 };
double D8[]={ 0.230377813309, 0.714846570553, 0.630880767930, -0.027983769417,
-0.187034811719, 0.030841381836, 0.032883011667, -0.010597401785 };
//////////////////////////////////////////////////////////////////
int getmax(unsigned char**image_in);
int getmin(unsigned char**image_in);
void chartodouble(unsigned char **image_in,double **double_in);
void doubletochar(double **int_in,unsigned char **image_in);
void daubechies8hl(double **double_in,double **double_out);
void id8h(double **double_in,double **double_out);
void id8l(double **double_in,double **double_out);
void redaubechies8hl(double **double_in,double **double_out);
////////////////////////////////////////////////////////////////
void main()
{
FILE *fr;
FILE *fw;
int j=0;
int max,min=0;
char topc[20];
unsigned char **image_in,**image_out;
double **double_in,**double_out;
fr=fopen("test.pgm","rb");
///////////////////////////////////////////////////////////
//begin to read file
fscanf(fr,"%s\n",topc);
fscanf(fr,"%d %d\n",&I_n,&I_m);
fscanf(fr,"%d",&i);
printf("input%s\n",topc);
printf("input %d,%d,%d\n",I_m,I_n,i);
//动态分配保存输出文件空间
image_in=(unsigned char **)calloc(I_m,sizeof(unsigned char *));
for(i=0;i<I_m;i++)
image_in=(unsigned char *)calloc(I_n,sizeof(unsigned char));
image_out=(unsigned char **)calloc(I_m,sizeof(unsigned char *));
for(i=0;i<I_m;i++)
image_out=(unsigned char *)calloc(I_n,sizeof(unsigned char));
//动态分配空间
double_in=(double **)calloc(I_m,sizeof(double *));
for(i=0;i<I_m;i++)
double_in=(double *)calloc(I_n,sizeof(double));
double_out=(double **)calloc(I_m,sizeof(double *));
for(i=0;i<I_m;i++)
double_out=(double *)calloc(I_n,sizeof(double));
//get gray(char) fill image_in
for(i=0;i<I_m;i++)
fread(image_in,sizeof(unsigned char)*1,I_n,fr);
fclose(fr);
///////////////////////////////////////////////////////////////////////
max=getmax(image_in);
min=getmin(image_in);
chartodouble(image_in,double_in);
daubechies8hl(double_in,double_out);
//redaubechies8hl(double_in,double_out);
doubletochar(double_out,image_out);
/////////////////////////////////////////////////////////////////////////////
// write file header
fw= fopen("out4.pgm","wb");
fprintf(fw,"%s\n",topc);
fprintf(fw,"%d %d\n",I_n,I_m);
fprintf(fw,"%d\n",255);
// write file data
for(j=0;j<I_m;j++)
fwrite(image_out[j],1,sizeof(unsigned char)*I_n,fw);
fclose(fw);
///////////////////////////////////////////////////////////////////////
free(image_in);
free(image_out);
free(double_in);
free(double_out);
printf("\nprocess end \n");
getchar();
}
////////////////////////////////////////////////////////////////////
int getmax(unsigned char**image_in)
{
int i,j,p;
p=(int)image_in[0][0];
for(i=0;i<I_m;i++)
for(j=0;j<I_n;j++)
{
if(p<(int)image_in[j])
p=(int)image_in[j];
}
printf("max is:%d\n",p);
return p;
}
int getmin(unsigned char**image_in)
{
int i,j,p;
p=(int)image_in[0][0];
for(i=0;i<I_m;i++)
for(j=0;j<I_n;j++)
{
if(p>(int)image_in[j])
p=(int)image_in[j];
}
printf("min is:%d\n",p);
return p;
}
void smooth2(unsigned char **image_in,unsigned char **image_out)
{
int i,j;
for(i=0;i<I_m;i++)
for(j=0;j<I_n;j++)
image_out[j]=image_in[j];
}
/////////////////////////////////////////////////////
void chartodouble(unsigned char **image_in,double **double_in)
{
int i,j;
for(i=0;i<I_m;i++)
for(j=0;j<I_n;j++)
double_in[j]=(double)image_in[j];
}
void doubletochar(double **double_out,unsigned char **image_out)
{
int i,j;
for(i=0;i<I_m;i++)
for(j=0;j<I_n;j++)
{
if(double_out[j]>0)
image_out[j]=(unsigned char)double_out[j];
else
//简单设为0
image_out[j]=0;
}
}
/////////////////////////////////////////////////////////////////
void daubechies8hl(double **double_in, double **double_out)
{
int i,j,k=0;
//int p=0,q=0;
double s = sqrt(2);
doubles1=0, s2=0;
intnStep=1;//步长为1 当前层为1
int CurN=256;//每行有256个离散点
int nSupp=4;//D8小波的支撑 8=2*4
intIndex1=0, Index2=0;
double* h = D8;
double *ptemp = new double[256];
double *pDbSrc=new double[256];
for(i=0;i<I_m;i++)
{
for(j=0;j<I_n;j++)
{
pDbSrc[j]=double_in[j];
}
///*
//开始进行行变换
Index1=0;
Index2=2*nSupp-1;
// 进行卷积,其中s1为低频部分,s2为高频部分的结果
for (int jj=0; jj<CurN/2; jj++)
{
s1 = s2 = 0;
double t = -1;
for (k=0; k<2*nSupp; k++, t=-t)
{
s1 += h[k]*pDbSrc[(Index1 & CurN-1) * nStep];
s2 += t*h[k]*pDbSrc[(Index2 & CurN-1) * nStep];
Index1++;
Index2--;
}
// 将结果存放在临时内存中
ptemp[jj] = s1/s;
ptemp[jj+CurN/2] = s2/s;
Index1 -= 2*nSupp;
Index2 += 2*nSupp;
Index1 += 2;
Index2 += 2;
}
/*
当开始的时候jj=0 Index1=0 Index2=5;
然后是jj=1 Index1=2 Index2=7;
然后是jj=2 Index1=4 Index2=9;
...
然后是jj=125 Index1=250 Index2=255;
然后是jj=126 Index1=252 Index2=257;257&255=1 256&255=0
然后是jj=127 Index1=254 Index2=259;259&255=3 258&255=2
然后是jj=128 跳出循环
*/
// 将临时数组ptemp存入图象的一行中
for (int ji=0; ji<CurN; ji++)
{
pDbSrc[ji*nStep] = ptemp[ji];
}
//*/
// 将结果存入输出图象的一行中
for(j=0;j<I_n;j++)
{
double_out[j]=pDbSrc[j];
}
}
////////////////////////////////////////////////////////////////////
//这个时候的行变换已经完成
// 开始进行列变换了,为了便于理解 先把数组保存一下
for(i=0;i<I_m;i++)
for(j=0;j<I_n;j++)
{
double_in[j]=double_out[j];
}
////////////////////////////////////////////////////////////////////
// 然后开始列变换
for(j=0;j<I_n;j++)
{
for(i=0;i<I_m;i++)
{
pDbSrc=double_in[j];
}
///*
//开始进行列变换
Index1=0;
Index2=2*nSupp-1;
// 进行卷积jj,其中s1为低频部分,s2为高频部分的结果
for (int jj=0; jj<CurN/2; jj++)
{
s1 = s2 = 0;
double t = -1;
for (k=0; k<2*nSupp; k++, t=-t)
{
s1 += h[k]*pDbSrc[(Index1 & CurN-1) * nStep];
s2 += t*h[k]*pDbSrc[(Index2 & CurN-1) * nStep];
Index1++;
Index2--;
}
// 将结果存放在临时内存中
ptemp[jj] = s1/s;
ptemp[jj+CurN/2] = s2/s;
Index1 -= 2*nSupp;
Index2 += 2*nSupp;
Index1 += 2;
Index2 += 2;
}
/*
当开始的时候jj=0 Index1=0 Index2=5;
然后是jj=1 Index1=2 Index2=7;
然后是jj=2 Index1=4 Index2=9;
...
然后是jj=125 Index1=250 Index2=255;
然后是jj=126 Index1=252 Index2=257;257&255=1 256&255=0
然后是jj=127 Index1=254 Index2=257;259&255=3 258&255=2
然后是jj=128 跳出循环
*/
// 将临时结果存入图象的一列中
for (int ji=0; ji<CurN; ji++)
{
pDbSrc[ji*nStep] = ptemp[ji];
}
//*/
//将结果保存到输出图象的一列中
for(i=0;i<I_m;i++)
{
double_out[j]=pDbSrc;
}
}
delete[] pDbSrc;
delete[] ptemp;
return;
}
////################################################################
////###############################################################
void id8l(double **double_in, double **double_out)
{
int i,j,k=0;
double s = sqrt(2);
doubles1=0, s2=0;
intnStep=1;//步长为1 当前层为1
int CurN=256;//每行有256个离散点
int nSupp=4;//D8小波的支撑 8=2*4
intIndex1=0, Index2=0,Index3=0;
double* h = D8;
double *ptemp = new double[256];
double *pDbSrc=new double[256];
for(j=0;j<I_n;j++)
{
for(i=0;i<I_m;i++)
{
pDbSrc=double_in[j];
}
///*
//开始进行列小波反变换
Index1 = CurN/2;
Index2 = CurN/2-nSupp+1;
// 进行卷积jj,其中s1为低频部分,s2为高频部分的结果
for (int jj=0; jj<CurN/2; jj++)
{
s1 = s2 = 0;
Index3=0;
for (k=0; k<nSupp; k++)
{
s1 += h[Index3]*pDbSrc[(Index1 & CurN/2-1) * nStep]
+h[Index3+1]*pDbSrc[((Index2 & CurN/2-1) + CurN/2) * nStep];
s2 += h[Index3+1]*pDbSrc[(Index1 & CurN/2-1) * nStep]
-h[Index3]*pDbSrc[((Index2 & CurN/2-1) + CurN/2) * nStep];
Index3+=2;
Index1--;
Index2++;
}
// 将结果存放在临时内存中
ptemp[2*jj] = s1*s;
ptemp[2*jj+1] = s2*s;
Index1 += nSupp;
Index2 -= nSupp;
Index1++;
Index2++;
}
// 将临时结果存入图象一列数组中
for (int ji=0; ji<CurN; ji++)
{
pDbSrc[ji*nStep] = ptemp[ji];
}
//*/
//将一列的结果放到输出数组中
for(i=0;i<I_m;i++)
{
double_out[j]=pDbSrc;
}
}
delete[] pDbSrc;
delete[] ptemp;
return;
}
////###############################################################
void id8h(double **double_in, double **double_out)
{
int i,j,k=0;
double s = sqrt(2);
doubles1=0, s2=0;
intnStep=1;//步长为1 当前层为1
int CurN=256;//每行有256个离散点
int nSupp=4;//D8小波的支撑 8=2*4
intIndex1=0, Index2=0,Index3=0;
double* h = D8;
double *ptemp = new double[256];
double *pDbSrc=new double[256];
for(i=0;i<I_m;i++)
{
for(j=0;j<I_n;j++)
{
pDbSrc[j]=double_in[j];
}
///*
//开始进行h行小波反变换
Index1 = CurN/2; //128
Index2 = CurN/2-nSupp+1; //128-3+1=126
// 进行卷积jj,其中s1为低频部分,s2为高频部分的结果
for (int jj=0; jj<CurN/2; jj++)
{
s1 = s2 = 0;
Index3=0;
for (k=0; k<nSupp; k++)
{
s1 += h[Index3]*pDbSrc[(Index1 & CurN/2-1) * nStep]
+h[Index3+1]*pDbSrc[((Index2 & CurN/2-1) + CurN/2) * nStep];
//126&(128-1)=126 126&127=126
s2 += h[Index3+1]*pDbSrc[(Index1 & CurN/2-1) * nStep]
-h[Index3]*pDbSrc[((Index2 & CurN/2-1) + CurN/2) * nStep];
Index3+=2;
Index1--;
Index2++;
}
// 将结果存放在临时内存中
ptemp[2*jj] = s1*s;
ptemp[2*jj+1] = s2*s;
Index1 += nSupp;
Index2 -= nSupp;
Index1++;
Index2++;
}
// 将结果存入源图象中
for (int ji=0; ji<CurN; ji++)
{
pDbSrc[ji*nStep] = ptemp[ji];
}
//*/
for(j=0;j<I_n;j++)
{
double_out[j]=pDbSrc[j];
}
}
delete[] pDbSrc;
delete[] ptemp;
return;
}
////////////////////////////////////////////////////////////
void redaubechies8hl(double **double_in, double **double_out)
{
int i,j,k=0;
//int p=0,q=0;
double s = sqrt(2);
doubles1=0, s2=0;
intnStep=1;//步长为1 当前层为1
int CurN=256;//每行有256个离散点
int nSupp=4;//D8小波的支撑 8=2*4
intIndex1=0, Index2=0,Index3=0;
double* h = D8;
double *ptemp = new double[256];
double *pDbSrc=new double[256];
for(i=0;i<I_m;i++)
{
for(j=0;j<I_n;j++)
{
pDbSrc[j]=double_in[j];
}
///*
//开始进行行变换
Index1=0;
Index2=2*nSupp-1;
// 进行卷积,其中s1为低频部分,s2为高频部分的结果
for (int jj=0; jj<CurN/2; jj++)
{
s1 = s2 = 0;
double t = -1;
for (k=0; k<2*nSupp; k++, t=-t)
{
s1 += h[k]*pDbSrc[(Index1 & CurN-1) * nStep];
s2 += t*h[k]*pDbSrc[(Index2 & CurN-1) * nStep];
Index1++;
Index2--;
}
// 将结果存放在临时内存中
ptemp[jj] = s1/s;
ptemp[jj+CurN/2] = s2/s;
Index1 -= 2*nSupp;
Index2 += 2*nSupp;
Index1 += 2;
Index2 += 2;
}
// 将临时数组ptemp存入图象的一行中
for (int ji=0; ji<CurN; ji++)
{
pDbSrc[ji*nStep] = ptemp[ji];
}
//*/
// 将结果存入输出图象的一行中
for(j=0;j<I_n;j++)
{
double_out[j]=pDbSrc[j];
}
}
////////////////////////////////////////////////////////////////////
//这个时候的行变换已经完成
// 开始进行列变换了,为了便于理解 先把数组保存一下
for(i=0;i<I_m;i++)
for(j=0;j<I_n;j++)
{
double_in[j]=double_out[j];
}
////////////////////////////////////////////////////////////////////
// 然后开始列变换
for(j=0;j<I_n;j++)
{
for(i=0;i<I_m;i++)
{
pDbSrc=double_in[j];
}
///*
//开始进行列变换
Index1=0;
Index2=2*nSupp-1;
// 进行卷积jj,其中s1为低频部分,s2为高频部分的结果
for (int jj=0; jj<CurN/2; jj++)
{
s1 = s2 = 0;
double t = -1;
for (k=0; k<2*nSupp; k++, t=-t)
{
s1 += h[k]*pDbSrc[(Index1 & CurN-1) * nStep];
s2 += t*h[k]*pDbSrc[(Index2 & CurN-1) * nStep];
Index1++;
Index2--;
}
// 将结果存放在临时内存中
ptemp[jj] = s1/s;
ptemp[jj+CurN/2] = s2/s;
Index1 -= 2*nSupp;
Index2 += 2*nSupp;
Index1 += 2;
Index2 += 2;
}
/*
当开始的时候jj=0 Index1=0 Index2=5;
然后是jj=1 Index1=2 Index2=7;
然后是jj=2 Index1=4 Index2=9;
...
然后是jj=125 Index1=250 Index2=255;
然后是jj=126 Index1=252 Index2=257;257&255=1 256&255=0
然后是jj=127 Index1=254 Index2=257;259&255=3 258&255=2
然后是jj=128 跳出循环
*/
// 将临时结果存入图象的一列中
for (int ji=0; ji<CurN; ji++)
{
pDbSrc[ji*nStep] = ptemp[ji];
}
//*/
//将结果保存到输出图象的一列中
for(i=0;i<I_m;i++)
{
double_out[j]=pDbSrc;
}
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
//这个时候正变换完成
//开始进行反变换
//先可以进行反列变换或者行的反变换
id8l(double_out,double_in);
id8h(double_in,double_out);
//id6hl(double_in,double_out);
delete[] pDbSrc;
delete[] ptemp;
return;
}
不知道适合不适合你需要咯
不过程序是很好理解的.