小波变换和零树编码c++实现.txt

该博客介绍了一种离散小波变换(DWT)算法的实现细节,包括了算法的主要步骤、关键参数设置以及与图像处理相关的应用。通过对不同层级的小波系数进行分解与重构,实现了图像的多分辨率分析。

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

DWT.h  
   
  #if   !defined(AFX_DWT_H__C2E4CEAE_A0CC_4C62_85A0_41C34344E2E0__INCLUDED_)  
  #define   AFX_DWT_H__C2E4CEAE_A0CC_4C62_85A0_41C34344E2E0__INCLUDED_  
   
  #if   _MSC_VER   >   1000  
  #pragma   once  
  #endif   //   _MSC_VER   >   1000  
  #include   "Dib.h"  
   
  const   float   hCoef[10][20]   =  
  {  
  {   .707106781187f,     .707106781187f},  
   
  {   .482962913145f,     .836516303738f,     .224143868042f,   -.129409522551f   },  
   
  {   .332670552950f,     .806891509311f,     .459877502118f,   -.135011020010f,   -.085441273882f,     .035226291882f   },  
   
  {   .230377813309f,     .714846570553f,     .630880767930f,   -.027983769417f,  
    -.187034811719f,     .030841381836f,     .032883011667f,   -.010597401785f   },  
   
  {   .160102397974f,     .603829269797f,     .724308528438f,     .138428145901f,   -.242294887066f,  
    -.032244869585f,     .077571493840f,   -.006241490213f,   -.012580751999f,     .003335725285f   },  
   
  {   .111540743350f,     .494623890398f,     .751133908021f,     .315250351709f,   -.226264693965f,  
    -.129766867567f,     .097501605587f,     .027522865530f,   -.031582039318f,     .000553842201f,  
      .004777257511f,   -.001077301085f   },  
   
  {   .077852054085f,     .396539319482f,     .729132090846f,     .469782287405f,   -.143906003929f,  
    -.224036184994f,     .071309219267f,     .080612609151f,   -.038029936935f,   -.016574541631f,  
      .012550998556f,     .000429577973f,   -.001801640704f,     .000353713800f   },  
   
  {   .054415842243f,     .312871590914f,     .675630736297f,     .585354683654f,   -.015829105256f,  
    -.284015542962f,     .000472484574f,     .128747426620f,   -.017369301002f,   -.044088253931f,  
      .013981027917f,     .008746094047f,   -.004870352993f,   -.000391740373f,     .000675449406f,  
    -.000117476784f   },  
   
  {   .038077947364f,     .243834674613f,     .604823123690f,     .657288078051f,     .133197385825f,  
    -.293273783279f,   -.096840783223f,     .148540749338f,     .030725681479f,   -.067632829061f,  
      .000250947115f,     .022361662124f,   -.004723204758f,   -.004281503682f,     .001847646883f,  
      .000230385764f,   -.000251963189f,     .000039347320f   },  
   
  {   .026670057901f,     .188176800078f,     .527201188932f,     .688459039454f,     .281172343661f,  
    -.249846424327f,   -.195946274377f,     .127369340336f,     .093057364604f,   -.071394147166f,  
    -.029457536822f,     .033212674059f,     .003606553567f,   -.010733175483f,     .001395351747f,  
      .001992405295f,   -.000685856695f,   -.000116466855f,     .000093588670f,   -.000013264203f   }  
  };  
   
  class   CDWT      
  {  
  public:  
  void   SetPara(int   Supp,   BOOL   bOptimize);  
  BOOL   CanDWT(int   Inv);  
  BOOL   DibDWTStep   (   int   Inv   );  
  CDWT();  
  virtual   ~CDWT();  
  int InitDWT   (   CDib*   pDib   );  
  private:  
  CDib *m_pDib;  
  int m_iHeight,   m_iWidth;  
  int m_iMaxWLevel,   m_iMaxHLevel,   m_iMaxLevel;  
  int m_iSupp,   m_iByte;  
  BOOL m_bOptimize;  
  public:    
  int   m_iCurDepth;  
  float *m_pfBuf;  
   
  protected:  
  BOOL   DWTStep_1D   (float   *pfBuf,   int   CurLevel,   int   Inv=0,   int   Step=1);  
  BOOL   DWTStep_2D(int   Inv,   int   Step);  
  inline   int   Log2   (int   n);  
  inline   char   FloatToChar(float   f);  
  inline   BYTE   FloatToByte(float   f);  
  };  
   
  #endif   //   !defined(AFX_DWT_H__C2E4CEAE_A0CC_4C62_85A0_41C34344E2E0__INCLUDED_)

 

 

 DWT.cpp  
   
   
  //   DWT.cpp:   implementation   of   the   CDWT   class.  
  //  
  //////////////////////////////////////////////////////////////////////  
   
  #include   "stdafx.h"  
  #include   "DWT.h"  
  #include   <math.h>  
   
  #ifdef   _DEBUG  
  #undef   THIS_FILE  
  static   char   THIS_FILE[]=__FILE__;  
  #define   new   DEBUG_NEW  
  #endif  
   
  //////////////////////////////////////////////////////////////////////  
  //   Construction/Destruction  
  //////////////////////////////////////////////////////////////////////  
   
  CDWT::CDWT()  
  {  
  m_pDib   =   NULL;  
  m_pfBuf   =   NULL;  
  m_iMaxLevel   =   0;  
  m_iCurDepth   =   0;  
  m_iSupp   =   1;  
  m_iByte   =   1;  
  m_bOptimize   =   FALSE;  
  }  
   
  CDWT::~CDWT()  
  {  
  if   (   m_pfBuf   )  
  delete   m_pfBuf;  
  }  
   
  CDWT::InitDWT   (   CDib   *pDib   )  
  {  
  m_pDib   =   pDib;  
  if   (   m_pfBuf   )  
  delete   m_pfBuf;  
  m_iWidth   =   m_pDib->Width();  
  m_iHeight   =   m_pDib->Height();  
  m_iMaxWLevel   =   Log2(m_iWidth);  
  m_iMaxHLevel   =   Log2(m_iHeight);  
  if   (   (   m_iWidth   !=   1<<m_iMaxWLevel   )   ||   (m_iHeight   !=   1<<m_iMaxHLevel)   )  
  return   FALSE;  
  m_iMaxLevel   =   __min(m_iMaxWLevel,   m_iMaxHLevel);  
  m_iByte   =   m_pDib->GetBitCount()/8;  
   
  return   TRUE;  
  }  
   
  BOOL   CDWT::DibDWTStep(int   Inv)  
  {  
  int   i,   j,   k;  
   
  int   BPL   =   m_pDib->GetLineSize();  
   
  BYTE *pBits;  
  float *pfBuf;  
   
  if   (   !m_pfBuf   )  
  {  
  m_pfBuf   =   new   float[m_iWidth*m_iHeight*m_iByte];  
  if   (   !m_pfBuf   )  
  return   FALSE;  
   
  pfBuf   =   m_pfBuf;  
  for   (   k   =   0;   k   <   m_iByte;   k++   )  
  {  
  pBits   =   m_pDib->GetBmBitsPtr()+m_iHeight*BPL;  
  for   (   j   =   0;   j   <   m_iHeight;   j++   )  
  {  
  pBits   -=   BPL;  
  for   (   i   =   0;   i   <   m_iWidth;   i++   )  
  pfBuf[i]   =   pBits[i*m_iByte+k];  
  pfBuf+=m_iWidth;  
  }  
  }  
  }  
   
  if   (!DWTStep_2D(Inv,   1))  
  return   FALSE;  
   
  if   (Inv)  
  m_iCurDepth--;  
  else  
  m_iCurDepth++;  
   
  int   lfw   =   m_iWidth>>m_iCurDepth,   lfh   =   m_iHeight>>m_iCurDepth;  
  pfBuf   =   m_pfBuf;  
  for   (   k   =   0;   k   <   m_iByte;   k++   )  
  {  
  pBits   =   m_pDib->GetBmBitsPtr()+m_iHeight*BPL;  
  for   (   j   =   0;   j   <   m_iHeight;   j++   )  
  {  
  pBits   -=   BPL;  
  for   (   i   =   0;   i   <   m_iWidth;   i++   )  
  {  
  if   (   (   j   <   lfh   )   &&   (   i   <   lfw   )   )  
  pBits[i*m_iByte+k]   =   FloatToByte(pfBuf[i]);  
  else  
  pBits[i*m_iByte+k]   =   (m_bOptimize)?BYTE(FloatToChar(pfBuf[i])   ^   0x80):  
  BYTE(FloatToChar(pfBuf[i]));  
  }  
  pfBuf+=m_iWidth;  
  }  
  }  
  return   TRUE;  
  }  
   
BOOL   CDWT::DWTStep_2D(int   Inv,   int   Step)  
  {  
  int   Width   =   1<<m_iMaxWLevel;  
  int Height   =   1<<m_iMaxHLevel;  
  int   CurWLevel   =   m_iMaxWLevel-m_iCurDepth;  
  int   CurHLevel   =   m_iMaxHLevel-m_iCurDepth;    
  int   CurW   =   1<<CurWLevel;  
  int   CurH   =   1<<CurHLevel;  
   
  if   (!Inv)  
  {  
  for   (   int   k   =   0;   k   <   m_iByte;   k++   )  
  for   (   int   i   =   0;   i   <   CurH;   i++   )  
  if   (!DWTStep_1D(m_pfBuf+k*Width*Height+(int)i*Width,   CurWLevel,   Inv,   Step))    
  return   FALSE;  
                                   
                  for   (   k   =   0;   k   <   m_iByte;   k++   )  
  for   (   int   i   =   0;   i   <   CurW;   i++   )  
  if   (!DWTStep_1D(m_pfBuf+k*Width*Height+i,   CurHLevel,   Inv,   Width))  
  return   FALSE;  
  }  
  else  
  {  
  CurW   <<=   1;  
  CurH   <<=   1;  
   
  for   (   int   k   =   0;   k   <   m_iByte;   k++   )  
  for   (   int   i   =   0;   i   <   CurW;   i++   )  
  if   (!DWTStep_1D(m_pfBuf+k*Width*Height+i,   CurHLevel,   Inv,   Width))    
  return   FALSE;  
   
  for   (   k   =   0;   k   <   m_iByte;   k++   )  
  for   (   int   i   =   0;   i   <   CurH;   i++   )  
  if   (!DWTStep_1D(m_pfBuf+k*Width*Height+(int)i*Width,   CurWLevel,   Inv,   Step))    
  return   FALSE;  
  }  
   
  return   TRUE;  
  }  
   
  BYTE   CDWT::FloatToByte(float   f)  
  {  
  return   (f<=0)?((BYTE)0):((f>=255)?(BYTE)255:(BYTE)(f+0.5));  
  }  
   
  char   CDWT::FloatToChar(float   f)  
  {  
  if   (f>=0)  
  return   (f>=127.0)?(char)127:(char)(f+0.5);  
  else  
  return   (f<=-128)?(char)-128:-(char)(-f+0.5);  
  }  
   
  int   CDWT::Log2(int   n)  
  {  
  int   result   =   0;  
  while   (n   >>=   1)   result++;  
  return   result;  
  }  
   
  BOOL   CDWT::DWTStep_1D(float   *pfBuf,   int   CurLevel,   int   Inv,   int   Step)  
  //pfBuf&Icirc;&ordf;&Ograve;&ordf;&acute;&brvbar;&Agrave;í&micro;&Auml;&Ecirc;&yacute;&frac34;&Yacute;&Ccedil;&oslash;&pound;&not;CurLevel&Icirc;&ordf;&Ograve;&Ntilde;&frac34;&shy;×&ouml;&Aacute;&Euml;&frac14;&cedil;&acute;&Icirc;&micro;&Auml;&Ograve;&raquo;&Icirc;&not;&ETH;&iexcl;&sup2;¨  
  //Inv±í&Ecirc;&frac34;&Ecirc;&Ccedil;&Otilde;&yacute;±&auml;&raquo;&raquo;&raquo;&sup1;&Ecirc;&Ccedil;&Auml;&aelig;±&auml;&raquo;&raquo;Step±í&Ecirc;&frac34;pfBuf&Ouml;&ETH;&Atilde;&iquest;&cedil;&ouml;&Ecirc;&yacute;&frac34;&Yacute;&micro;&Auml;&frac14;&auml;&cedil;&ocirc;  
  {  
  float   s   =   (float)   sqrt(2);  
          //s&Icirc;&ordf;&cedil;ù&ordm;&Aring;&Iuml;&Acirc;2  
  float*   h   =   (float*)   hCoef[m_iSupp-1];  
          //hCoef&Icirc;&ordf;&Agrave;&euml;&Eacute;&cent;&ETH;&iexcl;&sup2;¨&Iuml;&micro;&Ecirc;&yacute;  
   
  ASSERT(CurLevel>=0);  
          //&Ograve;&Ntilde;&frac34;&shy;×&ouml;&Aacute;&Euml;&frac14;&cedil;&acute;&Icirc;&ETH;&iexcl;&sup2;¨&pound;&not;&sup2;&raquo;&Auml;&Uuml;&Icirc;&ordf;&cedil;&ordm;&Ouml;&micro;  
  int   CurN   =   1<<CurLevel;  
          //   CurN   =   2&micro;&Auml;CurLevel&acute;&Icirc;·&frac12;&pound;&not;&Icirc;&ordf;&Ograve;&raquo;&cedil;&ouml;&para;&thorn;&frac12;&oslash;&Ouml;&AElig;1000000000   (&Egrave;&ocirc;&cedil;&Eacute;&Icirc;&raquo;&Icirc;&ordf;&Aacute;&atilde;&micro;&Auml;&para;&thorn;&frac12;&oslash;&Ouml;&AElig;&Ecirc;&yacute;)  
  int   iMask1   =   CurN   -   1,   iMask2   =   CurN/2   -   1;  
          //   iMask1   &Icirc;&ordf;&Ograve;&raquo;&cedil;&ouml;   111111111   (±&Egrave;&Eacute;&Iuml;&Atilde;&aelig;&micro;&Auml;&para;&thorn;&frac12;&oslash;&Ouml;&AElig;&Ecirc;&yacute;&Eacute;&Ugrave;&Ograve;&raquo;&Icirc;&raquo;&micro;&Auml;&Egrave;&laquo;&Ograve;&raquo;&Ecirc;&yacute;)  
          //   iMask2   &Icirc;&ordf;&Ograve;&raquo;&cedil;&ouml;   11111111     (&Ocirc;&Ugrave;±&Egrave;&Eacute;&Iuml;&Atilde;&aelig;&micro;&Auml;&Ecirc;&yacute;&Eacute;&Ugrave;&Ograve;&raquo;&Icirc;&raquo;&micro;&Auml;&Egrave;&laquo;&Ograve;&raquo;&Ecirc;&yacute;)  
   
  if   (Inv)   CurN   <<=   1;  
  if   (m_iSupp<1   ||   m_iSupp>10   ||   CurN<2*m_iSupp)   return   FALSE;  
   
  float   *ptemp   =   new   float[CurN];  
          //CurN   &acute;ú±í  
          //   &Otilde;&yacute;±&auml;&raquo;&raquo;   ±&Egrave;&Egrave;&ccedil;&Iuml;&Ouml;&Ecirc;&Ccedil;512&Iuml;ó&Euml;&Oslash;&pound;&not;&Ocirc;ò&Icirc;&ordf;512&Iuml;ó&Euml;&Oslash;  
          //   &Auml;&aelig;±&auml;&raquo;&raquo;   ±&Egrave;&Egrave;&ccedil;&Iuml;&Ouml;&Ecirc;&Ccedil;256&Iuml;ó&Euml;&Oslash;&pound;&not;&Ocirc;ò&Icirc;&ordf;512&Iuml;ó&Euml;&Oslash;  
  if   (!ptemp)   return   FALSE;  
   
  float s1,   s2;  
  int Index1,   Index2;  
          //pfBuf&micro;&Auml;&Iuml;&Acirc;±ê  
   
          //&Iuml;&Acirc;&Atilde;&aelig;·&Ouml;±&eth;&Ograve;&Ocirc;&para;&Ocirc;1)   512&iexcl;&Aacute;512&micro;&Auml;&Iacute;&frac14;&Iuml;ó&Ograve;&Ocirc;&frac14;&auml;&cedil;&ocirc;&Icirc;&ordf;1×÷&micro;&Uacute;&Ograve;&raquo;&acute;&Icirc;&ETH;&iexcl;&sup2;¨±&auml;&raquo;&raquo;   width=512  
          //                         2)   256&iexcl;&Aacute;256&micro;&Auml;&Iacute;&frac14;&Iuml;ó&Ograve;&Ocirc;&frac14;&auml;&cedil;&ocirc;&Icirc;&ordf;3×÷&micro;&Uacute;&Ograve;&raquo;&acute;&Icirc;&ETH;&iexcl;&sup2;¨±&auml;&raquo;&raquo;   width=512  
   
  if   (!Inv)  
  { //   DWT  
  Index1   =   0,   Index2   =   2*m_iSupp-1;  
                  //     1)   index1=0,   index2=1  
                  //     2)   index1=0,   index2=5  
   
  for   (   int   i   =   0;   i   <   CurN/2;   i++   )  
                  //   1)CurN=512,   CurN/2=256  
                  //       i&acute;&Oacute;0&micro;&frac12;255  
                  //       ptemp[512]  
                  //   2)CurN=256,   CurN/2=128  
                  //       i&acute;&Oacute;0&micro;&frac12;127  
                  //       ptemp[256]  
  {  
  s1   =   s2   =   0;  
  float   t   =   -1;  
                          for   (   int   j   =   0;   j   <   2*m_iSupp;   j++,   t   =   -t   )  
  {//   1)   j&acute;&Oacute;0&micro;&frac12;1,   t&frac12;&raquo;&Igrave;&aelig;+1,-1  
                            //   2)   j&acute;&Oacute;0&micro;&frac12;5,   t&frac12;&raquo;&Igrave;&aelig;+1,-1  
  s1   +=   h[j]*pfBuf[(Index1   &   iMask1)   *   Step];  
                                  //   1)   s1=h[0]*pfBuf[0]   +   h[1]*pfBuf[512]  
   
                                  //   2)   s2=h[0]*pfBuf[512&iexcl;&Aacute;0]   +   h[1]*pfBuf[512&iexcl;&Aacute;1]   +    
                                  //               h[2]*pfBuf[512&iexcl;&Aacute;2]   +   h[3]*pfBuf[512&iexcl;&Aacute;3]   +  
                                  //               h[4]*pfBuf[512&iexcl;&Aacute;4]   +   h[5]*pfBuf[512&iexcl;&Aacute;5]  
   
  s2   +=   t*h[j]*pfBuf[(Index2   &   iMask1)   *   Step];  
                                  //   1)   s1=h[0]*pfBuf[512]   -   h[1]*pfBuf[0]  
                                   
                                  //   2)   s2=h[0]*pfBuf[512&iexcl;&Aacute;5]   -   h[1]*pfBuf[512&iexcl;&Aacute;4]   +    
                                  //               h[2]*pfBuf[512&iexcl;&Aacute;3]   -   h[3]*pfBuf[512&iexcl;&Aacute;2]   +  
                                  //               h[4]*pfBuf[512&iexcl;&Aacute;1]   -   h[5]*pfBuf[512&iexcl;&Aacute;0]  
  Index1++, Index2--;  
  }  
  ptemp[i]   =   s1/s;  
  ptemp[i+CurN/2]   =   s2/s;  
                          //   1)  
                          //   ptemp[0]   /   ptemp[256]  
                          //   ptemp[1]   /   ptemp[257]  
                          //   ptemp[2]   /   ptemp[258]  
                          //   ......  
                          //   ptemp[255]   /ptemp[511]  
                           
                          //   2)  
                          //   ptemp[0]   /   ptemp[128]  
                          //   ptemp[1]   /   ptemp[129]  
                          //   ptemp[2]   /   ptemp[130]  
                          //   ......  
                          //   ptemp[127]   /   ptemp[255]  
                           
  Index1   -=   2*m_iSupp;  
  Index2   +=2*m_iSupp;  
  Index1   +=   2;  
  Index2   +=   2;  
  }  
  }  
  else  
  {  
  Index1   =   CurN/2;  
  Index2   =   CurN/2-m_iSupp+1;  
  for   (   int   i   =   0;   i   <   CurN/2;   i++   )  
  {  
  s1   =   s2   =   0;  
  int   Index3   =   0;  
  for   (   int   j   =   0;   j   <   m_iSupp;   j++   )  
  {  
  s1   +=   h[Index3]*pfBuf[(Index1   &   CurN/2-1)   *   Step]  
    +h[Index3+1]*pfBuf[((Index2   &   CurN/2-1)   +   CurN/2)   *   Step];  
  s2   +=   h[Index3+1]*pfBuf[(Index1   &   CurN/2-1)   *   Step]  
    -h[Index3]*pfBuf[((Index2   &   CurN/2-1)   +   CurN/2)   *   Step];  
   
  Index3   +=   2;  
  Index1--;  
  Index2++;  
  }  
  ptemp[2*i]   =   s1*s;  
  ptemp[2*i+1]   =   s2*s;  
   
  Index1   +=   m_iSupp;  
  Index2   -=   m_iSupp;  
  Index1++;  
  Index2++;  
  }  
  }  
   
  for   (   int   i   =   0;   i   <   CurN;   i++   )  
  pfBuf[i*Step]   =   ptemp[i];  
          //&frac12;&laquo;±&auml;&raquo;&raquo;&Ouml;&reg;&ordm;ó&micro;&Auml;&Ecirc;&yacute;×é&Igrave;&aelig;&raquo;&raquo;&Ocirc;&shy;&Agrave;&acute;&micro;&Auml;&Ecirc;&yacute;×é  
   
  delete[]   ptemp;  
  return   TRUE;  
  }  
   
  BOOL   CDWT::CanDWT(int   Inv)  
  {  
  if   (   Inv   )  
  return   (   m_iCurDepth   >   0   );  
  else  
  return   (   m_iCurDepth   <   m_iMaxLevel   );  
  }  
   
  void   CDWT::SetPara(int   Supp,   BOOL   bOptimize)  
  {  
  m_iSupp   =   Supp;  
  m_bOptimize   =   bOptimize;  
  }  

 


 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值