a floating median filter to filter floating point data such as analog inputs

Dependents:   Quadcopter_mk2

Fork of filter by Ad van der Weiden

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers filter.cpp Source File

filter.cpp

00001 #include <float.h>
00002 #include "filter.h"
00003 
00004 filter::filter(int window): N(window) {
00005     big = new bool[N];
00006     val = new double[N];
00007     big = new bool[N];
00008     i = 0;
00009     for (int j = 0; j < N; j++) {
00010         val[j] = 0;
00011         big[j] = j > N/2;
00012     }
00013     med = 0;
00014     median=0;
00015 }
00016 
00017 int filter::findmax() {
00018     double m = -FLT_MAX;
00019     int n = -1;
00020     for (int j = 0; j < N; j++) {
00021         if (j == med) continue;
00022         if (!big[j]) { //find max
00023             if (val[j] > m) {
00024                 m = val[j];
00025                 n = j;
00026             }
00027         }
00028     }
00029     return n;
00030 }
00031 
00032 int filter::findmin() {
00033     double m = FLT_MAX;
00034     int n = -1;
00035     for (int j = 0; j < N; j++) {
00036         if (big[j]) { //find min
00037             if (val[j] < m) {
00038                 m = val[j];
00039                 n = j;
00040             }
00041         }
00042     }
00043     return n;
00044 }
00045 
00046 double filter::process(double in) {
00047     //the value at position 'i' is to be replaced by 'in' and the new median is computed
00048     //var 'median' refers to the old median
00049     //  val[j] <= median <= val[k]
00050     //by convention the mediam is considered small
00051     val[i] = in;
00052     if (i == med) { //the median itself is removed (not the value but the actual sample)
00053         if (in <= median) { //the new value is smaller than or equal to the old median and may be the new median
00054             med = -1;  //hack to include the median cell in the comparison
00055             med = findmax(); //the largest small value is the new median
00056         } else { //the new value is larger than the old median and may be the new median
00057             big[i] = true; //add the new val to the big set, which is now 1 too large
00058             med = findmin();
00059             big[med] = false;
00060         }
00061     } else if (!big[i]) {//old value is removed from small values
00062         if (in <= median) {
00063             //replace small with small, median not affected
00064         } else { //the new value is large
00065             big[i] = true;
00066             med = findmin();
00067             big[med] = false;
00068         }
00069     } else  { //old value is large
00070         if (in <= median) { //but the new value is small
00071             big[i] = false;
00072             big[med] = true;
00073             med = findmax();
00074         } else {//new value is also large
00075             //replace large with large, median not affected
00076         }
00077     }
00078     if (++i >= N) i = 0;
00079     median = val[med];
00080     return median;
00081 }
00082 
00083 double filter::getMedian()
00084 {
00085     return median;
00086 }