The **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 algorithm is also famous as **Box blur filter** and often performs as **convolution** with *average blur mask*.

Our article discusses the general properties of median filtration and how we can use it in various online application. This tutorial describes how does the blur filter works and how to use it as an *OpenGL shader* for

## How does average 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 *a*verage *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.

### 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 **shaderfor fast image blurring by iterative *mean filtration*. We base our algorithm on the fact that *Gaussian filter* approximates well by multiple iterations of **box filter** or so called **average 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.

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:

## Fast Image blur source code

### Blur filter fragment shader

The source code below represents **fragment shader (GLSL)** of averge blur filter. The implementation uses window with size of 3×3 pixels. 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;
}
```