Question

I have a problem with HPF. After implementing HPF on dft, the resultant image is very strange.

Here you have an example (I'm new so I can't post pictures but I can't formulate this question without it):

http://imageshack.com/a/img69/5911/tnj6.png

http://imageshack.com/a/img132/6931/fc8k.png After applying HPF with radius 50

I don't understand why such situation appears. When I add white dot in the centre of the HPF mask then result is good. Also low pass filter works perfectly.

I think I can eliminate the possibility that my FFT implementation is wrong because I wrote one by myself and I also used this implementation: librow.com/articles/article-10 and the results were pretty much the same.

This is my HPF code:

void Picture::HighPass(int radius){
    const complex<double> oblivion=(0,0);
    const int middlex = w/2;
    const int middley=h/2;
    double distance=0;

    int * T = new int[w*h];

    //draw circle in the center
    for(int y=0; y<h; y++){
        for(int x=0; x<w; x++){
            distance = sqrt(pow((middlex-x),2) + pow((middley-y),2));
            if(distance<radius){ 
                T[x+y*w]=0;
            } else T[x+y*w]=1;
        }
    }
    //T[middlex+middley*w]=1;
    int *temp = new int[w*h];
    for(int i=0;i<w*h;i++)temp[i]=T[i];

        //swap quadrants 
    for(int x=0;x<middlex;x++){
        for(int y=0;y<middley;y++){
            T[x+y*w] = temp[(middlex+x)+(middley+y)*w];
            T[(middlex+x)+(middley+y)*w] = temp[x+y*w];
            T[(middlex+x)+y*w] = temp[x+((middley+y)*w)];
            T[x+((middley+y)*w)] = temp[(middlex+x)+y*w];
        }
    }

    for(int i=0;i<w*h;i++)
        if(T[i]==0) dft[i]=oblivion;

    delete [] T;
    delete[] temp;
}

I would be really grateful if you could give me some advise or solution.

Was it helpful?

Solution

First, the dot at the center of your filter kernel is effectively representative of the average brightness/intensity/offset/bias of the image. That's a key part of filters. If you convert an image from the spatial domain to the frequency domain, and mess with the central pixels, you will change the average brightness of the image.

Second, it seems like you are implementing a brick-wall type filter, by just generating a black circular shape in your kernel. If you were to visualize this as a 3D image, it would look like a solid cylinder. To remedy the ringing artifact (ie: any time you use a brickwall filter, you will encounter a ringing/aliasing artifact), use a Gaussian type of filter. If you visualize it as a 3D image, it looks like a mountain-type shape which is Gaussian distributed. Please refer to the references.

So, in short, rather than generating a brickwall filter, use a Gaussian filter. Refer to the section "Low Pass Filtering: Blurring" in reference [3] for a fully described graphical example.

References

  1. Gaussian Smoothing, Accessed 2014-02-19, <http://homepages.inf.ed.ac.uk/rbf/HIPR2/gsmooth.htm>
  2. Gaussian Filtering, Accessed 2014-02-19, <https://www.cs.auckland.ac.nz/courses/compsci373s1c/PatricesLectures/Gaussian%20Filtering_1up.pdf>
  3. Test FFT Processing, Accessed 2014-02-19, <http://www.fmwconcepts.com/misc_tests/FFT_tests/>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top