5

I am looking for a Ansi C implementation of a fast/efficient median filter. Any pointers?

So far, I have found the following implementation, which is good but I am curious on faster ones. I only need for 1 dimension.

user4749
  • 431
  • 2
  • 6
  • 17

1 Answers1

13

I needed to extract a signal from very noisy CPU consumption data. Here's the Jeff McClintock median filter...

Initialize the average and median to zero, then for each sample 'inch' the median toward the input sample by a small increment. Eventually it will settle at a point where about 50% of the input samples are greater, and 50% are less than the median. The size of the increment should be proportional to the actual median. Since we don't know the actual median, I use the average as an rough estimate. The step size is calculated as 0.01 times the estimate. Smaller step sizes are more accurate, but take longer to settle.

float median = 0.0f;
float average = 0.0f;

// for each sample
{
    average += ( abs(sample) - average ) * 0.1f; // rough running average magnitude.
    median += _copysign( average * 0.01, sample - median );
}

enter image description here

Jeff McClintock
  • 1,153
  • 9
  • 27
  • 1
    While this solution is very efficient, beware of the following caveats: 1) convergence rate depends on signal amplitude (compare step responses with different offsets and amplitudes), therefore does not converge against signal near zero! 2) for near constant input signal this estimate introduces jitter with amplitude of `average * 0.01` and frequency of sample rate 3) deflects on short impulses (which a median originally does not, thus being popular as pepper and noise filter) – orzechow Jun 06 '17 at 12:02
  • Yeah, an improvement to remove the jitter is to limit the step size (average * 0.01) instead to no larger than the error-signal (sample - median) i.e. : std::max( average * 0.01, fabs(sample - median) ). – Jeff McClintock Oct 04 '17 at 23:20