I am trying to write my own (or at least gain a better understanding of) Gaussian Blur filter using Python 2.7. I would really appreciate some direction. Everywhere else I have looked just uses built-ins...
1 Answers
You need to loop through each pixel in the image. At every pixel take weighted samples from its surroundings and sum them all together to new value of the pixel. So the code would look something like this:
for x in range(input.size[0]):
for y in range(input.size[1]):
result[x, y] = 0
result[x, y] += 0.01 * input[x-1, y+1] + 0.08 * input[x, y+1] + 0.01 * input[x+1, y+1]
result[x, y] += 0.08 * input[x-1, y ] + 0.64 * input[x, y ] + 0.08 * input[x+1, y ]
result[x, y] += 0.01 * input[x-1, y-1] + 0.08 * input[x, y-1] + 0.01 * input[x+1, y-1]
BUT in my code I'm not taking care of the edges of the image. This will result under and over indexing the image. There are at least three different easy ways how to take care of the edges:
- You can decrease the range of the for loop so it doesn't blur the pixels on the edge and crop not blurred pixels out of the image after the blur.
- You can make if statements in which you check that if you are on the edge of the image. On the edge you are not taking samples out of range and adjusting weights of the other pixels to sum to 1.0.
- You can mirror the image to every side. This can be done by actually mirroring the image or by accessing pixels inside the image as far away of the edge as far the over indexing would have gone.
With the options 2 and 3 the edges are not as blurred as the center of the image. This is a minor issue if your sample window size is 3x3 but it can be visible with much bigger sample window sizes.
If you want to achieve good performance, you can try for example replacing the for loops with OpenCL or OpenGL launch and write the inner loop into OpenCL kernel or GLSL shader. These will result as many pixels as possible to be computed in parallel. These can be optimized even further by blurring first in horizontal axes and then in vertical axes, which reduces sample counts and should be faster with bigger sample windows.
About the same thing are explained with other words in this post.