基于对称延拓的小波变换算法的VC实现

本文介绍了一种基于VisualC++数字图像处理的小波变换算法,并使用Matlab进行了验证。该算法适用于输入数据长度为2的幂次方的情况,通过DWTStep_1D函数实现了信号的一维离散小波变换及其逆变换。

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

参考《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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值