2) All median filters exhibit a delay of (FILTER_SIZE / 2 + 1) samples before they respond to a step change. When they do respond however, the output is also a step change. By contrast a classic LTI will slew to the stepped value at a rate governed by the time constant of the filter.

3) For a discussion on sorting algorithms, please see https://embeddedgurus.com/stack-overflow/2009/03/sorting-in-embedded-systems/ ]]>

I am not sure if replies to this post are still entertained. Anyhow, to me this is amazing! I have always used linear filters for all of my data acquisition type of applications…. About a decade ago, I came up against a problem, where I had a hunch a median filter would do the job. However, it remained only an idea since I did not know how to implement it and in the end, I simply used a heftier filter to remove the “burst” noise. However I have two questions for you…. I hope you would not mind answering even this late.

Q1. How does one pass the elements to the median filter? Does one pass 3 or 5 elements at a time? since my input is a circular buffer of say size 32 points, Do I perform the algorithm on a set of 3 / 5 elements at a time?

Q2. What happens when there is a step input ? Initially the median filter would discard the step value. How does the filter reach the final step value. Say from {3,4,4,6,3,5,5,3} the values go to {13,11,9,9,10,11,9,10}

I briefly worked with a quick sort algorithm and wonder if it would be a good fit here instead of the other sorting algorithms? What do you think?

Thanks for touching upon this oft neglected topic, for your thoughts and for the efforts of putting the code examples.

regards

Anand Phadnis

When I reach this level, I stop. ]]>

http://www.embedded.com/design/programming-languages-and-tools/4399504/Better-Than-Average ]]>

As always in this field, there is no single “right” answer. It would be boring if there were!

]]>Most often, I keep track of the last six samples in a circular buffer, along with the sum of the values. It’s easy to update the total count when you take the oldest sample out and put a new sample in. Then to read the “current” value, you scan through the buffer to find the highest and the lowest values (it’s a linear scan, and can always start at address 0 – you don’t need to follow the logical order or track the index numbers), and subtract them from your total count. This gives you an average (mean) of your samples, scaled by 4 (easy to divide again if you want), with outliers removed. The code is simple, small and fast, and using an average here will increase your resolution (for guasian noise).

If you really want to keep a list of samples in a sorted order, then a bubble sort is usually the best choice of sorting algorithm. While bubble sort is very inefficient for mixed lists, it is very good for almost-sorted lists – and being simple it can be written clearly and fast. When you have a small list that is kept sorted, and you are removing one sample and adding another before a re-sort, then bubble-sort only needs a single linear pass through the list and is thus highly efficient. (If the list is long enough, however, it would be more efficient to find the new spot using a binary search and “open the gap” using a block move – a sort of single-pass insertion sort.)

]]>Thank you so much ]]>

First off, this algorithm is really designed for processing a continuous stream of data which you wish to median filter. For example, if you have an analog-digital converter that is constantly outputting new data that you wish to median filter, then this is the algorithm for you. If you just have a one off static array to be median filtered, then you would be better off just sorting it and taking the middle value. That being said, if you really want to use the code to do what you want, then here’s what it would look like.

1. Change MEDIAN_FILTER_SIZE to the desired size of your filter (i.e. 5).

2. Your code would now look like this:

SHORT m_array[9] ={4,5,5,4,3,7,8,0,10};

void example_use(void)

{

SHORT idx;

SHORT median_value;

for (idx = 0; idx < 9; ++idx)

{

median_value = median_filter(m_array[idx]);

}

}

Now there are some subtleties here to watch out for. The algorithm as written only works on unsigned data (which is the sort of data you usually, but not always, get off an ADC). To use it with signed data, I think (but have not tested) that you need to do the following:

1. Change the first few lines of code so that they look like this:

SHORT median_filter(SHORT datum)

{

struct pair

{

struct pair *point; /* Pointers forming list linked in sorted order */

SHORT value; /* Values to sort */

};

2. Make this change to STOPPER

#define STOPPER (-32768) /* Smaller than any datum */

As an aside, the code above has been written to make it as easy to understand as possible. If I was doing this for real, I'd use the C99 data types and the N_ELEMENTS macro. Please search the blog if you aren't familiar with these as I think you'll be glad you did.

]]>