unit filterNormalize;
(* ***** 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 ***** *)
{
eburgel (filters@burgel.com)
}
{ ***********************************************************
Combine all images from a Stack into a single image.
*************************************************************}
interface
uses
filter, fparameters, image;
type
TFilterNormalize = class(TFilter)
public
constructor Create(); override;
procedure Run(); override;
private
parameterImageIn : TParameterImage;
parameterImageRef : TParameterImage;
parameterImageOut : TParameterImage;
inImage, normImage, outImage : PBitmap32 ;
procedure _run();
end;
implementation
uses
imageIO ;
constructor TFilterNormalize.Create() ;
begin
inherited Create() ;
parameterImageIn := addParameterImage('inImage', 'inImage') ;
parameterImageRef := addParameterImage('refImage', 'reference image') ;
parameterImageOut := addParameterImage('outImage', 'outImage');
end;
procedure TFilterNormalize.run();
begin
inImage := parameterImageIn.Image ;
normImage := parameterImageRef.Image ;
outImage := parameterImageOut.Image ;
if (inImage<>nil) and (normImage<>nil) and (outImage<>nil) then begin
_run();
end;
end;
procedure TFilterNormalize._run();
Var
i : Integer ;
W, H : Cardinal ;
color : TColorRec ;
pSrc : PColor32Array ;
pDst : PColor32Array ;
pNorm : PColor32Array ;
increments : Array of Array of Integer ;
x, y, Nw, Nh, Nx, Ny : Cardinal ;
B1x, B2x, B1y, B2y : Cardinal ;
R, G, B : Cardinal ;
sR, sG, sB : Cardinal ;
lum, lumA, lumB, lum1, lum2, lum3, lum4 : Integer ;
Value : Integer ;
cx, cy : integer ;
begin
W := inImage.Width ;
H := inImage.Height ;
Nw := normImage.Width ;
Nh := normImage.Height ;
For Ny := 0 to Nh-2 do Begin
pNorm := scanLine(normImage, Ny) ;
B1y := Ny*(H-1) div (Nh-1) ;
B2y := (Ny+1)*(H-1) div (Nh-1) ;
For Nx := 0 to Nw-2 do Begin
B1x := Nx*(W-1) div (Nw-1) ;
B2x := (Nx+1)*(W-1) div (Nw-1) ;
Lum1 := Luminosity(pNorm[Nx]) ;
Lum2 := Luminosity(pNorm[Nx+1]);
Lum3 := Luminosity(pNorm[Nx+Nw]) ;
Lum4 := Luminosity(pNorm[Nx+Nw+1]) ;
// interpolation entre les quatres points
For y := B1y to B2y do Begin
pSrc := scanLine(inImage, y) ;
pDst := scanLine(outImage, y) ;
inc(pSrc, B1x) ;
inc(pdst, B1x) ;
cy := (y-B1y)* $10000 div (B2y-B1y) ;
For x := B1x to B2x do Begin
cx := (x-B1x)* $10000 div (B2x-B1x) ;
lumA := (lum1*($10000-cx) + lum2*cx + $8000) div $10000 ;
lumB := (lum3*($10000-cx) + lum4*cx + $8000) div $10000 ;
lum := (lumA*($10000-cy) + lumB*cy + $8000) div $10000 ;
// red
value := TColorRec(pSrc[0]).Red + 127 - lum ;
if value > 255 then value := 255 else if value < 0 Then Value := 0 ;
TColorRec(pDst[0]).Red := value ;
// Green
value := TColorRec(pSrc[0]).green + 127 - lum ;
if value > 255 then value := 255 else if value < 0 Then Value := 0 ;
TColorRec(pDst[0]).green := value ;
// Blue
value := TColorRec(pSrc[0]).blue + 127 - lum ;
if value > 255 then value := 255 else if value < 0 Then Value := 0 ;
TColorRec(pDst[0]).blue := value ;
inc(pSrc) ;
inc(pDst) ;
End ;
End ;
//inc(pNorm) ;
End ;
End ;
//parameterImageOut.Image := outImage ;
end;
end.