1. Introduction to mean filter, or average filter

Mean filter, or average filter is windowed filter of linear class, that smoothes signal (image). The filter works as low-pass one. The basic idea behind
filter is for any element of the signal (image) take an average across its neighborhood. To understand how that is made in practice, let us start with window idea.

2. Filter window or mask

Let us imagine, you should read a letter and what you see in text restricted by hole in special stencil like this.

Fig. 1. First stencil.

So, the result of reading is sound [t]. Ok, let us read the letter again, but with the help of another stencil:

Fig. 2. Second stencil.

Now the result of reading t is sound [ð]. Let us make the third try:

Fig. 3. Third stencil.

Now you are reading letter t as sound [θ].

What happens here? To say that in mathematical language, you are making an operation (reading) over element (letter t). And the result (sound) depends on the element neighborhood
(letters next to t).

And that stencil, which helps to pick up element neighborhood, is window! Yes, window is just a stencil or pattern, by means of which you are selecting the element neighborhood 
a set of elements around the given one  to help you make decision. Another name for filter window is mask  mask is a stencil, which hides elements we are not paying attention to.

In our example the element we are operating on positioned at leftmost of the window, in practice however its usual position is the center of the window.

Let us see some window examples. In one dimension.

Fig. 4. Window or mask of size 5 in 1D.

In two dimensions.

Fig. 5. Window or mask of size 3×3 in 2D.

In three dimensions... Think about building. And now — about room in that building. The room is like 3D window, which cuts out some subspace from the entire space of the building. You can find 3D window in volume (voxel) image processing.

Fig. 6. Window or mask of size 3×3×3 in 3D.

3. Understanding mean filter

Now let us see, how to “take an average across element's neighborhood”. The formula is simple  sum up elements and divide the sum by the number of elements. For instance, let us calculate an average for the case, depicted in fig. 7.

Fig. 7. Taking an average.

And that is all. Yes, we just have filtered 1D signal by mean filter! Let us make resume and write down step-by-step instructions for processing by mean filter.

Mean filter, or average filter algorithm:

Place a window over element;

Take an average — sum up elements and divide the sum by the number of elements.

Now, when we have the algorithm, it is time to write some code — let us come down to programming.

4. 1D mean filter programming

In this section we develop 1D mean filter with window of size 5. Let us have 1D signal of length N as input. The first step is window placing — we do that by changing
index of the leading element:

// Move window through all elements of the signalfor (int i = 2; i < N - 2; ++i)

Pay attention, that we are starting with the third element and finishing with the last but two. The problem is we cannot start with the first element, because in this case
the left part of the filter window is empty. We will discuss below, how to solve that problem.

5. Treating edges

For all window filters there is some problem. That is edge treating. If you place window over first (last) element, the left (right) part of the window will be empty.
To fill the gap, signal should be extended. For mean filter there is good idea to extend signal or image symmetrically, like this:

Fig. 8. Signal extension.

So, before passing signal to our mean filter function the signal should be extended. Let us write down the wrapper, which makes all preparations.

As you can see, our code takes into account some practical issues. First of all we check our input parameters  signal should not be NULL, and signal length should be positive:

// Check argumentsif (!signal || N < 1)
return;

Second step  we check case N=1. This case is special one, because to build extension we need at least two elements. For the signal of 1 element length the result is the signal itself. As well pay attention, our mean filter works in-place, if output parameter result is NULL.

Since we are using memory management function from standard library, we should include its header.

#include<memory.h>

6. 2D mean filter programming

In 2D case we have 2D signal, or image. The idea is the same, just now mean filter has 2D window. Window influences only the elements selection. The rest is the same: summing up the elements and dividing by their number. So, let us have a look at 2D mean filter programming. For 2D case we choose window of size 3×3.

8. Mean filter library

Now we have four functions, two of them are for processing 1D signals by mean filter, and other two are for filtering 2D images. It is time to put everything together and create small mean filter library. Let us write code for header file.