具有幅度的频域图像滤波(不是matlab)

时间:2013-03-17 14:48:37

标签: c image image-processing dft imagefilter

我试图通过应用DFT(傅立叶)对图像进行模糊,计算幅度和相位部分,最后拍摄一个滤镜图像,它只是在黑色中间的白色模糊圆圈,具有相同的尺寸原始图片。

为此,在我从原始图像获得幅度图像之后,在幅度图像和滤波器图像之间进行乘法,“逐个位置”,因此我有一个新的幅度图像。

问题是,当我尝试用这个新的幅度(和旧阶段)反转DFT时,我得到了垃圾。如果我使用原始幅度进行IDFT,我会成功获得原始图像(镜像但是没问题)。

for(int i=0; i < ROWS; i++) {
        for(int j=0; j < COLS; j++) {
            magnitude->matriz[i][j] = (magnitude->matriz[i][j] * filter->matriz[i][j]);
        }
    }    

也许还有一些额外的数学?或者必须首先操纵滤镜(圆圈)图像。我尝试将结果除以COLS或ROWS,结果是某种二值化图像,它与原始图像相似,但不是我想要的! (甚至没有关闭)。

感谢您的帮助。

如有必要,我可以发布更多代码或所有代码。

EDITED 的 添加了代码和示例图像。

//The Discrete Fourier Transform function
//It applies the transform in an array only (1D)
COMPLEX* DFT(COMPLEX* F, int N, bool inv) {

   int u, x;
   float cosarg = 0;
   float sinarg = 0;
   float W;
   COMPLEX *ft;
   COMPLEX tmp;


   ft = (COMPLEX*) malloc(N*sizeof(COMPLEX));

   for (u=0; u<N; u++) {

      ft[u].r = 0;
      ft[u].i = 0;

      W = (u*2*PI)/N;

      for (x=0; x<N; x++) {
         tmp.r = cos(W*x);
         if(inv==false) tmp.i = (-1.0)*sin(W*x);
         else tmp.i= sin(W*x);
         ft[u] = complex_plus(ft[u],(complex_times(F[x],tmp))); 
      }
      if(inv==false)ft[u].r = ft[u].r/N;
      if(inv==false)ft[u].i = ft[u].i/N;
   }
   return ft;
}

int main(){
    //Declarations

    BMP Original;
    BMP Blur;
    BMP Edge;
    BMP Mag;
    BMP High;
    BMP Low;
    BMP Filter;
    BMP Magnitude;

    Matriz* magnitude;
    Matriz* phase;  

    MCOMPLEX* original;
    MCOMPLEX* fourier;
    MCOMPLEX* fourier_colunas;
    COMPLEX* buffer;
    COMPLEX* ftbuffer;

    Matriz* blur;
    Matriz* edge;
    Matriz* filter;

    int COLS;
    int ROWS;

    float max;
    float scale_brightness;

    //Original image
    Original.openBmp(STRING);
    Filter.openBmp(FILTER);

    Blur.creatImg(Original.getIntWidth(), Original.getIntHeight(), 0, 0, 0);
    Edge.creatImg(Original.getIntWidth(), Original.getIntHeight(), 0, 0, 0);
    Magnitude.creatImg(Original.getIntWidth(), Original.getIntHeight(), 0, 0, 0);

    //Convert open image to 2d array for manipulation
    original = converteToMCOMPLEX(Original);
    filter = converteToM(Filter);

    //Based on original image dimensions
    COLS= original->w;
    ROWS= original->h;

    //Dynamic allocations
    buffer=(COMPLEX*) malloc(ROWS*sizeof(COMPLEX));
    ftbuffer=(COMPLEX*) malloc(ROWS*sizeof(COMPLEX));
    fourier_colunas = (MCOMPLEX*) malloc(sizeof(MCOMPLEX));
    fourier_colunas->c= (COMPLEX**) malloc(COLS*sizeof(COMPLEX*));
    fourier = (MCOMPLEX*) malloc(sizeof(MCOMPLEX));
    fourier->c = (COMPLEX**) malloc(COLS*sizeof(COMPLEX*));
    magnitude = (Matriz*) malloc(sizeof(Matriz));
    magnitude->matriz = (float**) malloc(COLS*sizeof(float*));
    phase = (Matriz*) malloc(sizeof(Matriz));
    phase->matriz = (float**) malloc(COLS*sizeof(float*));
    blur = (Matriz*) malloc(sizeof(Matriz));
    blur->matriz = (float**) malloc(COLS*sizeof(float*));


    for(int i=0; i<COLS; i++){
        fourier_colunas->c[i] = (COMPLEX*) malloc(ROWS*sizeof(COMPLEX));
        fourier->c[i] = (COMPLEX*) malloc(ROWS*sizeof(COMPLEX));
        magnitude->matriz[i] = (float*) malloc(ROWS*sizeof(float));
        phase->matriz[i] = (float*) malloc(ROWS*sizeof(float));
        blur->matriz[i] = (float*) malloc(ROWS*sizeof(float));
    }




    //1D-Transform column by column

    for (int j=0; j<COLS; j++) {

        //Copy a column from array original into the buffer vector/
        for (int i=0; i<ROWS; i++) {
           buffer[i].r = original->c[i][j].r;
           buffer[i].i = original->c[i][j].r;
        }
        //Call DFT to apply 1D-transform in the column

        ftbuffer = DFT(buffer,ROWS,false);


        //Copy the result in an 2d array representing the complex fourier intermediary image
        //calculated considering just the transform of the columns
        for (int i=0; i<ROWS; i++) {
           fourier_colunas->c[i][j].r = ftbuffer[i].r;
           fourier_colunas->c[i][j].i = ftbuffer[i].i;
        }
  }

    //Now 1-Transform row by row

     for (int i=0; i<ROWS; i++) {
    //Copy a row from array fourier_colunas (the intermediary result) into the buffer vector

        for (int j=0; j<COLS; j++) {
           buffer[j].r = fourier_colunas->c[i][j].r;
           buffer[j].i = fourier_colunas->c[i][j].r;
        }

        //Call DFT to apply 1D-transform in the row

        ftbuffer = DFT(buffer,COLS,false);


        //Copy the result to the final fourier image 2D-transformed with two 1D-transforms
        for (int j=0; j<COLS; j++) {
           fourier->c[i][j].r = ftbuffer[j].r;
           fourier->c[i][j].i = ftbuffer[j].i;
        }
  }
     //This would serve the purpose to scale the magnitude image so it's better visible to human eye, 
     //not being used to not affect the final result (need pure magnitude image)

    //max=0;
    //
    //for (int i=0; i<ROWS; i++) {
    //  for (int j=0; j<COLS; j++) {
    //    if (complex_mag(fourier->c[i][j]) > max) max = complex_mag(fourier->c[i][j]);
    //  }
    //}

    //scale_brightness = 255/(log(1 + max));
    //   for (int i=0; i < ROWS; i++) {
    //  for (int j=0; j < COLS; j++) {
    //    magnitude->matriz[i][j] = scale_brightness*(log(1 + complex_mag(fourier->c[i][j])));
    //  }
    //}

     //Calculates the magnitude 2d array/image from the fourier transform (real and imaginary components)
    for (int i=0; i < ROWS; i++) {
        for (int j=0; j < COLS; j++) {
            magnitude->matriz[i][j] = complex_mag(fourier->c[i][j]);
        }
    }

    //Calculates the phase 2d array/image from the fourier transform (real and imaginary components)
    for (int i=0; i < ROWS; i++) {
        for (int j=0; j < COLS; j++) {
            phase->matriz[i][j] = complex_phase(fourier->c[i][j]);
        }
    }

    //This filter should work.
    for(int i=0; i < ROWS; i++) {
        for(int j=0; j < COLS; j++) {
            magnitude->matriz[i][j] = (magnitude->matriz[i][j] * filter->matriz[i][j]);
        }
    }

    //With the new magnitude combine with the (unmodified) phase part
    //to obtain a new fourier complex image to inverse transform
    for(int i=0; i < ROWS; i++) {
        for(int j=0; j < COLS; j++) {
            fourier->c[i][j].r = complex_r(magnitude->matriz[i][j], phase->matriz[i][j]);
            fourier->c[i][j].i = complex_i(magnitude->matriz[i][j], phase->matriz[i][j]);
        }
    }

    //This code is the same fourier procedure as before, with the exception of the inv flag 
    //set to TRUE, so now the DFT function performs a inverse fourier transform in the complex image (2d fourier array)
    //The result is IDFT(fourier)
    for (int j=0; j<COLS; j++) {


        for (int i=0; i<ROWS; i++) {
           buffer[i].r = fourier->c[i][j].r;
           buffer[i].i = fourier->c[i][j].i;
        }


        ftbuffer = DFT(buffer,ROWS,true);


        for (int i=0; i<ROWS; i++) {
           fourier_colunas->c[i][j].r = ftbuffer[i].r;
           fourier_colunas->c[i][j].i = ftbuffer[i].i;
        }
  }

     for (int i=0; i<ROWS; i++) {

        for (int j=0; j<COLS; j++) {
           buffer[j].r = fourier_colunas->c[i][j].r;
           buffer[j].i = fourier_colunas->c[i][j].i;
        }



        ftbuffer = DFT(buffer,COLS,true);


        //What remains is to the copy col by col in the final 2d array
        //that will represent the new image. We just want the real part
        for (int j=0; j<COLS; j++) {
             blur->matriz[i][j] = ftbuffer[j].r;
         //  blur->c[i][j].i = ftbuffer[j].i;
        }
  }

     //Procedures to convert the arrays to real images
     //and save them
     blur->h= Original.getIntHeight();
     blur->w= Original.getIntWidth();
     magnitude->h= Original.getIntHeight();
     magnitude->w= Original.getIntWidth();

     Magnitude = converteToBMP(magnitude, Magnitude);
     Magnitude.saveBmp("c:\\f1\\magnitude.bmp");

     Blur = converteToBMP(blur, Blur);
     Blur.saveBmp("c:\\f1\\blur.bmp");

    system("pause");
    return 0;
}

图片

我没有足够的声誉来指导链接图片,因此我将发布未格式化的链接。

原始图片:http://imm.io/ZIUH

两个Cenarios

1 - 没有过滤器。只需应用傅立叶变换和逆傅里叶变换即可获得相同的图像。

//Fourier transformed and reversed: http://imm.io/ZIU8
//Resultant not modified magnitude image: http://imm.io/ZIVX
//Resultand log-scaled magnitude image: http://imm.io/ZIW5

2 - 通过将幅度图像与滤镜图像相乘来过滤原始图像

//Filter: http://imm.io/ZIVq
//Filter and Magnitude: http://imm.io/ZIVC
//Result (fourier reversed): http://imm.io/ZIV4

0 个答案:

没有答案