code below runs on my laptop. it demonstrates median and linear (LP) filtering. test data is random values imposed on a constant value of 70.
the plot show the test data (gray), median filtered test data (red), linear filtered test data (yellow) and combined avg(median) (green)
below are values
main: samps
87, 65, 84, 85, 91, 55, 62, 83, 59, 73,
69, 76, 63, 71, 93, 91, 77, 81, 52, 75,
46, 57, 52, 85, 53, 65, 51, 50, 95, 56,
71, 87, 76, 60, 77, 71, 70, 94, 60, 84,
71, 83, 65, 90, 59, 63, 85, 91, 48, 92,
71, 49, 55, 78, 90, 62, 48, 46, 68, 48,
57, 94, 90, 88, 58, 72, 64, 83, 71, 78,
72, 47, 67, 92, 92, 81, 59, 82, 77, 63,
79, 53, 67, 89, 86, 62, 56, 90, 63, 79,
93, 74, 78, 88, 67, 91, 65, 86, 79, 91,
filter: median
0, 65, 84, 84, 85, 85, 62, 62, 62, 73,
69, 73, 69, 71, 71, 91, 91, 81, 77, 75,
52, 57, 52, 57, 53, 65, 53, 51, 51, 56,
71, 71, 76, 76, 76, 71, 71, 71, 70, 84,
71, 83, 71, 83, 65, 63, 63, 85, 85, 91,
71, 71, 55, 55, 78, 78, 62, 48, 48, 48,
57, 57, 90, 90, 88, 72, 64, 72, 71, 78,
72, 72, 67, 67, 92, 92, 81, 81, 77, 77,
77, 63, 67, 67, 86, 86, 62, 62, 63, 79,
79, 79, 78, 78, 78, 88, 67, 86, 79, 86,
filter: avg
87, 81, 82, 82, 84, 77, 73, 75, 71, 72,
71, 72, 70, 70, 75, 79, 79, 79, 72, 73,
66, 64, 61, 67, 63, 63, 60, 58, 67, 64,
66, 71, 72, 69, 71, 71, 70, 76, 72, 75,
74, 76, 73, 77, 73, 70, 74, 78, 70, 76,
74, 68, 65, 68, 73, 70, 65, 60, 62, 58,
58, 67, 72, 76, 72, 72, 70, 73, 72, 74,
73, 66, 66, 73, 77, 78, 73, 75, 76, 72,
74, 69, 68, 73, 76, 73, 68, 74, 71, 73,
78, 77, 77, 80, 76, 80, 76, 78, 78, 81,
filter: avg (median)
83, 84, 84, 84, 84, 84, 78, 74, 71, 71,
71, 71, 70, 70, 70, 75, 79, 80, 79, 78,
71, 67, 63, 62, 59, 61, 59, 57, 55, 55,
59, 62, 65, 68, 70, 70, 70, 70, 70, 73,
73, 75, 74, 76, 73, 71, 69, 73, 76, 79,
77, 75, 70, 66, 69, 71, 69, 63, 59, 56,
56, 56, 65, 71, 75, 74, 72, 72, 71, 73,
72, 72, 71, 70, 75, 79, 80, 80, 79, 78,
78, 74, 72, 71, 74, 77, 73, 70, 68, 71,
73, 74, 75, 76, 76, 79, 76, 78, 78, 80,
i could never come up with a simpler approach to sorting the data for a median filter. inevitably, you want to try larger filters (5, 7, )
#include <stdio.h>
#include <stdlib.h>
void
sort (
int *vec,
int N )
{
for (unsigned j = N-1; j > 0; j--) {
for (unsigned i = 0; i < j; i++) {
if (vec [i] > vec [i+1]) {
int t = vec [i];
vec [i] = vec [i+1];
vec [i+1] = t;
}
}
}
}
int
median (
int samp )
{
#define M 3
static int buf [M];
static int vec [M];
for (unsigned m = 1; M > m; m++)
vec [m-1] = buf [m-1] = buf [m];
vec [M-1] = buf [M-1] = samp;
sort (vec, M);
return vec [M / 2];
}
int
avg (
int samp )
{
static float _avg = 0;
if (0 == _avg) {
_avg = samp;
return _avg;
}
const float K = 1.0 / 4;
return _avg += (samp - _avg) * K;
}
// -----------------------------------------------------------------------------
void
gen (void)
{
printf ("int samps [] = {");
for (unsigned m = 0; 100 > m; m++) {
if (! (m % 8))
printf ("\n ");
printf (" %5.0f,", 70 + (50.0 * random () / RAND_MAX) - 25);
}
printf ("\n};\n");
printf ("#define N_SAMP (sizeof(samps)/sizeof(int))\n");
}
// -----------------------------------------------------------------------------
int samps [] = {
87, 65, 84, 85, 91, 55, 62, 83,
59, 73, 69, 76, 63, 71, 93, 91,
77, 81, 52, 75, 46, 57, 52, 85,
53, 65, 51, 50, 95, 56, 71, 87,
76, 60, 77, 71, 70, 94, 60, 84,
71, 83, 65, 90, 59, 63, 85, 91,
48, 92, 71, 49, 55, 78, 90, 62,
48, 46, 68, 48, 57, 94, 90, 88,
58, 72, 64, 83, 71, 78, 72, 47,
67, 92, 92, 81, 59, 82, 77, 63,
79, 53, 67, 89, 86, 62, 56, 90,
63, 79, 93, 74, 78, 88, 67, 91,
65, 86, 79, 91,
};
#define N_SAMP (sizeof(samps)/sizeof(int))
// -----------------------------------------------------------------------------
void
filter (void)
{
#define L 10
printf ("%s: samps");
for (unsigned m = 0; N_SAMP > m; m++) {
if (! (m % L))
printf ("\n ");
printf (" %5d,", samps [m]);
}
printf ("\n");
printf ("%s: median", __func__);
for (unsigned m = 0; N_SAMP > m; m++) {
if (! (m % L))
printf ("\n ");
printf (" %5d,", median (samps [m]));
}
printf ("\n");
printf ("%s: avg", __func__);
for (unsigned m = 0; N_SAMP > m; m++) {
if (! (m % L))
printf ("\n ");
printf (" %5d,", avg (samps [m]));
}
printf ("\n");
printf ("%s: avg (median)", __func__);
for (unsigned m = 0; N_SAMP > m; m++) {
if (! (m % L))
printf ("\n ");
printf (" %5d,", avg (median (samps [m])));
}
printf ("\n");
}
// -----------------------------------------------------------------------------
void
xgraph (void)
{
#define L 10
printf ("# %s: samps");
printf ("\ncolor=%s\nnext", "dark-gray");
for (unsigned m = 0; N_SAMP > m; m++) {
printf (" %4d %5d\n", m, samps [m]);
}
printf ("\n");
printf ("thickness = 1.5\n");
printf ("# %s: median", __func__);
printf ("\ncolor=%s\nnext", "red");
for (unsigned m = 0; N_SAMP > m; m++) {
printf (" %4d %5d\n", m, median (samps [m]));
}
printf ("\n");
printf ("# %s: avg", __func__);
printf ("\ncolor=%s\nnext", "yellow");
for (unsigned m = 0; N_SAMP > m; m++) {
printf (" %4d %5d\n", m, avg (samps [m]));
}
printf ("\n");
printf ("# %s: avg (median)", __func__);
printf ("\ncolor=%s\nnext", "green");
for (unsigned m = 0; N_SAMP > m; m++) {
printf (" %d %5d\n", m, avg (median (samps [m])));
}
printf ("\n");
}
// -----------------------------------------------------------------------------
int
main ()
{
#if 1
filter ();
#elif 1
xgraph ();
#else
gen ();
#endif
return 0;
}