Skip to main content
GameDev.net gamedev.net
🔒 Locked

Fourier transform on image - problem with sharpening filter

Started by maxest Nov 23, 2011 at 12:41 PM 3 replies 1.2k views
Original Post
maxest
maxest
I implemented DFT and inverse DFT for images. So now I want to apply some filters in frequency space. Blur went easy. I simply do a fall off function on the frequencies as they go farther away from the center frequency. Now I wanted to do a sharpening filter by altering the high frequencies. I found this website http://www.cs.unm.edu/~brayer/vision/fourier.html that discusses sharpening filter and proses a simple piecewise linear function. So I used it and even used the very same Lena picture (size 256x256). In theory, I'm doing the same thing as the author of the website but my results are way different, which I enclose in the attachment. The image indeed seems to be sharper, but where does this white mess come from? I noticed similar problems when I tried to do an edge detection filter (by removing low frequencies). Basically, it looks that if I cut the high frequencies my results are predictable, but when I try to leave high and get rid off low frequencues, I get a lot of that white messy stuff. Any suggestions?

For the sake of clarity, here are my source codes (I think they are easy to follow):

DFT:

void discreteFourierTransform(CImageByte& input, CImageFloat& output)
{
for (int y = 0; y < input.getHeight(); y++)
{
for (int x = 0; x < input.getWidth(); x++)
{
for (int j = 0; j < input.getHeight(); j++)
{
for (int i = 0; i < input.getWidth(); i++)
{
float p = -PI_mul_2 * ((float)(x*i)/(float)input.getWidth() + (float)(y*j)/(float)input.getHeight());

float R = (float)input(i, j);
float I = 0.0f;

output(x, y, 0) += R*cosf(p) - I*sinf(p);
output(x, y, 1) += R*sinf(p) + I*cosf(p);
}
}
}
}
}


Inverse DFT:

void inverseDiscreteFourierTransform(CImageFloat& input, CImageFloat& output)
{
for (int y = 0; y < input.getHeight(); y++)
{
for (int x = 0; x < input.getWidth(); x++)
{
for (int j = 0; j < input.getHeight(); j++)
{
for (int i = 0; i < input.getWidth(); i++)
{
float p = PI_mul_2 * ((float)(x*i)/(float)input.getWidth() + (float)(y*j)/(float)input.getHeight());

float& R = input(i, j, 0);
float& I = input(i, j, 1);

output(x, y, 0) += R*cosf(p) - I*sinf(p);
output(x, y, 1) += R*sinf(p) + I*cosf(p);
}
}

output(x, y, 0) /= (float)(input.getWidth() * input.getHeight());
output(x, y, 1) /= (float)(input.getWidth() * input.getHeight());
}
}
}


Sharpening filter:

void sharpenFilter_frequencySpace(CImageFloat& dft)
{
float r1 = 0.0f;
float r2 = 96.0f;

vec2 coeffs = solve2x2(vec2(r1, 0.5f), vec2(r2, 4.0f));

for (int j = 0; j < dft.getHeight(); j++)
{
for (int i = 0; i < dft.getWidth(); i++)
{
float dx = (float)(dft.getWidth()/2 - i);
float dy = (float)(dft.getHeight()/2 - j);
float d = sqrtf(dx*dx + dy*dy);

if (d <= r1)
{
dft(i, j, 0) *= 0.5f;
dft(i, j, 1) *= 0.5f;
}
else if (d > r1 && d <= r2)
{
float s = coeffs.x*d + coeffs.y;
dft(i, j, 0) *= s;
dft(i, j, 1) *= s;
}
else if (d > r2)
{
dft(i, j, 0) *= 4.0f;
dft(i, j, 1) *= 4.0f;
}
}
}
}
japro
japro
If the input image uses the full "color range" (all values from 0 to 255) applying the filter can lead to stuff going out of range which will result in overflows when converting back to bytes... So my guess is that you have to clamp the results to the legal output range.
maxest
maxest
Thank you soooooooooo much. At first when I read your comment I thought: "what the hell is he talking about". I was pretty sure that casting from float to byte will do the clamping for me (taking (byte)15000.0f would yield 255), but I've just learnt that it is more of a "repeat" mode. Now I clamp as you adviced before doing the casting and it's all fine.
Again, thank you very much!
quasar3d
quasar3d
And still she's beautiful:)
maxest
maxest
Okay, I got my Fourier sample working. I will certainly post a demo on my weblog with pretty nice and short code. And I'm also thinking about writing some short tutorial to the Fourier transform so if anyone's interested, keep your eyes on http://maxestws.blogspot.com

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.