a floating median filter to filter floating point data such as analog inputs
Fork of filter by
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 }
Generated on Wed Jul 13 2022 01:29:21 by 1.7.2