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

Dependents:   Quadcopter_mk2

Fork of filter by Ad van der Weiden

Revision:
0:46a72e790df8
Child:
1:9ce370b360ba
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/filter.cpp	Wed Feb 16 20:05:42 2011 +0000
@@ -0,0 +1,81 @@
+#include <float.h>
+#include "filter.h"
+
+medianFilter::medianFilter(int window): N(window) {
+    big = new bool[N];
+    val = new float[N];
+    big = new bool[N];
+    i = 0;
+    for (int j = 0; j < N; j++) {
+        val[j] = 0;
+        big[j] = j > N/2;
+    }
+    med = 0;
+    median=0;
+}
+
+int medianFilter::findmax() {
+    float m = -FLT_MAX;
+    int n = -1;
+    for (int j = 0; j < N; j++) {
+        if (j == med) continue;
+        if (!big[j]) { //find max
+            if (val[j] > m) {
+                m = val[j];
+                n = j;
+            }
+        }
+    }
+    return n;
+}
+
+int medianFilter::findmin() {
+    float m = FLT_MAX;
+    int n = -1;
+    for (int j = 0; j < N; j++) {
+        if (big[j]) { //find min
+            if (val[j] < m) {
+                m = val[j];
+                n = j;
+            }
+        }
+    }
+    return n;
+}
+
+float medianFilter::process(float in) {
+    //the value at position 'i' is to be replaced by 'in' and the new median is computed
+    //var 'median' refers to the old median
+    //  val[j] <= median <= val[k]
+    //by convention the mediam is considered small
+    val[i] = in;
+    if (i == med) { //the median itself is removed (not the value but the actual sample)
+        if (in <= median) { //the new value is smaller than or equal to the old median and may be the new median
+            med = -1;  //hack to include the median cell in the comparison
+            med = findmax(); //the largest small value is the new median
+        } else { //the new value is larger than the old median and may be the new median
+            big[i] = true; //add the new val to the big set, which is now 1 too large
+            med = findmin();
+            big[med] = false;
+        }
+    } else if (!big[i]) {//old value is removed from small values
+        if (in <= median) {
+            //replace small with small, median not affected
+        } else { //the new value is large
+            big[i] = true;
+            med = findmin();
+            big[med] = false;
+        }
+    } else  { //old value is large
+        if (in <= median) { //but the new value is small
+            big[i] = false;
+            big[med] = true;
+            med = findmax();
+        } else {//new value is also large
+            //replace large with large, median not affected
+        }
+    }
+    if (++i >= N) i = 0;
+    median = val[med];
+    return median;
+}