procedure Apply(const bitmap: IImageAdapter); override; overload;
procedure FilterDilate.Apply(bitmap: BitmapGray); var x, y: integer; newData: TByteMatrix; kernel: KernelData; mTop, mLeft, mRight, mBottom: byte; begin SetLength(newData, bitmap.Info.Height, bitmap.Info.Width); for x := 0 to bitmap.Info.Width - 1 do for y := 0 to bitmap.Info.Height - 1 do begin bitmap.GetKernel(_kernelSize, x, y, mTop, mBottom, mLeft, mRight, kernel); newData[y, x] := kernel.Min; end; SetLength(kernel.Kernel, 0, 0); bitmap.SetData(newData); end;
procedure FilterDilate.Apply(bitmap: BitmapBW); var x, y: integer; newData: TByteMatrix; kernel: KernelData; mTop, mLeft, mRight, mBottom: byte; w, h: Longword; begin SetLength(newData, bitmap.Info.Height, bitmap.Info.Width); for x := 0 to bitmap.Info.Width - 1 do for y := 0 to bitmap.Info.Height - 1 do begin bitmap.GetKernel(_kernelSize, x, y, mTop, mBottom, mLeft, mRight, kernel); w := _kernelSize - mRight - mLeft; h := _kernelSize - mTop - mBottom; if kernel.Sum < (w * h) then newData[y, x] := bitmap.FORECOLOR else newData[y, x] := bitmap.BACKCOLOR; end; SetLength(kernel.Kernel, 0, 0); bitmap.SetData(newData); end;
constructor FilterDilate.Create(const kernelSize: byte); begin if not Odd(kernelSize) then raise Exception.Create('Kernel size must be odd number!');
_kernelSize := kernelSize; end;
procedure FilterErode.Apply(bitmap: BitmapGray); var x, y: integer; newData: TByteMatrix; kernel: KernelData; mTop, mLeft, mRight, mBottom: byte; begin SetLength(newData, bitmap.Info.Height, bitmap.Info.Width); for x := 0 to bitmap.Info.Width - 1 do for y := 0 to bitmap.Info.Height - 1 do begin bitmap.GetKernel(_kernelSize, x, y, mTop, mBottom, mLeft, mRight, kernel); newData[y, x] := kernel.Max; end; SetLength(kernel.Kernel, 0, 0); bitmap.SetData(newData); end;
procedure FilterErode.Apply(bitmap: BitmapBW); var x, y: integer; newData: TByteMatrix; kernel: KernelData; mTop, mLeft, mRight, mBottom: byte; begin SetLength(newData, bitmap.Info.Height, bitmap.Info.Width); for x := 0 to bitmap.Info.Width - 1 do for y := 0 to bitmap.Info.Height - 1 do begin bitmap.GetKernel(_kernelSize, x, y, mTop, mBottom, mLeft, mRight, kernel); if kernel.Sum = 0 then newData[y, x] := bitmap.FORECOLOR else newData[y, x] := bitmap.BACKCOLOR; end; SetLength(kernel.Kernel, 0, 0); bitmap.SetData(newData); end;
constructor FilterErode.Create(const kernelSize: byte); begin if not Odd(kernelSize) then raise Exception.Create('Kernel size must be odd number!'); _kernelSize := kernelSize; end;
procedure FilterHitAndMiss.Apply(bitmap: BitmapGray); begin inherited;
end;
procedure FilterHitAndMiss.Apply(bitmap: BitmapBW); const s1: StructuredElementData = ( (_X_, _I_, _X_), (_O_, _I_, _I_), (_O_, _O_, _X_));
s2: StructuredElementData = ( (_X_, _I_, _X_), (_I_, _I_, _O_), (_X_, _O_, _O_));
s3: StructuredElementData = ( (_X_, _O_, _O_), (_I_, _I_, _O_), (_X_, _I_, _X_));
s4: StructuredElementData = ( (_O_, _O_, _X_), (_O_, _I_, _I_), (_X_, _I_, _X_));
var x, y: integer; newData: TByteMatrix; kernel: KernelData; mTop, mLeft, mRight, mBottom: byte; begin SetLength(newData, bitmap.Info.Height, bitmap.Info.Width); for x := 0 to bitmap.Info.Width - 1 do for y := 0 to bitmap.Info.Height - 1 do begin bitmap.GetKernel(3, x, y, mTop, mBottom, mLeft, mRight, kernel); if (mTop + mBottom + mLeft + mRight = 0) then begin if StructuredElement.Matches(s1, kernel.Kernel, _foreColor, _backColor) or StructuredElement.Matches(s2, kernel.Kernel, _foreColor, _backColor) or StructuredElement.Matches(s3, kernel.Kernel, _foreColor, _backColor) or StructuredElement.Matches(s4, kernel.Kernel, _foreColor, _backColor) then newData[y, x] := _foreColor else newData[y, x] := _backColor end; end; SetLength(kernel.Kernel, 0, 0); bitmap.SetData(newData); end;
constructor FilterHitAndMiss.Create(img: IImageAdapter); begin _foreColor := img.FORECOLOR; _backColor := img.BACKCOLOR; end;
procedure FilterThin.Apply(bitmap: BitmapGray); begin inherited;
end;
procedure FilterThin.Apply(bitmap: BitmapBW); var i, j, k, l, count, count2, num_transitions, transitions, WIDTH, HEIGHT: integer; temp_array, temp: TByteMatrix;
begin WIDTH := bitmap.Info.Width; HEIGHT := bitmap.Info.Height; SetLength(temp_array, HEIGHT, WIDTH); SetLength(temp, HEIGHT, WIDTH); for i := 1 to WIDTH - 2 do begin for j := 1 to HEIGHT - 2 do begin count := 0; num_transitions := 0;
// check for N(p) if (bitmap.GetPixel(i, j) = _foreColor) then begin if (bitmap.GetPixel(i - 1, j - 1) <> _backColor) then Inc(count); if (bitmap.GetPixel(i, j - 1) <> _backColor) then Inc(count); if (bitmap.GetPixel(i + 1, j - 1) <> _backColor) then Inc(count); if (bitmap.GetPixel(i + 1, j) <> _backColor) then Inc(count); if (bitmap.GetPixel(i - 1, j) <> _backColor) then Inc(count); if (bitmap.GetPixel(i + 1, j + 1) <> _backColor) then Inc(count); if (bitmap.GetPixel(i, j + 1) <> _backColor) then Inc(count); if (bitmap.GetPixel(i - 1, j + 1) <> _backColor) then Inc(count);
if (count <> 8) then begin // 2 <= N(p) <= 6 if ((count >= 2) and (count <= 6)) then begin if (bitmap.GetPixel(i - 1, j) = _backColor) and (bitmap.GetPixel(i - 1, j + 1) = _foreColor) then inc(num_transitions); if (bitmap.GetPixel(i - 1, j + 1) = _backColor) and (bitmap.GetPixel(i, j + 1) = _foreColor) then inc(num_transitions); if (bitmap.GetPixel(i, j + 1) = _backColor) and (bitmap.GetPixel(i + 1, j + 1) = _foreColor) then inc(num_transitions); if (bitmap.GetPixel(i + 1, j + 1) = _backColor) and (bitmap.GetPixel(i + 1, j) = _foreColor) then inc(num_transitions); if (bitmap.GetPixel(i + 1, j) = _backColor) and (bitmap.GetPixel(i + 1, j - 1) = _foreColor) then inc(num_transitions); if (bitmap.GetPixel(i + 1, j - 1) = _backColor) and (bitmap.GetPixel(i, j - 1) = _foreColor) then inc(num_transitions); if (bitmap.GetPixel(i, j - 1) = _backColor) and (bitmap.GetPixel(i - 1, j - 1) = _foreColor) then inc(num_transitions); if (bitmap.GetPixel(i - 1, j - 1) = _backColor) and (bitmap.GetPixel(i - 1, j) = _foreColor) then inc(num_transitions);
//S(p) := 1 if (num_transitions = 1) then begin // if p2 * p4 * p6 := 0 if (bitmap.GetPixel(i - 1, j) = _backColor) or (bitmap.GetPixel(i, j + 1) = 0) or (bitmap.GetPixel(i + 1, j) = _backColor) then begin // if p4 * p6 * p8 := 0 if (bitmap.GetPixel(i, j + 1) = _backColor) or (bitmap.GetPixel(i + 1, j) = 0) or (bitmap.GetPixel(i, j - 1) = _backColor) then begin temp_array[j, i] := _backColor; end else temp_array[j, i] := _foreColor; end else temp_array[j, i] := _foreColor; end else temp_array[j, i] := _foreColor; end else temp_array[j, i] := _foreColor; end else temp_array[j, i] := _foreColor; end else temp_array[j, i] := _backColor; end; end; //copy thinned bitmap back to original bitmap.SetData(temp_array);
// step 2 of the thinning algorithm for k := 1 to WIDTH - 2 do begin for l := 1 to HEIGHT - 2 do begin count2 := 0; transitions := 0; if (bitmap.GetPixel(k, l) = _foreColor) then begin if (bitmap.GetPixel(k - 1, l - 1) <> _backColor) then Inc(count2); if (bitmap.GetPixel(k, l - 1) <> _backColor) then Inc(count2); if (bitmap.GetPixel(k + 1, l - 1) <> _backColor) then Inc(count2); if (bitmap.GetPixel(k + 1, l) <> _backColor) then Inc(count2); if (bitmap.GetPixel(k - 1, l) <> _backColor) then Inc(count2); if (bitmap.GetPixel(k + 1, l + 1) <> _backColor) then Inc(count2); if (bitmap.GetPixel(k, l + 1) <> _backColor) then Inc(count2); if (bitmap.GetPixel(k - 1, l + 1) <> _backColor) then Inc(count2);
if (count2 <> 8) then begin if (count2 >= 2) and (count2 <= 6) then begin if (bitmap.GetPixel(k - 1, l) = _backColor) and (bitmap.GetPixel(k - 1, l + 1) = _foreColor) then Inc(transitions); if (bitmap.GetPixel(k - 1, l + 1) = _backColor) and (bitmap.GetPixel(k, l + 1) = _foreColor) then Inc(transitions); if (bitmap.GetPixel(k, l + 1) = _backColor) and (bitmap.GetPixel(k + 1, l + 1) = _foreColor) then Inc(transitions); if (bitmap.GetPixel(k + 1, l + 1) = _backColor) and (bitmap.GetPixel(k + 1, l) = _foreColor) then Inc(transitions); if (bitmap.GetPixel(k + 1, l) = _backColor) and (bitmap.GetPixel(k + 1, l - 1) = _foreColor) then Inc(transitions); if (bitmap.GetPixel(k + 1, l - 1) = _backColor) and (bitmap.GetPixel(k, l - 1) = _foreColor) then Inc(transitions); if (bitmap.GetPixel(k, l - 1) = _backColor) and (bitmap.GetPixel(k - 1, l - 1) = _foreColor) then Inc(transitions); if (bitmap.GetPixel(k - 1, l - 1) = _backColor) and (bitmap.GetPixel(k - 1, l) = _foreColor) then Inc(transitions);
if (transitions = 1) then begin // if p2 * p4 * p8 := 0 if (bitmap.GetPixel(k - 1, l) = _backColor) or (bitmap.GetPixel(k, l + 1) = 0) or (bitmap.GetPixel(k, l - 1) = _backColor) then begin // if p2 * p6 * p8 if (bitmap.GetPixel(k - 1, l) = _backColor) or (bitmap.GetPixel(k + 1, l) = 0) or (bitmap.GetPixel(k, l - 1) = _backColor) then begin temp[l, k] := _backColor; end else temp[l, k] := _foreColor; end else temp[l, k] := _foreColor; end else temp[l, k] := _foreColor; end else temp[l, k] := _foreColor; end else temp[l, k] := _foreColor; end else temp[l, k] := _backColor; end; end; bitmap.SetData(temp); SetLength(temp_array, 0, 0);
end;
constructor FilterThin.Create(img: IImageAdapter); begin _foreColor := img.FORECOLOR; _backColor := img.BACKCOLOR; end;
procedure FilterSmooth.Apply(bitmap: BitmapGray); begin inherited;
end;
procedure FilterSmooth.Apply(bitmap: BitmapBW); var w, h, sum: integer; map: BitmapBW;
begin map := bitmap; for h := 1 to map.Info.Width - 2 do for w := 1 to map.Info.Height - 2 do begin //? 0 ? //0 1 0 //? 0 ? sum := (map.GetPixel(h - 1, w) + map.GetPixel(h, w - 1) + map.GetPixel(h, w + 1) + map.GetPixel(h + 1, w)); if sum = 0 then map.SetPixel(h, w, _foreColor) else if sum = 4 then //noise removal map.SetPixel(h, w, _backColor);
////////////////////// FILL ////////////////////////////////////
//? 0 ? //0 1 0 //1 1 0
if (map.GetPixel(h - 1, w) = _foreColor) and (map.GetPixel(h, w - 1) = _foreColor) and (map.GetPixel(h, w + 1) = _foreColor) and (map.GetPixel(h + 1, w + 1) = _foreColor) and (map.GetPixel(h + 1, w - 1) = _backColor) and (map.GetPixel(h + 1, w) = _backColor) then map.SetPixel(h, w, _foreColor);
//1 0 ? //1 1 0 90 //0 0 ?
if (map.GetPixel(h - 1, w - 1) = _backColor) and (map.GetPixel(h - 1, w) = _foreColor) and (map.GetPixel(h, w - 1) = _backColor) and (map.GetPixel(h, w + 1) = _foreColor) and (map.GetPixel(h + 1, w - 1) = _foreColor) and (map.GetPixel(h + 1, w) = _foreColor) then map.SetPixel(h, w, _foreColor);
// 0 1 1 // 0 X 0 180 // ? 0 ?
if (map.GetPixel(h - 1, w - 1) = _foreColor) and (map.GetPixel(h - 1, w) = _backColor) and (map.GetPixel(h - 1, w + 1) = _backColor) and (map.GetPixel(h, w - 1) = _foreColor) and (map.GetPixel(h, w + 1) = _foreColor) and (map.GetPixel(h + 1, w) = _foreColor) then map.SetPixel(h, w, _foreColor);
//? 0 0 //0 X 1 270 //? 0 1
if (map.GetPixel(h - 1, w) = _foreColor) and (map.GetPixel(h - 1, w + 1) = _foreColor) and (map.GetPixel(h, w - 1) = _foreColor) and (map.GetPixel(h, w + 1) = _backColor) and (map.GetPixel(h + 1, w) = _foreColor) and (map.GetPixel(h + 1, w + 1) = _backColor) then map.SetPixel(h, w, _foreColor);
//////////////// DELETE /////////////////////////
//1 1 ? //1 0 0 //1 1 0
if (map.GetPixel(h - 1, w - 1) = _backColor) and (map.GetPixel(h - 1, w) = _backColor) and (map.GetPixel(h, w - 1) = _backColor) and (map.GetPixel(h, w + 1) = _foreColor) and (map.GetPixel(h + 1, w - 1) = _backColor) and (map.GetPixel(h + 1, w) = _backColor) and (map.GetPixel(h + 1, w + 1) = _foreColor) then map.SetPixel(h, w, _backColor);
//1 1 1 //1 0 1 90 //0 0 ?
if (map.GetPixel(h - 1, w - 1) = _backColor) and (map.GetPixel(h - 1, w) = _backColor) and (map.GetPixel(h - 1, w + 1) = _backColor) and (map.GetPixel(h, w - 1) = _backColor) and (map.GetPixel(h, w + 1) = _backColor) and (map.GetPixel(h + 1, w - 1) = _foreColor) and (map.GetPixel(h + 1, w) = _foreColor) then map.SetPixel(h, w, _backColor);
//0 1 1 //0 0 1 //? 1 1 180
if (map.GetPixel(h - 1, w - 1) = _foreColor) and (map.GetPixel(h - 1, w) = _backColor) and (map.GetPixel(h - 1, w + 1) = _backColor) and (map.GetPixel(h, w - 1) = _foreColor) and (map.GetPixel(h, w + 1) = _backColor) and (map.GetPixel(h + 1, w) = _backColor) and (map.GetPixel(h + 1, w + 1) = _backColor) then map.SetPixel(h, w, _backColor);
//? 0 0 //1 0 1 //1 1 1 270
if (map.GetPixel(h - 1, w) = _foreColor) and (map.GetPixel(h - 1, w + 1) = _foreColor) and (map.GetPixel(h, w - 1) = _backColor) and (map.GetPixel(h, w + 1) = _backColor) and (map.GetPixel(h + 1, w - 1) = _backColor) and (map.GetPixel(h + 1, w) = _backColor) and (map.GetPixel(h + 1, w + 1) = _backColor) then map.SetPixel(h, w, _backColor);
//1 1 1 //1 0 0 //1 1 ?
if (map.GetPixel(h - 1, w - 1) = _backColor) and (map.GetPixel(h - 1, w) = _backColor) and (map.GetPixel(h - 1, w + 1) = _backColor) and (map.GetPixel(h, w - 1) = _backColor) and (map.GetPixel(h, w + 1) = _foreColor) and (map.GetPixel(h + 1, w - 1) = _backColor) and (map.GetPixel(h + 1, w) = _backColor) then map.SetPixel(h, w, _backColor);
//1 1 1 //1 0 1 90 //? 0 1
if (map.GetPixel(h - 1, w - 1) = _backColor) and (map.GetPixel(h - 1, w) = _backColor) and (map.GetPixel(h - 1, w + 1) = _backColor) and (map.GetPixel(h, w - 1) = _backColor) and (map.GetPixel(h, w + 1) = _backColor) and (map.GetPixel(h + 1, w) = _foreColor) and (map.GetPixel(h + 1, w + 1) = _backColor) then map.SetPixel(h, w, _backColor);
//? 1 1 //0 0 1 180 //1 1 1
if (map.GetPixel(h - 1, w) = _backColor) and (map.GetPixel(h - 1, w + 1) = _backColor) and (map.GetPixel(h, w - 1) = _foreColor) and (map.GetPixel(h, w + 1) = _backColor) and (map.GetPixel(h + 1, w - 1) = _backColor) and (map.GetPixel(h + 1, w) = _backColor) and (map.GetPixel(h + 1, w + 1) = _backColor) then map.SetPixel(h, w, _backColor);
//1 0 ? //1 0 1 270 //1 1 1
if (map.GetPixel(h - 1, w - 1) = _backColor) and (map.GetPixel(h - 1, w) = _foreColor) and (map.GetPixel(h, w - 1) = _backColor) and (map.GetPixel(h, w + 1) = _backColor) and (map.GetPixel(h + 1, w - 1) = _backColor) and (map.GetPixel(h + 1, w) = _backColor) and (map.GetPixel(h + 1, w + 1) = _backColor) then map.SetPixel(h, w, _backColor); end; end;
procedure FilterDenoise.Apply(bitmap: BitmapGray); var x, y: integer; newData: TByteMatrix; kernel: KernelData; mTop, mLeft, mRight, mBottom: byte; arr: TByteVector; begin SetLength(newData, bitmap.Info.Height, bitmap.Info.Width); SetLength(arr, _kernelSize * _kernelSize); for x := 0 to bitmap.Info.Width - 1 do for y := 0 to bitmap.Info.Height - 1 do begin bitmap.GetKernel(_kernelSize, x, y, mTop, mBottom, mLeft, mRight, kernel); if (mTop + mBottom + mLeft + mRight = 0) then begin ByteMatrix.ToVector(kernel.Kernel, arr); newData[y, x] := ByteVector.Median(arr); end; end; SetLength(kernel.Kernel, 0, 0); SetLength(arr, 0); bitmap.SetData(newData); end;
procedure FilterDenoise.Apply(bitmap: BitmapBW); var w, h, sum: integer; data: TByteMatrix; backCnt, foreCnt: Word; begin backCnt := _backColor * 8; foreCnt := _foreColor * 8; SetLength(data, bitmap.Info.Height, bitmap.Info.Width); for h := 1 to bitmap.Info.Height - 2 do for w := 1 to bitmap.Info.Width - 2 do begin sum := (bitmap.GetPixel(w - 1, h - 1) + bitmap.GetPixel(w, h - 1) + bitmap.GetPixel(w + 1, h - 1) + bitmap.GetPixel(w - 1, h) + bitmap.GetPixel(w + 1, h) + bitmap.GetPixel(w - 1, h + 1) + bitmap.GetPixel(w, h + 1) + bitmap.GetPixel(w + 1, h + 1)); if sum = foreCnt then data[h, w] := _foreColor else if sum = backCnt then data[h, w] := _backColor else data[h, w] := bitmap.GetPixel(w, h); end; bitmap.SetData(data);
end;
constructor FilterDenoise.Create(foreColor: byte = 0); begin _kernelSize := 3; end;
constructor FilterSmooth.Create(img: IImageAdapter); begin _foreColor := img.FORECOLOR; _backColor := img.BACKCOLOR; end;