Mean Filter for Fast Noise Reduction


Mean filter is a linear low-pass blur filter where each pixel in the output image has average value of its neighboring pixels in the input image. The filter is also famous as Box blur filter and often performs as convolution with average blur mask. Our article discusses the common properties of median filtration and how we can use it in different online application. This tutorial describes how does the mean filter works and how to use it as an OpenGL shader for GPU processing.

mean filter size 9 Mean filter with size 9


How does Mean filter works?

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 Median filter as “blurring” or “smoothing” filter. Like the Gaussian blur, an uniform blurring with mean filter is done using a convolution kernel like the one below. Keep in mind that this filter is also a separable one, which means it’s usually better to execute it once for rows and once for columns.

$\displaystyle{K}=\frac{1}{{9}}{\left[\begin{matrix}{1}&{1}&{1}\\{1}&{1}&{1}\\{1}&{1}&{1}\end{matrix}\right]}=\frac{1}{{3}}{\left[\begin{matrix}{1}&{1}&{1}\end{matrix}\right]}\ast\frac{1}{{3}}{\left[\begin{matrix}{1}\\{1}\\{1}\end{matrix}\right]}$ Mean filter with size 3×3

Moving Averages

In addition to mean filter separation it is possible to apply additional optimization called “moving averages” and reduce its complexity further to O(1). The following steps describe the process:
  • 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 under the kernel.
  • Add values at the right.
  • Calculate the average sum and write it as output

Iterative Box Blur over GPU

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 filter 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

Fast Image blur source code

Mean filter fragment shader

The source code below represents fragment shader (GLSL) of mean filter. The filter window has a size of 3×3, and for the number of iterations we use the math equation (3) from the above section.


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


Related Articles