Bill, the cached version of that page is freely available. Here's the relevant code (not formatted):
{***********************************
* copy the image data to a Array of integer
*
***********************************}
procedure ScanRasterValues (aBmp : TBitmap; xstart, ystart, xsteps, ysteps : Integer; var RvalueArray, GValueArray, BValueArray : TImageFilter);
var ByteLine : Pbytearray;
i, j : integer;
begin
for j := ystart to ystart + ysteps do
begin
ByteLine := aBmp.ScanLine[j];
for i:= xstart to xstart + xsteps do
begin
BvalueArray [i-xstart, j-ystart] := ByteLine[3*i];
GvalueArray [i-xstart, j-ystart] := ByteLine[3*i +1];
RvalueArray [i-xstart, j-ystart] := ByteLine[3*i +2];
end;
end;
end;
function FilterResult (aFilter, bFilter : TImageFilter) : word;
var i,j : Integer;
n,m : Integer;
begin
n := length( aFilter );
m:= n;
for i := 1 to n do
for j := 1 to m do
result := aFilter[i][j] * bfilter[i,j];
end;
{******************************************************************************
* Input:
* bmp1, bm2 : TBitMap
* ImageFilter : Image Filter array , size FilterSize x FilterSize
* assume filter size is always even !! 1,3,5, ...
*
* OutPut:
*
*
*
*******************************************************************************}
procedure ReduceNoise_AnyFilter (bmp1, bmp2 : TBitMap; aImageFilter : TImageFilter );
var P1 : pbytearray; // from Image 1
FilterSize : Integer; // 3,5,7
FilterSize2 : Integer; // 2,3,4
i,j,jj : Integer;
RvalueArray : TImageFilter; // Red Color Values
GvalueArray : TImageFilter; // Green Color Values
BvalueArray : TImageFilter; // Blue Color Values
begin
// the filter size
FilterSize := length(aImageFilter);
FilterSize2 := round((FilterSize-1)/2 +1);
// adjust dyn. arrays
setlength ( RvalueArray, Filtersize, Filtersize );
setlength ( GvalueArray, Filtersize, Filtersize );
setlength ( BvalueArray, Filtersize, Filtersize );
// Loop through all Pixels
for j := FilterSize2 to bmp1.Height - (FilterSize2 +1) do
begin
p1 := bmp1.ScanLine[j];
for i := FilterSize2 to bmp1.Width - (FilterSize2+1) do
begin
ScanRasterValues (bmp2, i-FilterSize2, j-FilterSize2, FilterSize, FilterSize,RvalueArray, GValueArray, BValueArray );
p1[3 * i ] := FilterResult ( aImageFilter,BvalueArray ) ; // Bvalue
p1[3 * i + 1 ] := FilterResult ( aImageFilter,GvalueArray ) ; // Gvalue
p1[3 * i + 2 ] := FilterResult ( aImageFilter,RvalueArray ) ; // Rvalue
end; // i := ...
end; // j:= ..
end;
http://en.wikipedia.org/wiki/Median_filter (also see links at page bottom)
http://www.student.kuleuven.be/~m0216922/CG/filtering.html
http://www.miszalok.de/Samples/IP/median_filter/median_filter.pdf
http://www.librow.com/articles/article-1/appendix-a-1 (look for the implementation file link)
http://ndevilla.free.fr/median/median.pdf
-Uwe