unit filterGranularityExplorer;
(* ***** 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
TFilterGranularityExplorer = class(TFilter)
public
constructor Create; override;
destructor Destroy; override;
procedure Run(); override;
procedure setParameterImage( const aName: String; const aImage: PBitmap32); override;
private
parameterPrecision : TParameterInteger;
parameterSensibility : TParameterInteger;
parameterImageIn, parameterImageOut : TParameterImage;
imageDiffHorizontal, imageDiffVertical : PBitmap32;
procedure destroyImages;
procedure _run();
procedure _runLong();
procedure calculateDiffHorizontal();
procedure calculateDiffVertical();
end;
implementation
uses
imageIO, Math;
constructor TFilterGranularityExplorer.Create;
begin
inherited;
parameterImageIn:=addParameterImage('inImage','explication...');
parameterImageOut:=addParameterImage('outImage','explication...');
parameterPrecision:=addParameterInteger('precision','',0,10,2);
parameterSensibility:=addParameterInteger('sensibility','',1,15,10);
end;
destructor TFilterGranularityExplorer.Destroy;
begin
inherited;
destroyImages;
end;
procedure TFilterGranularityExplorer.destroyImages;
begin
image.freeImage(imageDiffHorizontal);
image.freeImage(imageDiffVertical);
end;
procedure TFilterGranularityExplorer.Run();
begin
if (parameterImageIn.Image<>nil) and (parameterImageOut.Image<>nil) then begin
_run();
end;
end;
procedure TFilterGranularityExplorer.setParameterImage( const aName: String; const aImage: PBitmap32);
var
createImages : boolean;
w, h : Integer;
begin
inherited;
if aName='inImage' then begin
// we create images with 1 pixel removed
w:=parameterImageIn.Image.Width-1;
h:=parameterImageIn.Image.Height-1;
createImages:=true;
if (imageDiffHorizontal<>nil) then begin
if (imageDiffHorizontal.Width=w) and
(imageDiffHorizontal.Height=h) then begin
createImages:=false;
end;
end;
if createImages=true then begin
destroyImages;
imageDiffHorizontal:=createImage(w,parameterImageIn.Image.Height);
imageDiffVertical:=createImage(parameterImageIn.Image.Width,h);
end else begin
eraseImage(imageDiffHorizontal);
eraseImage(imageDiffVertical);
end;
end;
end;
// Create a image containing all vertical + horizontal difference.
// Example for a precision of 3 (=3*3):
// diff( row 10, col 100) =
// (diff horizontal)
// (src( row 9, col 100) - src( row 9, col 99)) +
// (src( row 9, col 101) - src( row 9, col 100)) +
// (src( row 10, col 100) - src( row 10, col 99)) +
// (src( row 10, col 101) - src( row 10, col 100)) +
// (src( row 11, col 100) - src( row 11, col 99)) +
// (src( row 11, col 101) - src( row 11, col 100)) +
// (diff vertical)
// (src( row 10, col 99) - src( row 9, col 99)) +
// (src( row 11, col 99) - src( row 10, col 99)) +
// (src( row 10, col 100) - src( row 9, col 100)) +
// (src( row 11, col 100) - src( row 10, col 100)) +
// (src( row 10, col 101) - src( row 9, col 101)) +
// (src( row 11, col 101) - src( row 10, col 101)) +
procedure TFilterGranularityExplorer._run();
var
PDest : PColor32Array;
w,h :Integer;
value : Integer;
diff : Integer;
tContraste : Integer;
tContrasteHorizontal, tContrasteVertical : Integer;
neighbor :Integer;
imageSrcRow, imageSrcCol : Integer;
imageSrcRowmax, imageSrcColmax : Integer;
imageSrcNeighborRow, imageSrcNeighborCol : Integer;
imageSrcNeighborRowmin, imageSrcNeighborColmin : Integer;
imageSrcNeighborRowmax, imageSrcNeighborColmax : Integer;
pSrcDiffHorizontal, pSrcDiffVertical : PColor32Array;
imageSrcDiffHorizontalRowmax, imageSrcDiffHorizontalColmax : Integer;
imageSrcDiffVerticalRowmax, imageSrcDiffVerticalColmax : Integer;
begin
h:=parameterImageIn.Image.Height;
w:=parameterImageIn.Image.Width;
neighbor:=parameterPrecision.Value;
// We start by calculate the difference in horizontal and vertical
// The result is in imageDiffHorizontal and imageDiffVertical
calculateDiffHorizontal();
calculateDiffVertical();
imageSrcRowmax:=h-1;
imageSrcColmax:=w-1;
pSrcDiffHorizontal:=imageDiffHorizontal.Bits;
imageSrcDiffHorizontalRowmax:=imageDiffHorizontal.Height-1;
imageSrcDiffHorizontalColmax:=imageDiffHorizontal.Width-1;
pSrcDiffVertical:=imageDiffVertical.Bits;
imageSrcDiffVerticalRowmax:=imageDiffVertical.Height-1;
imageSrcDiffVerticalColmax:=imageDiffVertical.Width-1;
for imageSrcRow:=0 to imageSrcRowmax do begin
pDest:=parameterImageOut.Image.Bits;
Inc(pDest,imageSrcRow*w);
for imageSrcCol:=0 to imageSrcColmax do begin
// contrast horizontal and contrast vertical
tContrasteHorizontal:=0;
tContrasteVertical:=0;
imageSrcNeighborRowmin:=imageSrcRow-neighbor+1; if imageSrcNeighborRowmin<0 then imageSrcNeighborRowmin:=0;
imageSrcNeighborColmin:=imageSrcCol-neighbor+1; if imageSrcNeighborColmin<0 then imageSrcNeighborColmin:=0;
imageSrcNeighborRowmax:=imageSrcRow+neighbor;
if imageSrcNeighborRowmax>imageSrcDiffHorizontalRowmax then imageSrcNeighborRowmax:=imageSrcDiffHorizontalRowmax;
if imageSrcNeighborRowmax>imageSrcDiffVerticalRowmax then imageSrcNeighborRowmax:=imageSrcDiffVerticalRowmax;
imageSrcNeighborColmax:=imageSrcCol+neighbor;
if imageSrcNeighborColmax>imageSrcDiffHorizontalColmax then imageSrcNeighborColmax:=imageSrcDiffHorizontalColmax;
if imageSrcNeighborColmax>imageSrcDiffVerticalColmax then imageSrcNeighborColmax:=imageSrcDiffVerticalColmax;
for imageSrcNeighborRow:=imageSrcNeighborRowmin to imageSrcNeighborRowmax do begin
pSrcDiffHorizontal:=imageDiffHorizontal.Bits;
Inc(pSrcDiffHorizontal,imageSrcNeighborRow*imageDiffHorizontal.Width+imageSrcNeighborColmin);
pSrcDiffVertical:=imageDiffVertical.Bits;
Inc(pSrcDiffVertical,imageSrcNeighborRow*imageDiffVertical.Width+imageSrcNeighborColmin);
for imageSrcNeighborCol:=imageSrcNeighborColmin to imageSrcNeighborColmax do begin
// horizontal
value:=pSrcDiffHorizontal^[0];
Inc(pSrcDiffHorizontal);
diff:=value and $000000FF;
Inc(tContrasteHorizontal,diff);
// vertical
value:=pSrcDiffVertical^[0];
Inc(pSrcDiffVertical);
diff:=value and $000000FF;
Inc(tContrasteVertical,diff);
end;
end;
// contrast global
tContraste:=tContrasteHorizontal+tContrasteVertical;
if tContraste>255 then tContraste:=255;
// set gray value with Color32 for optimization
pDest^[0]:= Color32(tContraste,tContraste,tContraste);
Inc(pDest);
end;
end;
end;
procedure TFilterGranularityExplorer._runLong();
var
pSrc, PDest : PColor32Array;
w,h :Integer;
value : Integer;
tIntensity, tIntensityPreviouse : Integer;
diff : Integer;
tContraste : Integer;
sensibility : Integer;
neighbor :Integer;
imageSrcRow, imageSrcCol : Integer;
imageSrcRowmax, imageSrcColmax : Integer;
imageSrcNeighborRow, imageSrcNeighborCol : Integer;
imageSrcNeighborRowmin, imageSrcNeighborColmin : Integer;
imageSrcNeighborRowmax, imageSrcNeighborColmax : Integer;
begin
h:=parameterImageIn.Image.Height;
w:=parameterImageIn.Image.Width;
neighbor:=parameterPrecision.Value;
sensibility:=parameterSensibility.Max-parameterSensibility.Value+1;
pSrc:=parameterImageIn.Image.Bits;
imageSrcRowmax:=h-1;
imageSrcColmax:=w-1;
for imageSrcRow:=0 to imageSrcRowmax do begin
pDest:=parameterImageOut.Image.Bits;
Inc(pDest,imageSrcRow*w);
for imageSrcCol:=0 to imageSrcColmax do begin
tContraste:=0;
imageSrcNeighborRowmin:=imageSrcRow-neighbor; if imageSrcNeighborRowmin<0 then imageSrcNeighborRowmin:=0;
imageSrcNeighborColmin:=imageSrcCol-neighbor; if imageSrcNeighborColmin<0 then imageSrcNeighborColmin:=0;
imageSrcNeighborRowmax:=imageSrcRow+neighbor; if imageSrcNeighborRowmax>imageSrcRowmax then imageSrcNeighborRowmax:=imageSrcRowmax;
imageSrcNeighborColmax:=imageSrcCol+neighbor; if imageSrcNeighborColmax>imageSrcColmax then imageSrcNeighborColmax:=imageSrcColmax;
// by row
for imageSrcNeighborRow:=imageSrcNeighborRowmin to imageSrcNeighborRowmax do begin
tIntensityPreviouse:=-1;
for imageSrcNeighborCol:=imageSrcNeighborColmin to imageSrcNeighborColmax do begin
value:=pSrc[imageSrcNeighborRow*w+imageSrcNeighborCol];
tIntensity:=Intensity(value);
if tIntensityPreviouse<>-1 then begin
diff:=tIntensity-tIntensityPreviouse;
if diff<0 then diff:=-diff;
diff:=diff div sensibility;
Inc(tContraste,diff);
end;
tIntensityPreviouse:=tIntensity;
end;
end;
// by col
for imageSrcNeighborCol:=imageSrcNeighborColmin to imageSrcNeighborColmax do begin
tIntensityPreviouse:=-1;
for imageSrcNeighborRow:=imageSrcNeighborRowmin to imageSrcNeighborRowmax do begin
value:=pSrc[imageSrcNeighborRow*w+imageSrcNeighborCol];
tIntensity:=Intensity(value);
if tIntensityPreviouse<>-1 then begin
diff:=tIntensity-tIntensityPreviouse;
if diff<0 then diff:=-diff;
diff:=diff div sensibility;
Inc(tContraste,diff);
end;
tIntensityPreviouse:=tIntensity;
end;
end;
if tContraste>255 then tContraste:=255;
// set gray value with Color32 for optimization
pDest^[0]:= Color32(tContraste,tContraste,tContraste);
Inc(pDest);
end;
end;
end;
// We create a image containing all difference between each 2 cols of source image, by row.
// Example :
// diff(row 10, col 100) = src(row 10, col 100) - src(row 10, col 99)
procedure TFilterGranularityExplorer.calculateDiffHorizontal();
var
pSrc, PDest : PColor32Array;
w,h :Integer;
value : Integer;
tIntensity, tIntensityPreviouse : Integer;
diff : Integer;
sensibility : Integer;
imageSrcRow, imageSrcCol : Integer;
imageSrcRowmax, imageSrcColmax : Integer;
begin
h:=parameterImageIn.Image.Height;
w:=parameterImageIn.Image.Width;
sensibility:=parameterSensibility.Max-parameterSensibility.Value+1;
pSrc:=parameterImageIn.Image.Bits;
imageSrcRowmax:=h-1;
imageSrcColmax:=w-1;
for imageSrcRow:=0 to imageSrcRowmax do begin
pDest:=imageDiffHorizontal.Bits;
Inc(pDest,imageSrcRow*imageDiffHorizontal.Width);
tIntensityPreviouse:=0;
for imageSrcCol:=0 to imageSrcColmax do begin
value:=pSrc[imageSrcRow*w+imageSrcCol];
tIntensity:=Intensity(value);
if imageSrcCol>0 then begin
diff:=tIntensity-tIntensityPreviouse;
if diff<0 then diff:=-diff;
diff:=diff div sensibility;
pDest^[0]:= image.Gray32(diff);
Inc(pDest);
end;
tIntensityPreviouse:=tIntensity;
end;
end;
end;
// We create a image containing all difference between each 2 rows of source image, by colonne.
// Example :
// diff(row 10, col 100) = src(row 10, col 100) - src(row 9, col 100)
procedure TFilterGranularityExplorer.calculateDiffVertical();
var
pSrc, PDest : PColor32Array;
w,h :Integer;
value : Integer;
tIntensity : Integer;
tIntensityPreviouse : array of Integer;
diff : Integer;
sensibility : Integer;
imageSrcRow, imageSrcCol : Integer;
imageSrcRowmax, imageSrcColmax : Integer;
begin
h:=parameterImageIn.Image.Height;
w:=parameterImageIn.Image.Width;
sensibility:=parameterSensibility.Max-parameterSensibility.Value+1;
pSrc:=parameterImageIn.Image.Bits;
imageSrcRowmax:=h-1;
imageSrcColmax:=w-1;
tIntensityPreviouse:=nil;
SetLength(tIntensityPreviouse,parameterImageIn.Image.Width);
for imageSrcRow:=0 to imageSrcRowmax do begin
if imageSrcRow>0 then begin
pDest:=imageDiffVertical.Bits;
Inc(pDest,(imageSrcRow-1)*imageDiffVertical.Width);
end;
for imageSrcCol:=0 to imageSrcColmax do begin
value:=pSrc[imageSrcRow*w+imageSrcCol];
tIntensity:=Intensity(value);
if imageSrcRow>0 then begin
diff:=tIntensity-tIntensityPreviouse[imageSrcCol];
if diff<0 then diff:=-diff;
diff:=diff div sensibility;
pDest^[0]:=image.Gray32(diff);
Inc(pDest);
end;
// we save the intensity of this colonne (used in the next row)
tIntensityPreviouse[imageSrcCol]:=tIntensity;
end;
end;
end;
end.