unit filterProjectionLine;
(* ***** 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, windows;
type
TFilterProjectionLine = class(TFilter)
public
constructor Create; override;
destructor Destroy; override;
procedure Run(); override;
private
parameterInputType : TParameterString;
parameterSegmentArray : TParameterPointer;
parameterImageIn : TParameterImage;
parameterSmooth : TParameterInteger;
outputparameterImageOut : TParameterImage;
outputparameterProjectionLine : TParameterArraySingles;
ouputParameterMaximum : TParameterSingle;
outImage : PBitmap32;
smooth : Integer ;
projectionLine : array of Single;
maximum : Single;
procedure _run();
procedure createProjectionLineFromImage(imgIn : PBitmap32);
procedure createProjectionLineFromSegments(segmentArray : array of TSegment);
procedure computeMaximum();
procedure viewProjectionLine();
end;
implementation
uses
imageIO, Math, divers;
constructor TFilterProjectionLine.Create;
begin
inherited;
parameterInputType:=addParameterString('inputType','input is IMAGE or SEGMENTS','IMAGE');
parameterImageIn:=addParameterImage('inImage','used if inputType=image : the image containing');
parameterSegmentArray:=addParameterPointer('segmentArray','used if inputType=segments : a pointer on a array of TSegment object, provides for example by TFilterBlobExplorer');
parameterSmooth:=addParameterInteger('smooth', 'smooth', 0, 50, 10) ;
outputparameterImageOut := addOutputParameterImage('outImage', 'outImage');
outputparameterProjectionLine:=addOutputParameterArraySingles('projectionLine','the projection of each point on a line, array of type Single');
ouputParameterMaximum := addOutputParameterSingle('maximum', 'computed maximum') ;
end;
destructor TFilterProjectionLine.Destroy;
begin
image.freeImage(outImage);
inherited;
end;
procedure TFilterProjectionLine.run();
begin
if (parameterImageIn.Image<>nil) then begin
_run();
end;
end;
procedure TFilterProjectionLine._run();
var
segmentArray : array of TSegment;
begin
segmentArray := nil;
smooth := parameterSmooth.Value;
if parameterInputType.Value='IMAGE' then begin
createProjectionLineFromImage(parameterImageIn.Image);
end else begin
segmentArray:=parameterSegmentArray.Value;
createProjectionLineFromSegments(segmentArray);
end;
computeMaximum();
viewProjectionLine();
setOutputParameterImage('outImage',outImage);
setOutputParameterArraySingles('projectionLine',projectionLine);
setOutputParameterSingle('maximum', maximum);
end;
procedure TFilterProjectionLine.createProjectionLineFromImage(imgIn : PBitmap32);
var
projectLineLength : Integer;
x, y, maxX, maxY : Integer;
pSrc : PColor32Array;
intensity : Integer;
roi : TRect;
index : Integer;
begin
roi := getRegionOfInterest(imgIn);
maxX := scanWidth(imgIn)-1;
maxY := scanHeight(imgIn)-1;
// search projectLine length
projectLineLength:=maxX+1;
// create array
setLength(projectionLine, projectLineLength);
for x:=0 to Length(projectionLine)-1 do projectionLine[x] := 0;
// fill array
for y:=0 to maxY do begin
pSrc := scanLine(imgIn, y);
for x:=0 to maxX do begin
intensity:=image.Intensity(pSrc^[0]);
index:=x-roi.Left;
projectionLine[index]:=projectionLine[index]+intensity/255;
inc(pSrc);
end;
end;
// smooth array
divers.smoothIt(projectionLine, smooth) ;
end;
procedure TFilterProjectionLine.createProjectionLineFromSegments(segmentArray : array of TSegment);
var
x : integer;
i, iMax : Integer;
index : integer;
segment : TSegment;
projectLineLength : Integer;
xMin, xMax : Single;
scale : Extended;
border : Integer;
begin
scale:=10;
border:=10;
// search projectLine length
xMin:=MaxSingle; xMax:=-1;
iMax:=Length(segmentArray)-1;
for i:=0 to iMax do begin
segment := segmentArray[i];
xMin:=Min(xMin,segment.p1.x);
xMax:=Max(xMax,segment.p1.x);
end;
projectLineLength:=Floor((xMax-xMin+border*2)*10)+1;
// create array
setLength(projectionLine, projectLineLength);
for x:=0 to Length(projectionLine)-1 do projectionLine[x] := 0;
// fill array
iMax:=Length(segmentArray)-1;
for i:=0 to iMax do begin
segment := segmentArray[i];
index := Floor((segment.p1.x-xMin+border)*10);
projectionLine[index]:=projectionLine[index]+scale;
end;
// smooth array
divers.smoothIt(projectionLine, smooth) ;
end;
procedure TFilterProjectionLine.computeMaximum();
var
x : Integer;
begin
maximum:=-1;
for x:=0 to Length(projectionLine)-1 do Begin
maximum:=Max(maximum,projectionLine[x]);
end;
end;
procedure TFilterProjectionLine.viewProjectionLine();
var
x, y : integer;
begin
image.freeImage(outImage);
outImage:=image.createImage(Length(projectionLine),200);
for x:=0 to Length(projectionLine)-1 do Begin
y := Floor(projectionLine[x]);
if y >= 200 then y := 199 ;
image.drawLine(outImage, x, 199, x, 199-y, clRed32);
end;
image.drawLine(outImage,0,199-maximum,Length(projectionLine)-1,199-maximum,clYellow32);
end;
end.