Shop OBEX P1 Docs P2 Docs Learn Events
Faster way to median filter 3 values in PASM? — Parallax Forums

Faster way to median filter 3 values in PASM?

lonesocklonesock Posts: 917
edited 2011-04-12 10:52 in Propeller 1
Hi, All.

I'm thinking of adding a simple median-of-3 filter to EasyADC to get rid of some noise spikes. What I have so far sums the 3 values, and tracks the max and min values, as the median would be sum - max - min. I would appreciate it if anyone has a faster way, as I'm trying to keep the sampling speed up.

Here's the code to date:
              ' median filter
              mov       filter_max, A
              max       filter_max, oldA1
              max       filter_max, oldA2
              
              mov       filter_min, A
              min       filter_min, oldA1
              min       filter_min, oldA2
                           
              mov       medA, A
              add       medA, oldA1
              add       medA, oldA2
              sub       medA, filter_max
              sub       medA, filter_min

              mov       oldA2, oldA1 
              mov       oldA1, A              
              mov       A, medA
Thanks,
Jonathan

Comments

  • Dave HeinDave Hein Posts: 6,347
    edited 2011-04-11 15:44
    This uses 4 fewer instructions.
            mov temp0, A
            mov temp1, oldA1
    
            max temp0, oldA1
            max temp1, oldA2
            max oldA2, A
    
            min temp0, oldA2
            min temp0, temp1
    
            mov oldA2, oldA1
            mov oldA1, A
            mov A, temp0
    
  • lonesocklonesock Posts: 917
    edited 2011-04-11 16:10
    Ah, a sort instead of tracking min and max and sum! I'll need some time to wrap my brain around it.

    Thanks!

    Jonathan
  • Andrey DemenevAndrey Demenev Posts: 377
    edited 2011-04-11 16:11
                        mov     medA, A
                        cmp     maxA, A             wc, wz
                if_b    mov     medA, maxA
                if_b    mov     maxA, A
                if_ae   cmp     minA, A             wc, wz
                if_a    mov     medA, minA
                if_a    mov     minA, A
                        mov     A, medA
    
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-04-11 16:20
    lonesock wrote: »
    Ah, a sort instead of tracking min and max and sum! I'll need some time to wrap my brain around it.
    With 3 numbers you can compute the minimums for each of the 3 possible pairings. The maximum of the 3 minimums will be the median value.
  • lonesocklonesock Posts: 917
    edited 2011-04-12 08:41
    @ Andrey: Thanks! I think that's kind of a sliding median, where the last min/median/max values are kept for each update...I'd have to add the 3 most recent points each time to allow the median filter to respond quickly to changes in input. That brings up an interesting idea, though...what if I kept the median value from the last round and only added in the 2 most recent samples? I'm sure it would delay the response a bit, but it's at least worth simulating with a bunch of different waveforms + noise.

    @ Dave: You are the man! Thanks for the explanation!

    Jonathan

    P.S. To make this a real challenge, might be nice to have a 5-point median filter as well....just saying [8^)
  • lonesocklonesock Posts: 917
    edited 2011-04-12 10:52
    I was able to shave one instruction off of Dave's code:
                  ' Store the original value of A
                  mov       filter0, A   
                  ' Get the minimum of each of the 3 possible pairs ( A & oldA1, A & oldA2, oldA1 & oldA2 )              
                  mov       filter1, oldA2
                  max       oldA2, A                ' this modifies oldA2, but it will be overwritten soon anyway
                  max       filter1, oldA1
                  max       A, oldA1                ' A is modified (will be the median filtered value)
                  ' find the maximum of those 3 minima               
                  min       A, oldA2
                  min       A, filter1
                  ' update my tracking variables               
                  mov       oldA2, oldA1
                  mov       oldA1, filter0
    
    Anyone see a way to minimize this further?

    Jonathan
Sign In or Register to comment.