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

均值和差值形式的小波变换和恢复,多层小波变换和恢复效果不好

 

#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)
 {
  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);
  }
  
  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] + pRow[x + 1]) / 2.0f;
    pData[y][nHalfW + i] = (pRow[x] - pRow[x + 1]) / 2.0f;
   }
  }
  // 垂直变换
  for (x = 0; x < nWidth; x++)
  {
   for (i = 0; i < nHalfH; i++)
   {
    y = i * 2;
    pColumn[i] = (pData[y][x] + pData[y + 1][x]) / 2.0f;
    pColumn[nHalfH + i] = (pData[y][x] - pData[y + 1][x]) / 2.0f;
   }
   for (i = 0; i < nHeight; i++)
   {
    pData[i][x] = pColumn[i];
   }
  }
 }
 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++)
   {
    y = i * 2;
    pColumn[y] = pData[i][x] + pData[nHalfH + i][x];
    pColumn[y + 1] = pData[i][x] - 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++)
   {
    x = i * 2;
    pRow[x] = pData[y][i] + pData[y][nHalfW + i];
    pRow[x + 1] =  pData[y][i] - pData[y][nHalfW + i];
   }
   memcpy(pData[y], pRow, sizeof(float) * nWidth);
  }
 }
 delete[] pData;
 delete[] pRow;
 delete[] pColumn;
}

 

### 基于小波变换的模极大值法去噪算法 #### 小波变换模极大值法简介 基于小波变换的模极大值法是一种用于信号去噪的技术。此方法利用了信号和噪声在不同尺度下的小波变换模极大值的不同传播特性来区分并去除噪声[^3]。 #### 算法原理 当对含有噪声的信号执行多尺度小波变换时,真正的信号特征会在多个连续尺度上显示出一致性的极值路径;而随机产生的噪声则不会形成这种连贯性,在大多数情况下仅在一个特定尺度下表现为局部极大值。通过识别这些具有跨尺度稳定特性的模极大值链,可以从原始数据中有效地恢复出干净的信号[^4]。 #### MATLAB实现示例 下面是一个简单的MATLAB代码片段,展示了如何使用小波变换模极大值法来进行一维信号的去噪: ```matlab function denoised_signal = wavelet_maxima_denoising(signal, level) % WAVELET_MAXIMA_DENOISING 使用小波变换模极大值法进行信号去噪 wname = 'db4'; % 设置小波基函数名称 [C,L] = wavedec(signal,level,wname); % 执行离散小波分解 for i = 1:level detail_coeffs{i} = detcoef(C,L,i); % 计算当前层细节系数绝对值的最大值位置 [~,maxIdx] = max(abs(detail_coeffs{i})); % 只保留最大值处对应的系数,其余置零 detail_coeffs{i}(detail_coeffs{i}~=detail_coeffs{i}(maxIdx)) = 0; end % 更新修改后的细节部分到原有多分辨率表示中 C_new = C; pos = length(C)-sum(L)+1; for i = 1:length(detail_coeffs) C_new(pos+(i-1)*L(end-i+1):(pos+i*L(end-i+1))-1) = detail_coeffs{end-(i-1)}; end % 进行逆向重构获得去噪后的新信号 denoised_signal = waverec(C_new,L,wname); end ``` 上述程序定义了一个名为`wavelet_maxima_denoising`的功能函数,它接受待处理的一维数组形式输入信号以及指定的小波分解层数作为参数,并返回经过小波变换模极大值法处理过的净化版输出信号。 #### 应用场景 这种方法广泛应用于各种领域内的信号处理任务当中,比如生物医学工程中的心电图(ECG)/脑电图(EEG)记录、地震学里的地质勘探数据分析等场合,能够显著提高信噪比(SNR),从而改善后续分析工作的准确性与可靠性[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值