 • ## Basics of the Sigma Filter

is a variant of the 3x3 average filter, which is too strong for many applications.
The fog filter adds a certain percentage of the original pixel to the democratic vote of its 3x3 rectangular neighborhood.
Thus the central pixel obtains a higher vote than any of its 8 neighbors.
Here is the pseudo-code for a gray value pixel:
1. Take the pixel's gray value and add the gray values of its eight neighbors.
2. Divide the sum by 9, round the result to integer.
3. Write it to an intermediary image.
4. The output image is composed of a certain FilterWeight-percentage of the intermediary image plus
a certain OriginalWeight-percentage of the input image.

The addition of a percentage of the original image is equivalent to an elevated weight of the `pixel[y,x]` among its neighbors.
Sample: The 3x3 fog filter which gives `old[y,x]` a weight of `8`, what means, that `old[y,x]` has as many votes as its 8 neighbors together
→ equivalent to 50% original + 50% average filter.

 ``` 0101 old = 1870 0651 1010``` ```new[1,1] = (0 + 1 + 0 + 1 + 8*8 + 7 + 0 + 6 + 5)/16 = 84/16 = 5.25 = rounded 5 new[2,1] = (1 + 0 + 1 + 8 + 7*8 + 0 + 6 + 5 + 1)/16 = 77/16 = 4.81 = rounded 5 new[1,2] = (1 + 8 + 7 + 0 + 6*8 + 5 + 1 + 0 + 1)/16 = 69/16 = 4.31 = rounded 4 new[2,2] = (8 + 7 + 0 + 6 + 5*8 + 1 + 0 + 1 + 0)/16 = 60/16 = 3.75 = rounded 4 new[0,0] = ( 0*8 + 1 + 1 + 8)/11 = 10/11 = 0.91 = rounded 1 new[1,0] = ( 0 + 1*8 + 0 + 1 + 8 + 7)/13 = 24/13 = 1.85 = rounded 2 new[3,3] = (5 + 1 + 1 + 0*8 )/11 = 7/11 = 0.63 = rounded 1 new[2,3] = (6 + 5 + 1 + 0 + 1*8 + 0 )/13 = 20/13 = 1.54 = rounded 2 etc.``` ``` 1331 new = 2551 1442 1121``` The gray value differences of the original remain visible, and image "new" is less blurred as with the 3x3 average filter.

# Experiments:

1. Try out sigma = 255.
2. Press several times the "More Noise" button.
3. Try out `sigma = 100`. It produces the best noise suppression.

# C#-Code of the `SigmaFilter3x3` click event:

```private void filter( int sigma )
{ int midPixel, anyPixel, sum, no, x, xx, xxx, y, yy, yyy;
for ( y=0; y < ySize; y++ ) //=============
{ for ( x=0; x < xSize; x++ ) //===========
{ midPixel = image1[y,x];   //input is the noisy image
sum = no = 0;
for ( yy=-1; yy <= 1; yy++ ) //==========
{ yyy = y + yy;
if ( yyy < 0 | yyy >= ySize ) continue;   //beyond the border
for ( xx=-1; xx <= 1; xx++ )//=========
{ xxx = xx + x;
if ( xxx < 0 | xxx >= xSize ) continue; //beyond the border
anyPixel = image1[yyy,xxx];
if ( Math.Abs( midPixel - anyPixel ) < sigma )
{ sum += anyPixel; no++; }
} //====== end for (int xx... ================
} //======== end for (int yy... ================
if ( no > 0 ) image2[y,x] = Convert.ToByte( (float)sum / no );
else          image2[y,x] = (Byte)midPixel; //just copy
} //============ end for (int x... =====================
} //============== end for (int y... =====================
}```

# Experiments:

1. Try out a kernel of 11x11 with many sigmas.
2. Try out sigma = 0 and sigma = 255.
3. Try out extreme kernels such as 128x1 and 1x106.
4. Load bigger images but do not apply kernels bigger than 15x15. Otherwise you have to be very patient.
5. When a filter takes too long, you can shorten the thread by simply shifting the FWidth slider to 1.

******************************************************************************************************
Q: What is a sigma filter ? One line pseudo code ?
A: It's a variant of the average filter with a selection, what neighbors inside the kernel have the right to vote.
Outsiders, which differ heavily from the central pixel are excluded from being averaged.
`if ( abs(neighborPixel-centerPixel) < sigma ) average neighborPixel; else forget it;`
It is the best and most flexible noise suppression filter.
******************************************************************************************************
Q: What happens when sigma = 0 ? What happens when sigma = 255 ?
A:
Sigma = 0 → just identical neighbors are averaged → no filtering at all.
Sigma = 255 → all neighbors are averaged → same result as the average filter.
*******************************************************************************************************
Q: How works the sigma filters border handling ? Advantages, Disadvantages ?
A: The kernel automatically shrinks where it overlaps the image borders. The filter covers the complete image.
Advantages: No black spaces are left along the borders. Border handling is part of the algorithm.
Disadvantages: Filter strength is weaker along the borders and the method is quite time consuming.
*******************************************************************************************************
Q: Why is a NxN sigma filter slower than a simple NxN average filter ?
A:
Average; Each pixel requires NxN additions.
Sigma; Each pixel requires NxN subtractions plus NxN `if`s before an addition.
*******************************************************************************************************
Q: Why there is no fast sigma filter ?
A: The filter can't be separated in a horizontal and a vertical partial filter and
there is no effective way to use the precedent sum to compute the next one.
*******************************************************************************************************
Q: How to find the best kernel size and the best sigma ?
A: The sigma filter works best with a kernel size between 5x5 and 15X15 and with a sigma of about 128.
The best fitting values must be found by trial and error.
*******************************************************************************************************