CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Question for PCM programmer on modifying median filter

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
cbarberis



Joined: 01 Oct 2003
Posts: 172
Location: Punta Gorda, Florida USA

View user's profile Send private message Send e-mail

Question for PCM programmer on modifying median filter
PostPosted: Fri Mar 16, 2012 6:41 am     Reply with quote

I have a question for PCM programmer, but anyone else that has the answer is just as welcome. I trying to adapt the original "median filter" which I think PCM programmer posted a few years back. I am trying to adapt this filter so it removes occasional spikes from data on five individual data channels, the data comes from a 22bit converter so I have to use int32 for all data handling. Because I gather, process and send out data sequentially, I think the best method would be to duplicate the main filter function five times with a different function name in each case. So I have tried this and I have gotten very weird results, mainly because I screwed-up a few things like
" memset(sorted_data, 0, MEDIAN_FILTER_WIDTH * 2);" and
"memcpy(sorted_data, input_buffer, num_elements * 2);" which I believe only works on bytes, so how would you modify these two functions to handle int32 data? Also I have been sharing the following function with all five median filter functions;
void Insertion_Sort_32(unsigned int32 *data, char array_size);
Should the above function be also discrete to each filter function?

Here is a copy of the modified median filter shown only for a single section

// DEFINES



#define MEDIAN_FILTER_WIDTH 5


//------------------------------------------

// FUNCTION PROTOTYPES



unsigned int32 median_filter(unsigned int32 latest_element);

void Insertion_Sort_32(unsigned int32 *data, char array_size);




//========================================================



// filters.c

//-------------------

// median_filter:

// This function sorts an array of longs so it's in

// ascending order. It then returns the middle element.

// ie., If the array has 7 elements (0-6), it returns

// the element at index 3. The user should ensure that

// the array has an odd number of elements.

// This function stores data from prior calls in a static

// buffer.



// The output of this function will always be N/2 +1

// elements behind the input data, where N is the filter width.




unsigned int32 median_filter(unsigned int32 latest_element)
{

static unsigned int32 input_buffer[MEDIAN_FILTER_WIDTH];

static char inbuf_index = 0;

static char num_elements = 0;

static unsigned int32 sorted_data[MEDIAN_FILTER_WIDTH];

unsigned int32 median;



// Insert incoming data element into circular input buffer.

input_buffer[inbuf_index] = latest_element;

inbuf_index++;

if(inbuf_index >= MEDIAN_FILTER_WIDTH) // If index went past buffer end

inbuf_index = 0; // then reset it to start of buffer



if(num_elements < MEDIAN_FILTER_WIDTH)

num_elements++;



// THIS LINE MAY NOT BE NEEDED IF SORTED DATA IS STATIC.

// memset(sorted_data, 0, MEDIAN_FILTER_WIDTH * 2);



// Copy input data buffer to the (to be) sorted data array.

memcpy(sorted_data, input_buffer, num_elements * 2); // memcpy works on bytes



// Then sort the data.

Insertion_Sort_32(sorted_data, MEDIAN_FILTER_WIDTH);



// During the first few calls to this function, we have fewer

// elements in the sorted data array than the filter width.

// So to compensate for that, we pick the median from the number

// of elements that are available. ie, if we have 3 elements,

// we pick the middle one of those as the median.

// Also, because the sort function sorts the data from low to high,

// we have to calculate the index from the high end of the array.

median = sorted_data[MEDIAN_FILTER_WIDTH - 1 - num_elements/2];



return(median);

}



//-------------------------------------------------------------





//-----------------------------------------------------

void Insertion_Sort_32(unsigned int32 *data, char array_size)

{

char i, j;

unsigned int32 index;



for(i = 1; i < array_size; i++)

{

index = data[i];

j = i;



while ((j > 0) && (data[j-1] > index))

{

data[j] = data[j-1];

j = j - 1;

}



data[j] = index;

}



}
cbarberis



Joined: 01 Oct 2003
Posts: 172
Location: Punta Gorda, Florida USA

View user's profile Send private message Send e-mail

PostPosted: Fri Mar 16, 2012 6:54 am     Reply with quote

I guess for the following functions which I never clearly understood, I would have to change them as follows to work with an int32?

memset(sorted_data, 0, MEDIAN_FILTER_WIDTH * 4);

and

memcpy(sorted_data, input_buffer, num_elements * 4);

But I am still not sure that you can share the Insertion_sort() function?
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Fri Mar 16, 2012 7:46 am     Reply with quote

Hi,

It's bad forum etiquitte to address a question to a specific member. You should also learn to use the "code" button when you post your code.

John
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Mar 16, 2012 8:49 am     Reply with quote

Several comments:

First, in general, having any code duplicated more than perhaps twice, is a sign that you are not really 'thinking'.
Make a single function, and hand it the _address_ of a structure, containing the memory block and temporary values. The same code then does for everything.

Then, int32, is 4 bytes. memset, and memcpy, work in bytes. The original code used int16's, which are 2 bytes, hence the '*2'. You need *4.

As a further comment though, if you are averaging the data, and just want to reject extreme values, consider an 'Olympic' average algorithm. As an example, just sum ten values, and while you are summing then, record the largest and smallest value you see. Then subtract these two values from the sum, and divide by eight. Result an average of the eight 'middle' values in the group of ten. Simpler, quicker, and uses a lot less space, while working to reject the extreme values, which sounds as if this is exactly what is needed. This is the basis of the 'trimmean' function in Excel.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group