Box Blur – Image smooth with WebGL


Box blur is a linear low-pass filter where each pixel in the output image has average value of its neighboring pixels in the input image. The filter is also called Mean filter, since it is often done as convolution with average blur mask. Our example use a 3×3 blurring mask as the one on below.

mean-filter-maskMean filter mask

Even though the modern camera devices provide pretty good quality, often pictures are noisy. In such cases a common technique is to use low-pass filter to prevent high frequency noise artifacts. Using such filter results in a blurry image, so frequently we refer to the low pass filter as “blurring” or “smoothing” filter.


Box Blur over GPU

Before you continue with this article it will be good to visit the detailed Gaussian Filter topic. This section provides a GPU  based approach using WebGL/OpenGL shader for fast image blurring by iterative mean filtration. We base our algorithm on the fact that Gaussian blur approximates well by multiple iterations of box or so called mean filter. Equation (1) describes the standard deviation of mean filter with size n, since it corresponds to uniform probability distribution. In case of multiple iterations m the resulting std deviation is result from equation 2.
Box blur standard deviationBox blur standard deviation

Thus in order to calculate number of iterations m for known kernel size (e.g. n=3) and provided sigma, the equation could be represented as following:

Box blur iterations countIterations count based on standard deviation and kernel size

Moving Averages

The 2D box filter can be represented as two separate 1D horizontal/vertical vectors in the same way as the Gaussian filter. Using this feature it is possible to achieve O(n) complexity. In addition to this it is possible to apply additional optimization called moving averages and reduce its complexity further to O(1).

The following steps describe the Moving Averages algorithm:

  • Iterate through each row/column in a single pass
  • For the first pixel use the whole kernel size and calculate the sum and write the mean as output
  • For each next pixel use the sum from the previous step and subtract values which are no longer covered by the kernel.
  • Add values at the right.
  • Calculate the average sum and write it as output

Fast Image blur source code

Mean filter fragment shader

The source code below represents fragment shader (GLSL) of mean filter. The window size is 3×3 and number of used iterations is calculated using the math equation (3) mentioned above.


precision mediump float;

// our texture
uniform sampler2D u_image;
uniform vec2 u_textureSize;
void main() {
	vec2 textCoord = gl_FragCoord.xy / u_textureSize;
	vec2 onePixel = vec2(1.0, 1.0) / u_textureSize;
	gl_FragColor = (
		texture2D(u_image, textCoord + onePixel*vec2(-1.0, -1.0)) +
		texture2D(u_image, textCoord + onePixel*vec2(0.0, -1.0)) + 
		texture2D(u_image, textCoord + onePixel*vec2(1.0, -1.0)) + 
		texture2D(u_image, textCoord + onePixel*vec2(-1.0, 0.0)) + 
		texture2D(u_image, textCoord + onePixel*vec2(0.0,  0.0)) + 
		texture2D(u_image, textCoord + onePixel*vec2(1.0,  0.0)) + 
		texture2D(u_image, textCoord + onePixel*vec2(-1.0, 1.0)) + 
		texture2D(u_image, textCoord + onePixel*vec2(0.0,  1.0)) + 
		texture2D(u_image, textCoord + onePixel*vec2(1.0,  1.0))) / 9.0;
}

Visit FivekoGFX on GitHub for more image processing examples

 

Fast Image blur Demo

Sigma: 3

Related Articles