3

I want to implement the DFT (Discrete Fourier Transform) in C++ language to process images.

formula for 1D DFT

As I was studying the theory, I got to know, that I can divide the 2D DFT into two 1D DFT parts. Firstly, for each row I perform 1D DFT then I do it for each column. Of course, I should make operations on complex numbers.

Here occur some problems, because I am not sure where to use real, and where imaginary part of the complex number. I found somewhere, that the values of the input image pixels I should treat as a real part with the imaginary part set as 0.

I made an implementation of that, but I suppose that the result image is incorrect.

lenaclenac_dft

I would be grateful if someone could help me with that one.

For reading and saving images I use CImg library.

void DFT (CImg<unsigned char> image)
{
    int w=512;
    int h=512;
    int rgb=3;
    complex <double> ***obrazek=new complex <double>**[w];
    for (int b=0;b<w;b++) //making 3-dimensional table to store DFT values
    {
        obrazek[b]=new complex <double>*[h];
        for (int a=0;a<h;a++)
        {
            obrazek[b][a]=new complex <double>[rgb];
        }
    }

    CImg<unsigned char> kopia(image.width(),image.height(),1,3,0);

    complex<double> sum=0;
    complex<double> sum2=0;
    double pi = 3.14;

    for (int i=0; i<512; i++){
    for (int j=0; j<512; j++){
    for (int c=0; c<3; c++){
        complex<double> cplx(image(i,j,c), 0);
        obrazek[i][j][c]=cplx;
    }}}

    for (int c=0; c<3; c++) //for rows
    {
            for (int y=0; y<512; y++)
            {
                sum=0;
                for (int x=0; x<512; x++)
                {
                    sum+=(obrazek[x][y][c].real())*cos((2*pi*x*y)/512)-(obrazek[x][y][c].imag())*sin((2*pi*x*y)/512);
                    obrazek[x][y][c]=sum;
                }
            }
    }

    for (int c=0; c<3; c++) //for columns
    {
            for (int y=0; y<512; y++)//r
            {
                sum2=0;
                for (int x=0; x<512; x++)
                {
                    sum2+=(obrazek[y][x][c].real())*cos((2*pi*x*y)/512)-(obrazek[y][x][c].imag())*sin((2*pi*x*y)/512);
                    obrazek[y][x][c]=sum2;
                }
            }
    }

    for (int i=0; i<512; i++){
    for (int j=0; j<512; j++){
    for (int c=0; c<3; c++){
        kopia(i,j,c)=obrazek[i][j][c].real();
    }}}

    CImgDisplay image_disp(kopia,"dft");

    while (!image_disp.is_closed() )
    {

        image_disp.wait();

    }
    saving(kopia);
}
Richard Chambers
  • 16,643
  • 4
  • 81
  • 106
sashafierce
  • 83
  • 1
  • 11
  • 1
    How have you tried to debug this? For example, have you tried computing the DFT of a very simple input data-set (e.g. the identity matrix or an all-ones matrix), or at least simplifying your code to only work with grayscale images (as opposed to RGB)? – Oliver Charlesworth Jan 09 '12 at 20:37
  • 5
    I will make one observation, though: Your value of `pi` is woefully inaccurate. You should use 3.141592653589793. – Oliver Charlesworth Jan 09 '12 at 20:42
  • 3
    I will make some other observations: Your complex multiplication is wrong. And your 1D DFTs are fundamentally wrong (there should be a 4D loop, not a 3D loop). I suggest you start from scratch; first write a function that correctly multiplies complex numbers, then a routine that generates the complex exponential terms, then a function that combines these to perform a 1D DFT. You can then wrap this in a function that performs 2D DFTs, and then finally another wrapper function that calculates the DFT for each colour-plane. – Oliver Charlesworth Jan 09 '12 at 21:01

0 Answers0