这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » FPGA » 图像的小波变换

共5条 1/1 1 跳转至

图像的小波变换

专家
2013-01-21 21:19:05     打赏

/************************************************************
                      离散小波变化函数
*************************************************************/
 
/************************************************************
参数说明:
 
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;
   

   
}
不知道适合不适合你需要咯
不过程序是很好理解的.




关键词: 图像     小波     变换     数组     double     unsign    

专家
2013-01-22 15:14:29     打赏
2楼

看来做图像处理的人不多啊!


高工
2013-01-24 21:20:30     打赏
3楼
好长的C代码,据我所知,小波变换应用非常之广泛啊,较傅里叶变幻而已,可以改变频域的分辨率,具有细节分析的“低通”效果

专家
2013-01-24 22:38:39     打赏
4楼
这个代码算是比较短的了!!

工程师
2013-01-25 22:22:57     打赏
5楼
厉害!!!

共5条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]