unit filterStandardDeviation;
(* ***** BEGIN LICENSE BLOCK *****
* Copyright (C) 2004 Durand Emmanuel
* Copyright (C) 2004 Burgel Eric
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact :
* filters@edurand.com
* filters@burgel.com
*
* ***** END LICENSE BLOCK ***** *)
{
edurand (filters@edurand.com)
}
interface
uses
filter, fparameters, image, SysUtils;
type
TFilterStandardDeviation = class(TFilter)
public
constructor Create; override;
destructor Destroy; override;
procedure Run(); override;
private
pourcentageEcarttype : TParameterInteger;
parameterImageIn, parameterImageOut : TParameterImage;
parameterOutputColor : TParameterString;
parameterShowOnlyROI : TParameterBoolean;
imgIn, imgOut : PBitmap32 ;
showOnlyROI : boolean;
procedure _run();
end;
implementation
uses
imageIO, Math;
constructor TFilterStandardDeviation.Create;
begin
inherited;
parameterImageIn := addParameterImage( 'inImage', 'explication...' );
parameterImageOut := addParameterImage( 'outImage', 'explication...' );
pourcentageEcarttype := addParameterInteger( 'percentStandardDeviation', 'bornInf/Sup=moyenne-/+pourcentageEcarttype', 1, 500, 250 );
parameterOutputColor := addParameterString( 'outputColor', 'UNCHANGED/WHITE','WHITE' );
parameterShowOnlyROI := addParameterBoolean( 'showOnlyROI','true/false', false );
end;
destructor TFilterStandardDeviation.Destroy;
begin
end;
procedure TFilterStandardDeviation.Run();
begin
imgIn := parameterImageIn.Image ;
imgOut := parameterImageOut.Image ;
showOnlyROI := parameterShowOnlyROI.Value;
if (imgIn<>nil) and (imgOut<>nil) then begin
image.eraseImage( imgOut );
_run();
end;
end;
procedure TFilterStandardDeviation._run();
var
PSrc : PColor32Array;
PDest : PColor32Array;
trow, tcol : Integer;
trowmax, tcolmax : Integer;
maxX, maxY : Integer;
x, y : Integer;
tIntensity, tIntensityCount, tIntensityMoyenne : Integer;
variance, ecarttype : Single;
delta : Integer;
borneInf, borneSup : Integer;
mEcarttype : Single;
bOutpuColorWhite : Boolean;
begin
bOutpuColorWhite:=True;
if parameterOutputColor.Value='UNCHANGED' then bOutpuColorWhite:=False;
maxX := scanWidth(imgIn)-1 ;
maxY := scanHeight(imgIn)-1 ;
if (maxX>0) and (maxY>0) then begin
// calcul intensity moyenne
tIntensityCount:=0;
tIntensityMoyenne:=0;
for y:=0 to maxY do Begin
pSrc := scanLine(imgIn, y) ;
for x:=0 to maxX do Begin
tIntensity:=Intensity(pSrc^[0]);
Inc(tIntensityCount);
Inc(tIntensityMoyenne,tIntensity);
inc(pSrc);
end;
end;
tIntensityMoyenne:=tIntensityMoyenne div tIntensityCount;
// calcul variance
variance:=0;
for y:=0 to maxY do Begin
pSrc := scanLine(imgIn, y) ;
for x:=0 to maxX do Begin
tIntensity:=Intensity(pSrc^[0]);
delta:=tIntensity-tIntensityMoyenne;
variance:=variance+(delta*delta)/tIntensityCount;
inc(pSrc);
end;
end;
// calcul ecart type
ecarttype:=Sqrt(variance);
// calcul standard deviation bounds
mEcarttype:=pourcentageEcarttype.Value/100.;
borneInf:=Round(tIntensityMoyenne-mEcarttype*ecarttype);
borneSup:=Round(tIntensityMoyenne+mEcarttype*ecarttype);
// show
if showOnlyROI=true then begin
for y:=0 to maxY do Begin
pSrc := scanLine(imgIn, y) ;
pDest := scanLine(imgOut, y) ;
for x:=0 to maxX do Begin
tIntensity := Intensity(pSrc^[0]);
if (tIntensity<borneInf) or (tIntensity>borneSup) then begin
if bOutpuColorWhite=True then begin
pDest^[0] := clWhite32;
end else begin
pDest^[0] := image.Gray32(tIntensity);
end;
end;
Inc(pSrc);
Inc(pDest);
end;
end;
end else begin
pSrc := imgIn.Bits;
pDest := imgOut.Bits;
trowmax := parameterImageOut.Image.Height-1;
tcolmax := parameterImageOut.Image.Width-1;
for trow:=0 to trowmax do begin
for tcol:=0 to tcolmax do begin
tIntensity := Intensity(PSrc[trow*tcolmax+tcol]);
if (tIntensity<borneInf) or (tIntensity>borneSup) then begin
if bOutpuColorWhite=True then begin
pDest[trow*tcolmax+tcol] := clWhite32;
end else begin
pDest[trow*tcolmax+tcol] := image.Gray32(tIntensity);
end;
end else begin
pDest[trow*tcolmax+tcol]:=clBlack32;
end;
end;
end;
end;
end;
end;
end.