I'm trying to implement low-pass filtering of images on java.
Implementing the following items (p. 245) from Gonzalez’s book “Digital Image Processing”:
- The original image is multiplied by "(-1) ^ (x + y)" so that its Fourier transform is centered;
- Calculates the direct DFT F (u, v) of the image obtained after step 1;
- The f-tion F (u, v) is multiplied by the f-tion of the filter H (u, v);
- Calculates the inverse DFT of the result of step 3;
- Calculates the real part of the result of step 4;
- The result of step 5 is multiplied by (-1) ^ (x + y)
Purely for example, I decided to implement the "Perfect Low-Pass Filter" (p. 277). As I understand it, the result is wrong from the very first step.
What am I doing wrong?
I attach the code of each step and the results of processing at each step.
My implementation steps:
one)
double funcXY; Complex[][] arrOnStepOne = new Complex[bufferedImage.getWidth()][bufferedImage.getHeight()]; for (int x = 0; x < bufferedImage.getWidth(); x++) { for (int y = 0; y < bufferedImage.getHeight(); y++) { funcXY = (Math.pow(-1.0, (x + y))) * bufferedImage.getRGB(x, y); Complex complexFuncXY = new Complex(funcXY, 0); arrOnStepOne[x][y] = complexFuncXY; } } 2)
int width = arrOnStepOne.length; int height = arrOnStepOne[0].length; Complex sumByX = new Complex(0, 0); Complex sumByY = new Complex(0, 0); Complex[][] complexFurje = new Complex[width][height]; for (int u=0; u <= width-1; u++) { for (int v = 0; v <= height-1; v++) { sumByX = new Complex(0, 0); for (int x = 0; x <= width - 1; x++) { sumByY = new Complex(0, 0); for (int y = 0; y <= height - 1; y++) { Double teta = -2 * Math.PI * ((u * x / (double) width) + (v * y / (double) height)); Complex complexE = new Complex(Math.cos(teta), Math.sin(teta)); sumByY = sumByY.Add(arrOnStepOne[x][y].Mult(complexE)); } sumByX = sumByX.Add(sumByY); } complexFurje[u][v] = sumByX.Div(new Complex(width*height, 0)); } } 3)
int d0; int nPow = 2; double d; double filtrD; double filtrH; Complex[][] complexFiltr = new Complex[width][height]; for (int u=0;u <= width-1; u++) { for (int v = 0; v <= height-1; v++) { d = Math.pow((u - width / 2.), 2) + Math.pow((v - height / 2.), 2); filtrD = Math.pow(d, 1. / 2); //D(u,v) d0 = 80; filtrH = 1 / (1 + Math.pow(filtrD / d0, 2. * nPow)); complexFiltr[u][v] = new Complex(filtrH, 0).Mult(complexFurje[u][v]); } } four)
for (int x = 0; x <= width-1 ; x++) { System.out.println("X = " + x +" / " + (width-1) + "."); for (int y = 0; y <= height-1 ; y++) { sumByU = new Complex(0, 0); for (int u = 0; u <= width-1; u++) { sumByV = new Complex(0, 0); for (int v = 0; v <= height - 1; v++) { Double teta = 2 * Math.PI * (x * u / (double) width + y * v / (double) height); Complex complexE = new Complex(Math.cos(teta), Math.sin(teta)); sumByV = sumByV.Add(complexE.Mult(complexFiltr[u][v])); } sumByU = sumByU.Add(sumByV); } funcStep4XY[x][y]=sumByU; } } 5.6)
for (int x = 0; x <= width-1; x++) { for (int y = 0; y <= height-1; y++) { funcStep5XY[x][y] = funcStep4XY[x][y].getdReal(); funcStep5XY[x][y] *= Math.pow(-1.0,x+y); } } 