/*--------------------------------------------------------------------------- med3x3.asm - perform three-by-three median filtering ----------------------------------------------------------------------------- Description: A median filter replaces a given pixel with the median value of its neighbors. Unlike a 3x3 convolution, which can destroy some spatial resolution, the median filter is useful for removing isolated lines or pixels while preserving spatial resolution. It performs well on images containing binary noise, but poorly when the noise is Gaussian. It also does not work well when the number of noise pixels in the 3x3 window is greater than 4. This implementation is based on magic described in Andrew Glassner's "Graphics Gems", cited below in the "References" section. ----------------------------------------------------------------------------- Program Characteristics: Calling Registers: i0 index to data values m0 column offset (usually 1) m1 row offset (usually [#pixels/row - 2]) m2 offset to next 3x3 block (usually -[2*m1 + 1]) Altered Registers: r0-r6 tmp values Return Values: r0 median value Computation Time: 56 cycles ----------------------------------------------------------------------------- Author: Jim Donahue, Analog Devices DSP Division References: Glassner, Andrew S. (1990), "Graphics Gems", Academic Press, Inc. p.171,711 Jain, Anil K. (1989) "Fundamentals of Digital Image Processing", Prentice Hall, p.246-247 Created: 27-MAR-91 ----------------------------------------------------------------------------*/ #define s2(a,b) comp(a,b); if gt b = pass a, a = b; #define mnmx3(a,b,c) s2(b,c); s2(a,c); s2(a,b) #define mnmx4(a,b,c,d) s2(a,b); s2(c,d); s2(a,c); s2(b,d) #define mnmx5(a,b,c,d,e) s2(a,b); s2(c,d); s2(a,c); s2(a,e); \ s2(d,e); s2(b,e) #define mnmx6(a,b,c,d,e,f) s2(a,d); s2(b,e); s2(c,f); \ s2(a,b); s2(a,c); s2(e,f); s2(d,f) .SEGMENT /pm pm_code; .GLOBAL med3x3; med3x3: r1=dm(i0,m0); r2=dm(i0,m0); r3=dm(i0,m1); r4=dm(i0,m0); r5=dm(i0,m0); r6=dm(i0,m1); strt: mnmx6(r1, r2, r3, r4, r5, r6); mm6: r1 = dm(i0,m0); mnmx5(r1, r2, r3, r4, r5); mm5: r1 = dm(i0,m0); mnmx4(r1, r2, r3, r4); mm4: r1 = dm(i0,m2); mnmx3(r1, r2, r3); mm3: rts (db); r0 = r2; nop; .ENDSEG;