At each sample the oldest value in the window is replaced with the new value and it is checked if the new value affects the median, if so a new value for the median is selected.

Committer:
networker
Date:
Fri Jan 31 10:36:45 2014 +0000
Revision:
0:9bd415456089
An efficient implementation of a sliding window median filter

Who changed what in which revision?

UserRevisionLine numberNew contents of line
networker 0:9bd415456089 1 #include <float.h>
networker 0:9bd415456089 2 #include "filter.h"
networker 0:9bd415456089 3
networker 0:9bd415456089 4 medianFilter::medianFilter(int window): N(window) {
networker 0:9bd415456089 5 big = new bool[N];
networker 0:9bd415456089 6 val = new float[N];
networker 0:9bd415456089 7 big = new bool[N];
networker 0:9bd415456089 8 i = 0;
networker 0:9bd415456089 9 for (int j = 0; j < N; j++) {
networker 0:9bd415456089 10 val[j] = 0;
networker 0:9bd415456089 11 big[j] = j > N/2;
networker 0:9bd415456089 12 }
networker 0:9bd415456089 13 med = 0;
networker 0:9bd415456089 14 median=0;
networker 0:9bd415456089 15 }
networker 0:9bd415456089 16
networker 0:9bd415456089 17 int medianFilter::findmax() {
networker 0:9bd415456089 18 float m = -FLT_MAX;
networker 0:9bd415456089 19 int n = -1;
networker 0:9bd415456089 20 for (int j = 0; j < N; j++) {
networker 0:9bd415456089 21 if (j == med) continue;
networker 0:9bd415456089 22 if (!big[j]) { //find max
networker 0:9bd415456089 23 if (val[j] > m) {
networker 0:9bd415456089 24 m = val[j];
networker 0:9bd415456089 25 n = j;
networker 0:9bd415456089 26 }
networker 0:9bd415456089 27 }
networker 0:9bd415456089 28 }
networker 0:9bd415456089 29 return n;
networker 0:9bd415456089 30 }
networker 0:9bd415456089 31
networker 0:9bd415456089 32 int medianFilter::findmin() {
networker 0:9bd415456089 33 float m = FLT_MAX;
networker 0:9bd415456089 34 int n = -1;
networker 0:9bd415456089 35 for (int j = 0; j < N; j++) {
networker 0:9bd415456089 36 if (big[j]) { //find min
networker 0:9bd415456089 37 if (val[j] < m) {
networker 0:9bd415456089 38 m = val[j];
networker 0:9bd415456089 39 n = j;
networker 0:9bd415456089 40 }
networker 0:9bd415456089 41 }
networker 0:9bd415456089 42 }
networker 0:9bd415456089 43 return n;
networker 0:9bd415456089 44 }
networker 0:9bd415456089 45
networker 0:9bd415456089 46 float medianFilter::process(float in) {
networker 0:9bd415456089 47 //the value at position 'i' is to be replaced by 'in' and the new median is computed
networker 0:9bd415456089 48 //var 'median' refers to the old median
networker 0:9bd415456089 49 // val[j] <= median <= val[k]
networker 0:9bd415456089 50 //by convention the mediam is considered small
networker 0:9bd415456089 51 val[i] = in;
networker 0:9bd415456089 52 if (i == med) { //the median itself is removed (not the value but the actual sample)
networker 0:9bd415456089 53 if (in <= median) { //the new value is smaller than or equal to the old median and may be the new median
networker 0:9bd415456089 54 med = -1; //hack to include the median cell in the comparison
networker 0:9bd415456089 55 med = findmax(); //the largest small value is the new median
networker 0:9bd415456089 56 } else { //the new value is larger than the old median and may be the new median
networker 0:9bd415456089 57 big[i] = true; //add the new val to the big set, which is now 1 too large
networker 0:9bd415456089 58 med = findmin();
networker 0:9bd415456089 59 big[med] = false;
networker 0:9bd415456089 60 }
networker 0:9bd415456089 61 } else if (!big[i]) {//old value is removed from small values
networker 0:9bd415456089 62 if (in <= median) {
networker 0:9bd415456089 63 //replace small with small, median not affected
networker 0:9bd415456089 64 } else { //the new value is large
networker 0:9bd415456089 65 big[i] = true;
networker 0:9bd415456089 66 med = findmin();
networker 0:9bd415456089 67 big[med] = false;
networker 0:9bd415456089 68 }
networker 0:9bd415456089 69 } else { //old value is large
networker 0:9bd415456089 70 if (in <= median) { //but the new value is small
networker 0:9bd415456089 71 big[i] = false;
networker 0:9bd415456089 72 big[med] = true;
networker 0:9bd415456089 73 med = findmax();
networker 0:9bd415456089 74 } else {//new value is also large
networker 0:9bd415456089 75 //replace large with large, median not affected
networker 0:9bd415456089 76 }
networker 0:9bd415456089 77 }
networker 0:9bd415456089 78 if (++i >= N) i = 0;
networker 0:9bd415456089 79 median = val[med];
networker 0:9bd415456089 80 return median;
networker 0:9bd415456089 81 }