小波变换和恢复1(输入数组的形式)

抽样差值的小波变换和恢复(对一层小波效果好,多层小波恢复的效果较差)

#include <stdlib.h>
#include <cv.h>
#include <highgui.h>

// 二维离散小波变换(矩阵数组)
void DWT(float *pMatrix, int height, int width, int nLayer);
// 二维离散小波恢复(矩阵数组)
void IDWT(float *pMatrix, int height, int width, int nLayer);


int main()
{
       // 小波变换层数
       int nLayer = 1;
       // 输入彩色图像
       IplImage *pSrc = cvLoadImage("12.bmp", CV_LOAD_IMAGE_GRAYSCALE);
       //cvSaveImage("222.bmp",pSrc);
       // 计算小波图象大小
       int height = pSrc->height;
       int width = pSrc->width;
       // 创建小波图象
       cvNamedWindow("1",1);
       cvShowImage("1",pSrc);
       //cvWaitKey(0);
       IplImage *pWavelet = cvCreateImage(cvGetSize(pSrc), IPL_DEPTH_32F, 1);
       IplImage *image = cvCreateImage(cvGetSize(pSrc), IPL_DEPTH_8U, 1);
       if (pWavelet)
       {

#if 0   //分块小波变换 
       int nwidth = 8;
        float *pMatrix1 = new float[height*(nwidth+2)];
        for(int i = 0; i < height*(nwidth+2); i++)
        {
               pMatrix1[i] = 255.0f;
        }
        int time = (int)(width / nwidth);
        for(int n = 0; n < time; n++)
         {
               float *pMatrix2 = new float[height*2];
               int temp = 0;
               int temp1 = 0;
               for(int i = 0; i < height; i++)
               {
                      for(int j = n*nwidth; j < (n+1)*nwidth; j++)
                       {
                             pMatrix1[i*nwidth + j%nwidth] = 0.0;
                             temp1 = (unsigned char)(*(pSrc->imageData+i*pSrc->widthStep+j));
                             pMatrix1[i*nwidth + j%nwidth] = (float)(temp1);
                      }
               }
               for(int i = 0; i < height; i++)
               {
                      for(int j =(n+1)*nwidth-2; j < (n+1)*nwidth; j++)
                      {
                             pMatrix1[i*nwidth + j%nwidth] = 0.0;
                             temp1 = (unsigned char)(*(pSrc->imageData+i*pSrc->widthStep+j));
                             pMatrix1[i*nwidth + j%nwidth] = (float)(temp1);
                      }
               }

               {
                      // 二维离散小波变换
                      DWT(pMatrix1,height,nwidth, nLayer);
                      // 二维离散小波恢复
                      IDWT(pMatrix1,height,nwidth, nLayer);
               }

               for(int i = 0; i < height; i++)
               {
                      for(int j = n*nwidth; j < (n+1)*nwidth; j++)
                      {
                             temp = (int)(pMatrix1[i*nwidth + j%nwidth]);
                             *(image->imageData+i*image->widthStep+j) = (unsigned char)temp;
                      } 
               }
               delete pMatrix2;
        }
        delete pMatrix1;

#else  //整幅图的小波变换
        float *pMatrix = new float[height*width];
        int temp = 0;
        int temp1 = 0;
        for(int i = 0; i < height; i++)
        {
               for(int j = 0; j < width; j++)
               {
                      pMatrix[i*width + j] = 0.0;
                      temp1 = (unsigned char)(*(pSrc->imageData+i*pSrc->widthStep+j));
                      pMatrix[i*width + j] = (float)(temp1);
               }
        }

        {
                二维离散小波变换
               //DWT(pMatrix,height,width, nLayer);
                二维离散小波恢复
               //IDWT(pMatrix,height,width, nLayer);

               // 二维离散小波变换
               dwt(pMatrix,height,width, nLayer);
               // 二维离散小波恢复
               idwt(pMatrix,height,width, nLayer);
        }
  
         for(int i = 0; i < height; i++)
        {
               for(int j = 0; j < width; j++)
               {
                      temp = (int)(pMatrix[i*width + j]);
                      if(temp < 0)
                             temp = 0;
                      if(temp > 255)
                             temp = 255;
                      *(image->imageData+i*image->widthStep+j) = (unsigned char)temp;
               } 
        }
        delete pMatrix;
#endif
        cvNamedWindow("123",1);
        cvShowImage("123",image);
        cvWaitKey(0);
        cvReleaseImage(&pWavelet);

  
       }
       // 显示图像pSrc
       // ...
       cvReleaseImage(&pSrc);

       return 0;
}

// 二维离散小波变换(单通道浮点图像)
void DWT(float *pMatrix, int height, int width, int nLayer)
{
 int     i, x, y, n;
 float   fValue   = 0;
 float   fRadius  = sqrt(2.0f);
 int     nWidth   = width;
 int     nHeight  = height;
 int     nHalfW   = nWidth / 2;
 int     nHalfH   = nHeight / 2;
 float **pData    = new float*[height];
 float  *pRow     = new float[width];
 float  *pColumn  = new float[height];
 for (i = 0; i < height; i++)
 {
  pData[i] = &pMatrix[i*width];
 }
 // 多层小波变换
 for (n = 0; n < nLayer; n++, nWidth /= 2, nHeight /= 2, nHalfW /= 2, nHalfH /= 2)
 {
  // 水平变换
  for (y = 0; y < nHeight; y++)
  {
   // 奇偶分离
   memcpy(pRow, pData[y], sizeof(float) * nWidth);
   for (i = 0; i < nHalfW; i++)
   {
    x = i * 2;
    pData[y][i] = pRow[x];
    pData[y][nHalfW + i] = pRow[x + 1];
   }
   //差
   for (i = 0; i < nHalfW - 1; i++)
   {
    fValue = (pData[y][i] + pData[y][i + 1]) / 2;
    pData[y][nHalfW + i] -= fValue;
   }
   fValue = (pData[y][nHalfW - 1] + pData[y][nHalfW - 2]) / 2;
   pData[y][nWidth - 1] -= fValue;
   fValue = (pData[y][nHalfW] + pData[y][nHalfW + 1]) / 4;
   pData[y][0] += fValue;
   for (i = 1; i < nHalfW; i++)
   {
    fValue = (pData[y][nHalfW + i] + pData[y][nHalfW + i - 1]) / 4;
    pData[y][i] += fValue;
   }
   // 频带系数
   for (i = 0; i < nHalfW; i++)
   {
    pData[y][i] *= fRadius;
    pData[y][nHalfW + i] /= fRadius;
   }
  }
  // 垂直变换
  for (x = 0; x < nWidth; x++)
  {
   // 奇偶分离
   for (i = 0; i < nHalfH; i++)
   {
    y = i * 2;
    pColumn[i] = pData[y][x];
    pColumn[nHalfH + i] = pData[y + 1][x];
   }
   for (i = 0; i < nHeight; i++)
   {
    pData[i][x] = pColumn[i];
   }
   //差
   for (i = 0; i < nHalfH - 1; i++)
   {
    fValue = (pData[i][x] + pData[i + 1][x]) / 2;
    pData[nHalfH + i][x] -= fValue;
   }
   fValue = (pData[nHalfH - 1][x] + pData[nHalfH - 2][x]) / 2;
   pData[nHeight - 1][x] -= fValue;
   fValue = (pData[nHalfH][x] + pData[nHalfH + 1][x]) / 4;
   pData[0][x] += fValue;
   for (i = 1; i < nHalfH; i++)
   {
    fValue = (pData[nHalfH + i][x] + pData[nHalfH + i - 1][x]) / 4;
    pData[i][x] += fValue;
   }
   // 频带系数
   for (i = 0; i < nHalfH; i++)
   {
    pData[i][x] *= fRadius;
    pData[nHalfH + i][x] /= fRadius;
   }
  }
 }
 delete[] pData;
 delete[] pRow;
 delete[] pColumn;
}

// 二维离散小波恢复(单通道浮点图像)
void IDWT(float *pMatrix, int height, int width, int nLayer)
{
 int     i, x, y, n;
 float   fValue   = 0;
 float   fRadius  = sqrt(2.0f);
 int     nWidth   = width >> (nLayer - 1);
 int     nHeight  = height >> (nLayer - 1);
 int     nHalfW   = nWidth / 2;
 int     nHalfH   = nHeight / 2;
 float **pData    = new float*[height];
 float  *pRow     = new float[width];
 float  *pColumn  = new float[height];
 for (i = 0; i < height; i++)
 {
  pData[i] = &pMatrix[i*width];
 }
 // 多层小波恢复
 for (n = 0; n < nLayer; n++, nWidth *= 2, nHeight *= 2, nHalfW *= 2, nHalfH *= 2)
 {
  // 垂直恢复
  for (x = 0; x < nWidth; x++)
  {
   // 频带系数
   for (i = 0; i < nHalfH; i++)
   {
    pData[i][x] /= fRadius;
    pData[nHalfH + i][x] *= fRadius;
   }
   // 提升小波恢复
   fValue = (pData[nHalfH][x] + pData[nHalfH + 1][x]) / 4;
   pData[0][x] -= fValue;
   for (i = 1; i < nHalfH; i++)
   {
    fValue = (pData[nHalfH + i][x] + pData[nHalfH + i - 1][x]) / 4;
    pData[i][x] -= fValue;
   }
   for (i = 0; i < nHalfH - 1; i++)
   {
    fValue = (pData[i][x] + pData[i + 1][x]) / 2;
    pData[nHalfH + i][x] += fValue;
   }
   fValue = (pData[nHalfH - 1][x] + pData[nHalfH - 2][x]) / 2;
   pData[nHeight - 1][x] += fValue;
   // 奇偶合并
   for (i = 0; i < nHalfH; i++)
   {
    y = i * 2;
    pColumn[y] = pData[i][x];
    pColumn[y + 1] = pData[nHalfH + i][x];
   }
   for (i = 0; i < nHeight; i++)
   {
    pData[i][x] = pColumn[i];
   }
  }
  // 水平恢复
  for (y = 0; y < nHeight; y++)
  {
   // 频带系数
   for (i = 0; i < nHalfW; i++)
   {
    pData[y][i] /= fRadius;
    pData[y][nHalfW + i] *= fRadius;
   }
    //提升小波恢复
   fValue = (pData[y][nHalfW] + pData[y][nHalfW + 1]) / 4;
   pData[y][0] -= fValue;
   for (i = 1; i < nHalfW; i++)
   {
    fValue = (pData[y][nHalfW + i] + pData[y][nHalfW + i - 1]) / 4;
    pData[y][i] -= fValue;
   }
   for (i = 0; i < nHalfW - 1; i++)
   {
    fValue = (pData[y][i] + pData[y][i + 1]) / 2;
    pData[y][nHalfW + i] += fValue;
   }
   fValue = (pData[y][nHalfW - 1] + pData[y][nHalfW - 2]) / 2;
   pData[y][nWidth - 1] += fValue;
   // 奇偶合并
   for (i = 0; i < nHalfW; i++)
   {
    x = i * 2;
    pRow[x] = pData[y][i];
    pRow[x + 1] = pData[y][nHalfW + i];
   }
   memcpy(pData[y], pRow, sizeof(float) * nWidth);
  }
 }
 delete[] pData;
 delete[] pRow;
 delete[] pColumn;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值