From:	CSBVAX::CSBVAX::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 15-FEB-1989 07:46
To:	MRGATE::"ARISIA::EVERHART"
Subj:	Re: image processing programs


Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Wed, 15 FEB 89 03:23:41 PDT
Received: from NSS.Cs.Ucl.AC.UK by KL.SRI.COM with TCP; Wed, 15 Feb 89 02:59:04 PST
Received: from vaxb.rhbnc.ac.uk by NSS.Cs.Ucl.AC.UK   via Janet with NIFTP
           id aa04808; 15 Feb 89 10:29 GMT
Date:		15-FEB-1989 10:54:44 GMT
From:		UHAP058%vaxb.rhbnc.ac.uk@NSS.Cs.Ucl.AC.UK
To:		Info-Vax <@NSS.Cs.Ucl.AC.UK:Info-Vax@kl.sri.com>
Subject:        Re: image processing programs
Sender:         "JANET UHAP058@UK.AC.RHBNC.VAXB" <UHAP058%vaxb.rhbnc.ac.uk@NSS.Cs.Ucl.AC.UK>
Message-Id:     <206019B7_000B640C.00920698FF270A20$12_2@UK.AC.RHBNC.VAXB>
Originally-to:  $INFO-VAX
Originally-from:UHAP058      "Zahid Hussain"
Mailer:         Janet_Mailshr V3.3a (02-Feb-1989)


Hi,
   Included are some simple examples of median filtering functions
(unfortunately, all the examples are in VAX PASCAL). All these routines work 
on a 256x256 images. The type definition file is given below.

{==========================================================================}
[ENVIRONMENT('mvg$head.pen')]
MODULE mvg$head;
CONST
    low_x = 0;
    low_y = 0;
    high_x = 256;
    high_y = 256;
    Array_Area = 65536;
    term = 'TT:';
    ESC = chr(27);
    CSI = chr(155);


TYPE
    VECTOR = array[0..255] of integer;
    RVECTOR = array[0..255] of real;
    KERNEL = array[-1..1,-1..1] of integer;
    BYTE = [BYTE(1)]0..255;
    WORD = [WORD]0..65535;
    string = varying [255] of char;
    filetype = varying [127] of char;

    BINARY = array[low_y..high_y, low_x..high_x] of [BIT(1)] boolean;
    IMAGE = array[low_x..high_x, low_y..high_y] of integer;
    IMAGE_PTR = ^IM_TYPE;
    IM_TYPE = RECORD
                  name : string;
                  im_flag : BYTE;
                  prot : BYTE;
                  pixel : IMAGE;
              END;
    BINARY_PTR = ^BINARY;
END.
{==========================================================================}

The first routine median filters an image using a 3x3 window. The median value 
within the window is chosen by picking the 5th element after a bubble sort.

{==========================================================================}
[INHERIT('mvg$head')]
MODULE mvg$median3;

procedure bubble_sort(var x : VECTOR; n : integer);
var
    pass,i,tmp : integer;
    swap : boolean;
begin
    swap := TRUE;
    pass := 1;
    while((pass <= n-1) AND (swap)) do
    begin
        swap := FALSE;
        for i := 1 to n-pass do
            if(x[i] > x[i+1]) then
            begin
                swap := TRUE;
                tmp := x[i];
                x[i] := x[i+1];
                x[i+1] := tmp;
            end;
        pass := pass + 1;
    end;
end;

[global]
function mvg$median3(x : IMAGE) : IMAGE;
var
    imout : IMAGE;
    i,j,t,t1,t2 : integer;
    tmp : VECTOR;
begin
    for i := low_y+1 to high_y-1 do
    begin
        for j := low_x+1 to high_x-1 do
        begin
            t := 0;
            for t1 := -1 to 1 do
            begin
                for t2 := -1 to 1 do
                begin
                    t := t + 1;
                    tmp[t] := x[i+t1,j+t2];
                end;
            end;
            bubble_sort(tmp,9);
            imout[i,j] := tmp[5];
        end;
    end;
    mvg$median3 := imout;
end;
end.
{==========================================================================}

This routine filters the image over a larger window, the radius of which the 
user can specify. The techique used is to hitogram the pixels within the 
specified window.

{==========================================================================}
[INHERIT('mvg$head')]
MODULE mvg$lmedian_filter;

[global]
function mvg$lmedian_filter(imin : IMAGE;radius : integer) : IMAGE;
var
    imout : IMAGE;
    i,j,t1,t2,t,k,r : integer;
    clreg,hist : ^vector;

procedure clear_reg(var h : VECTOR);
var
    i : integer;
BEGIN
        h := ZERO;
END;

function choose_median(h : VECTOR; t : integer) : integer;
var
    m_val,count : integer;
BEGIN
    count := 0;
    m_val := 0;
    repeat
        count := count + h[m_val];
        m_val := m_val + 1;
    until (count >= t);
    choose_median := m_val-1;
END;

BEGIN
    new(hist); new(clreg);
    clear_reg(clreg^);
    t := sqr(2 * radius + 1) div 2;
    for i := (low_y + radius) to (high_y - radius) do
    BEGIN
        for j := (low_x + radius) to (high_x - radius) do
        BEGIN
            hist^ := clreg^;
            for t1 := -radius to radius do
            BEGIN
                for t2 := -radius to radius do
                BEGIN
                    k := imin[i+t1,j+t2];
                    hist^[k] := hist^[k] + 1;
                END;
            END;
            imout[i,j] := choose_median(hist^,t);
        END;
    END;
{ DEAL WITH THE CORNERS : CORRECT FOR THEM }
    for i := (low_y + radius) to (high_y - radius) do
    BEGIN
        r := 0;
        for j := low_x to (low_x + radius -1) do
        BEGIN
            hist^ := clreg^;
            for t1 := -radius to radius do
            BEGIN
                for t2 := r to radius do
                BEGIN
                     k := imin[i+t1,j+t2];
                    hist^[k] := hist^[k] + 1;
                END;
            END;
            imout[i,j] := choose_median(hist^,t);
            r := r - 1;
        END;
        r := radius - 1;
        for j := (high_x - radius + 1) to high_x do
        BEGIN
            hist^ := clreg^;
            for t1 := -radius to radius do
            BEGIN
                for t2 := -radius to r do
                BEGIN
                    k := imin[i+t1,j+t2];
                    hist^[k] := hist^[k] + 1;
                END;
            END;
            imout[i,j] := choose_median(hist^,t);
            r := r - 1;
        END;
    END;
    dispose(hist); dispose(clreg);
    mvg$lmedian_filter := imout;
END;
END.
{==========================================================================}

Finally a routine to median filter a binary image.

{==========================================================================}
[INHERIT('mvg$head')]
MODULE mvg$median_bin;

[global]
function mvg$median_bin(imin : BINARY; r : integer) : BINARY;
var
    imout : BINARY;
    i,j,t1,t2,neigh,med : integer;
begin
    med := round(((2*r+1) * (2*r+1)) / 2);
    for i := low_y+r to high_y-r do
    begin
        for j := low_x+r to high_x-r do
        begin
            neigh := 0;
            for t1 := -r to r do
            begin
                for t2 := -r to r do
                begin
                    if (imin[i+t1,j+t2] = TRUE) then
                        neigh := neigh + 1;
                end;
            end;
            if (neigh >= med) then
                imout[i,j] := TRUE
            else
                imout[i,j] := FALSE;
        end;
    end;
    mvg$median_bin := imout;
end;
end.
{==========================================================================}

I have also included a short list of refernces which might be useful. The
list is not very upto date, I've not looked at the current state of image
processing filtering techiques since I did my PhD. The list is in a BiBTeX
format. 

@article{danielsson:median,
    author = "Danielsson, Per-Erik",
    title = "{Getting the Median Faster}",
    journal = "Computer Graphics and Image Processing",
    year = "1981",
    volume = "17",
    pages = "71-78"
}

@article{fitch:median:threshold:decomposition,
    author = "Fitch, J. Patrick and Edward J. Coyle and Neal C. Gallagher",
    title = "{Median Filtering by Threshold Decomposition}",
    journal = "IEEE Trans. Acoustics, Speech, and Signal Processing",
    year = "1984",
    volume = "ASSP-32",
    pages = "1183-1188"
}

@article{ip:potter:lebedev,
    author = "Ip, H. H-S. and D. J. Potter and D. S. Lebedev",
    title = "Impulse noise cleaning by iterative threshold median filtering",
    journal = "Pattern Recognition Letters",
    year = "1983",
    volume = "2",
    pages = "1983"
}

@article{mathews:CLIP7:median,
    author = "K. N. Mathews",
    title = "Large window median filtering on {CLIP7}",
    journal = "Pattern Recognition Letters",
    year = "1983",
    volume = "1",
    pages = "341-346"
}

@article{nodes:gallagher:median,
    author = "Nodes, Thomas A. and Neal C. {Gallagher, Jr.}",
    title = "{Median Filters: Some Modifications and Their Properties}",
    journal = "IEEE Trans. Acoustics, Speech, and Signal Processing",
    year = "1982",
    volume = "ASSP-30",
    pages = "739-746"
}

@article{paler:foglein:illingworth:kittler:median,
    author = "Paler, K. and J. {F\"oglein} and J. Illingworth and J. 
Kittler",
    title = "Local ordered grey levels as an aid to corner detection",
    journal = "Pattern Recognition",
    year = "1984",
    volume = "17",
    pages = "535-543"
}

@article{reeves:SIMD:median,
    author = "Anthony P. Reeves",
    title = "{The Local Median and Other Window Operations on SIMD Computers}",
    journal = "Computer Graphics and Image Processing",
    year = "1982",
    volume = "19",
    pages = "165-178"
}

@article{scoller:weidner:huang:median,
    author = "Irwin Scollar and Bernd Weidner and Thomas S. Huang",
    title = "{Image Enhancement Using the Median and the Interquartile 
Distance}",
    journal = "Computer Vision, Graphics, and Image Processing",
    year = "1984",
    volume = "25",
    pages = "236-251"
}

@inproceedings{davies:7icpr:590,
    author = "E. R. Davies",
    title = "The median filter: an appraisal and a new truncated version",
    booktitle = "Seventh International Conf. on Pattern Recognition",
    publisher = "IEEE Computer Society Press",
    year = "1984",
    address = "Montreal, Canada",
    pages = "590-592",
    extra = "mode mean"
}

@article{davies:filters:1988,
    author = "E. R. Davies",
    title = "On the noise suppression and image enhancement characteristics of 
the median, truncated median and mode filters",
    journal = "Pattern Recognition Letters",
    year = "1988",
    volume = "7",
    pages = "87-97",
    extra = ""
}

@article{Median:VLSI:1D:1983,
    author = "K Oflazer",
    title = "Design and implementation od a single-chip 1D Median filter",
    journal = "IEEE transactions on acoustics, speech, and signsl processing",
    year = "1983",
    volume = "31",
    pages = "1164-1168"
}


I hope this is of some help. If you need more help or informations contact me 
by e-mail and I'll see what i can do.
					** Zahid.

=============================================================================
Zahid Hussain, PhD
Royal Holloway & Bedford New College, 
University of London		E-mail: Janet: uhap058@uk.ac.rhbnc.vaxb
Egham Hill, Egham			Earn/Bitnet: uhap058@vaxb.rhbnc.ac.uk
Surrey Tw20 0EX
England, U.K.

