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

Dependents:   df-2013-minihack-slingshot SPK-DVIMXR QuadCopter Projeto ... more

filter.cpp

Committer:
networker
Date:
2011-02-16
Revision:
0:46a72e790df8

File content as of revision 0:46a72e790df8:

#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;
}