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”:

  1. The original image is multiplied by "(-1) ^ (x + y)" so that its Fourier transform is centered;
  2. Calculates the direct DFT F (u, v) of the image obtained after step 1;
  3. The f-tion F (u, v) is multiplied by the f-tion of the filter H (u, v);
  4. Calculates the inverse DFT of the result of step 3;
  5. Calculates the real part of the result of step 4;
  6. 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); } } 

The results of my steps Link to the book itself here

  • If you are given an exhaustive answer, mark it as correct (a daw opposite the selected answer). - Nicolas Chabanovsky
  • Uh .. And why the whole question is removed? - Pavel Parshin
  • @PavelParshin restored the question - Nick Volynkin

1 answer 1

Judging by the artifacts on step1.jpg, the calculations are performed in integers. In this case, an overflow occurs instead of saturation, which is why black pixels can be seen instead of "flashing" in white.

As a result, the DFT step2.jpg instead of a white "star" on a black background looks like an occasional noise, formed by the same overflow distortions.

Well, in the end, after the PDPF, a very noisy image of step56.jpg is obtained.

Just not enough bit in the calculations. For example, you need 35 bits, and 32 bits are used.