2014-03-26 68 views
0

我想通過哈爾變換實現基本的二維小波變換之一。使用2d Haar小波變換軟閾值處理的圖像去噪(C++)

我將此應用於圖像去噪問題。

我恢復的結果有一些黑色塊和somw白色塊。

我想我堅持軟閾值的一部分沒有正常化。

這裏是我的代碼:

#include "StdAfx.h" 
    #include "WaveletDenoising.h" 
    #include <cmath> 


    WaveletDenoising::WaveletDenoising(void) 
    { 
    } 

    WaveletDenoising::~WaveletDenoising(void) 
    { 
    } 

    /* Forward Haar wavelet transform: */ 
    void WaveletDenoising::ForwardHaar1D(double* data, int length) 
    { 
    const float inv_sqrt2 = 1/sqrt((double)2.0); 

    float norm = 1.0f/sqrt((double)length); 

    for(int i=0; i < length; i++) { 
     data[i] *= norm; 
    } 

    float *tmp = new float[length]; 

    while(length > 1) { 
     length /= 2; 

     for(int i=0; i < length; i++) { 
      tmp[i] = (data[2*i] + data[2*i+1]) * inv_sqrt2; 
      tmp[length + i] = (data[2*i] - data[2*i+1]) * inv_sqrt2; 
     } 

     memcpy(data, tmp, length*2*sizeof(float)); 
    } 

    delete [] tmp; 
    } 

    /* Transpose matrix: */ 
    void WaveletDenoising::Transpose(double *data, int width, int height) 
    { 
    double *B = new double[width*height]; 

    for(int y=0; y < height; y++) { 
     for(int x=0; x < width; x++) { 
      B[x*height + y] = data[y*width + x]; 
     } 
    } 

    memcpy(data, B, sizeof(double)*width*height); 

    delete [] B; 
    } 

    /* Forward 2d Haar wavelet transform: */ 
    void WaveletDenoising::ForwardHaar2D(double* data, int width, int height) 
    { 
    for(int i=0; i < height; i++) 
     ForwardHaar1D(&data[i*width], width); 

    Transpose(data, width, height); 

    for(int i=0; i < width; i++) 
     ForwardHaar1D(&data[i*height], height); 

    Transpose(data, height, width); 
    } 

    /* Inverse 1d Haar transform */ 
    void WaveletDenoising::InverseHaar1D(double* data, int length) 
    { 
    const float inv_sqrt2 = 1/sqrt((double)2.0); 
    float inv_norm = sqrt((double)length); 

    float *tmp = new float[length]; 
    int k = 1; 

    while(k < length) { 
     for(int i=0; i < k; i++) { 
      tmp[2*i] = (data[i] + data[k+i]) * inv_sqrt2; 
      tmp[2*i+1] = (data[i] - data[k+i]) * inv_sqrt2; 
     } 

     memcpy(data, tmp, sizeof(double)*(k*2)); 

     k *= 2; 
    } 

    for(int i=0; i < length; i++) { 
     data[i] *= inv_norm; 
    } 

    delete [] tmp; 
    } 

    /* Inverse 2d Haar wavelet transform */ 
    void WaveletDenoising::InverseHaar2D(double* data, int width, int height) 
    { 
    for(int i=0; i < width; i++) { 
     InverseHaar1D(&data[i*height], height); 
    } 

    Transpose(data, height, width); 

    for(int i=0; i < height; i++) { 
     InverseHaar1D(&data[i*width], width); 
    } 

    Transpose(data, width, height); 
    } 

    /* Image denoising by soft-thresholding */ 
    void WaveletDenoising::WaveletThresholdDenoising(int width, int height, double* src, double* des, double threshold) 
    { 
    int i, j, x, y; 

    this->ForwardHaar2D(src, width, height); 

    double mi = src[0*width+0]; /* find min value */ 
    double ma = src[0*width+0]; /* find max value */ 

    for (y=0; y<height; y++) 
    { 
     for (x=0; x<width; x++) 
     { 
      if (mi > src[y*width+x]) 
       mi = src[y*width+x]; 
      if (ma < src[y*width+x]) 
       ma = src[y*width+x]; 
     } 
    } 

    /* soft-thresholding */ 
    for (y=0; y<height; y++) 
    { 
     for (x=0; x<width; x++) 
     { 
      if (src[y*width+x] < threshold) 
       src[y*width+x] = 0; 
      else if (src[y*width+x] > threshold) 
       src[y*width+x] = src[y*width+x] - threshold; 
      else if (src[y*width+x] < -threshold) 
       src[y*width+x] = src[y*width+x] + threshold; 


     } 
    } 

    this->InverseHaar2D(src, width, height); 

    for (y=0; y<height; y++) 
    { 
     for (x=0; x<width; x++) 
     { 
      // for normalized: 
      src[y*width+x] = ((src[y*width+x] - mi)/(ma - mi))*255; 

      double temp = src[y*width+x]; 
      if (temp < 0) temp = 0; 
      else if (temp >255) temp = 255; 
      else temp = temp; 
      des[y*width+x] = (BYTE) src[y*width+x]; 
     } 
    } 
    } 

我怎樣才能做到這一點?

回答

1

在此代碼上花費了幾個小時後,我終於找到了我的代碼問題。首先,我必須改變double類型而不是floattemp變量InverseHaar1D函數。其次,根據噪聲級別調整調用函數中的值threshold。第三,擺脫一些冗餘線路作爲以下明確的功能。您可以通過以下鏈接查看結果:https://www.mediafire.com/?v80rslisl7fff6n

/* Image denoising by soft-thresholding */ 
    void WaveletDenoising::WaveletThresholdDenoising(int width, int height, double* src, double* des, double threshold) 
    { 
    int x, y; 

    /* Forward 2d Haar transform */ 
    this->ForwardHaar2D(src, width, height); 

    /* soft-thresholding */ 
    for(y=0; y < height; y++) 
    { 
     for(x=0; x < width; x++) 
     { 
      if (src[y*width+x] > threshold) 
       src[y*width+x] = src[y*width+x] - threshold; 
      else if (src[y*width+x] < -threshold) 
       src[y*width+x] = src[y*width+x] + threshold; 
      else 
       src[y*width+x] = 0; 
     } 
    } 

    /* Inverse 2D Haar transform */ 
    this->InverseHaar2D(src, width, height); 

    for (y=0; y<height; y++) 
    { 
     for (x=0; x<width; x++) 
     { 
      double temp = src[y*width+x]; 
      if (temp < 0) temp = 0; 
      else if (temp >255) temp = 255; 
      else 
       des[y*width+x] = (BYTE) temp; 
     } 
    } 
    }