参考《Visual C++数字图像处理典型算法及实现 》中的源代码,按照matlab中的程序做了修改,并用matlab进行了分解及重构的验证。
局限性:该算法仅对输入数据长度为2的指数的情况有效。 int Log2(int x) {//求最大可分解尺度,不要随便用math.h中的函数,因为各种重载过于复杂,极可能出错 int k=1; while((1<<k)<=x) k++; k--; return k; } BOOL DWTStep_1D(double* data,int nCurLevel,int nInv,int nStep,int nSupp) { //double s=sqrt((double)2); //获得小波基的指针 double* h=(double*)hCoef[nSupp-1];//系数为Lo_R ASSERT(nCurLevel>=0); //计算当前层数的长度 int CurN=1<<nCurLevel; if(nInv) CurN<<=1; if(nSupp<1||nSupp>10||CurN<2*nSupp) return FALSE; //分配内存存放结果 double* ptemp=new double[CurN]; if(!ptemp) return FALSE; double s1,s2; int Index1,Index2; //判断是进行DWT还是进行IDWT if(!nInv) {//DWT //对称延拓 int ExtN=2*nSupp+CurN;//延拓后的长度 double* pdata=new double[ExtN]; for(int i=0;i<nSupp;i++) { pdata[i]=data[nSupp-1-i]; pdata[ExtN-nSupp+i]=data[CurN-1-i]; } for(int i=nSupp;i<ExtN-nSupp;i++) pdata[i]=data[i-nSupp]; //分解及系数提取 Index1=0; Index2=2*nSupp-1; for(int i=0;i<CurN/2;i++) { s1=s2=0; double t=-1; for(int j=0;j<2*nSupp;j++,t=-t) { s1+=h[j]*pdata[(Index1)*nStep]; s2+=t*h[j]*pdata[(Index2)*nStep]; Index1++; Index2--; } ptemp[i]=s1; ptemp[i+CurN/2]=s2; Index1-=2*nSupp; Index2+=2*nSupp; Index1+=2;//downsample,隔一个采样一次 Index2+=2; } delete[] pdata; } else {//IDWT //卷积零延拓 double* pdatal=new double[nSupp+CurN/2+1]; double* pdatah=new double[nSupp+CurN/2+1]; int bn=nSupp/2; for(int i=0;i<bn;i++) {//零延拓数据前端 pdatal[i]=0; pdatah[i]=0; } for(int i=CurN/2+bn;i<nSupp+CurN/2+1;i++) {//零延拓数据后端 pdatal[i]=0; pdatah[i]=0; } for(int i=0;i<CurN/2;i++) {//拷贝中间数据 pdatal[bn+i]=data[i]; pdatah[bn+i]=data[CurN/2+i]; } //重构并提取系数 Index1=nSupp;//逆序乘积(正序卷积) for(int i=0;i<CurN/2;i++) { s1=s2=0; int Index3=0; int Index4=2*nSupp-2; if(nSupp%2==0) { for(int j=0;j<nSupp;j++) { s1+=h[Index3]*pdatal[Index1*nStep]+h[Index4+1]*pdatah[Index1*nStep]; s2+=h[Index3+1]*pdatal[Index1*nStep]-h[Index4]*pdatah[Index1*nStep]; Index3+=2; Index4-=2; Index1--; } ptemp[2*i]=s1; ptemp[2*i+1]=s2; } if(nSupp%2==1) { for(int j=0;j<nSupp;j++) { s1+=h[Index3]*pdatal[Index1*nStep]+h[Index4+1]*pdatah[Index1*nStep]; s2+=h[Index3+1]*pdatal[(Index1-1)*nStep]-h[Index4]*pdatah[(Index1-1)*nStep]; Index3+=2; Index4-=2; Index1--; } ptemp[2*i]=s2; ptemp[2*i+1]=s1; } Index1+=nSupp; Index1++; } delete[] pdatal; delete[] pdatah; } for(int i=0;i<CurN;i++) data[i*nStep]=ptemp[i]; //删除分配的临时内存 delete[] ptemp; return TRUE; } BOOL DWT_1D(double* data,int nMaxLevel,int nDWTSteps,int nInv,int nStep,int nSupp) { //计算最小可分解的层数 int MinLevel=nMaxLevel-nDWTSteps; //判断是否为DWT if(!nInv) {//DWT int n=nMaxLevel; while(n>MinLevel) if(!DWTStep_1D(data,n--,nInv,nStep,nSupp)) return FALSE; } else {//IDWT int n=MinLevel; while(n<nMaxLevel) if(!DWTStep_1D(data,n++,nInv,nStep,nSupp)) return FALSE; } return TRUE; }
本文来源:http://blog.csdn.net/antheazhang/archive/2007/08/24/1757428.aspx
|