a floating median filter to filter floating point data such as analog inputs
Fork of filter by
Diff: filter.cpp
- Revision:
- 0:46a72e790df8
- Child:
- 1:9ce370b360ba
diff -r 000000000000 -r 46a72e790df8 filter.cpp --- /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; +}