ImageEn, unit iexHelperFunctions

TIEBitmapHelper.MatchTemplate

TIEBitmapHelper.MatchTemplate


Declaration

// Single Result overload
function MatchTemplate(SearchTemplate: TIEBitmap; MatchMethod: TIEVisionTemplateMatchMethod; MatchThreshold: Double; out Rect: TRect; out Rank: Double): Boolean; overload;

// Multiple Result overload
function MatchTemplate(SearchTemplate: TIEBitmap; MatchThreshold: Double; out Rects: TIERectArray; out Ranks: TIEArrayOfDouble): Integer; overload;


Description

Shortcut methods for matchTemplate and matchTemplateMulti that search the image for the locations of the template image.

Parameter Description
SearchTemplate Template image to find. It must be not larger than the source image
MatchMethod Comparison method (First overload only)
MatchThreshold Minimum rank required. Range is 0 to 100%, though generally values of <90% are not good matches
rects List of rectangles representing bounding boxes of found objects
ranks List of doubles representing ranks of found objects



Note:
 You must add the iexHelperFunctions unit to your uses clause
 You can draw the rects to a canvas using DrawRects
 Template matching requires IEVision. You will need to register it before calling the method


Single Result Method Behaviour

The following call:

// perform template searching
if ImageEnView1.IEBitmap.MatchTemplate( ImageEnView2.IEBitmap, ievSQDIFF, 95, rect, rank ) then
  Memo1.Lines.Add( format( 'Found: (%d,%d,%d,%d) - %d%%', [ rect.Left, rect.Top, rect.Right, rect.Bottom, trunc(rank) ]));

Is the same as calling:

// get image to search in
image := ImageEnView1.IEBitmap.GetIEVisionImage();

// get the template image to search
templ := ImageEnView2.IEBitmap.GetIEVisionImage();

// perform template searching
rect := image.matchTemplate(templ, ievSQDIFF, @rank);

if rank >= 95 then
begin
  r := IEVisionRectToTRect( rect );
  Caption := format( 'Found: (%d,%d,%d,%d) - %d%%', [ r.Left, r.Top, r.Right, r.Bottom, trunc( rank )]);
end;


Multi Result Method Behaviour

The following call:

// perform template searching
count := ImageEnView1.IEBitmap.MatchTemplate( ImageEnView2.IEBitmap, 96.0, rects, ranks );
for i := 0 to count - 1 do
begin
  r := rects[i];
  Memo1.Lines.Add( format( '#%d: (%d,%d,%d,%d) - %d%%', [ i+1, r.Left, r.Top, r.Right, r.Bottom, trunc(ranks[i]) ]));
end;

Is the same as calling:

// get image to search in
image := ImageEnView1.IEBitmap.GetIEVisionImage();

// get the template image to search
templ := ImageEnView2.IEBitmap.GetIEVisionImage();

// get template mask (from alpha channel)
if ImageEnView2.IEBitmap.HasAlphaChannel() then
  templMask := ImageEnView2.IEBitmap.AlphaChannel.GetIEVisionImage(true)
else
  templMask := nil;

// perform template searching
count := image.matchTemplateMulti(templ, templMask, 96.0, rects, ranks);

for i := 0 to count - 1 do
begin
  r := IEVisionRectToTRect( rects.getRect(i) );
  Memo1.Lines.Add( format( '#%d: (%d,%d,%d,%d) - %d%%', [ i+1, r.Left, r.Top, r.Right, r.Bottom, trunc(ranks.getDouble(i)) ]));
end;


Demo

Demo  Demos\ImageEditing\EveryMethod\EveryMethod.dpr


Overload 1 Example

// Search image (ImageEnView1) for one instance of the selected image in a TImageEnMView
ImageEnView1.LayersClear( False );
idx := ImageEnMView1.SelectedImage;

// perform template searching
if ImageEnView1.IEBitmap.MatchTemplate( ImageEnMView1.GetTIEBitmap(idx), ievSQDIFF, 95, rect, rank ) then
begin
  ImageEnView1.LayersAdd( ielkText, rect );
  with TIETextLayer( ImageEnView1.CurrentLayer ) do
  begin
    BorderColor  := clRed;
    BorderWidth  := 5;
    FillColor    := clWhite;
    Opacity      := 0.66;
    Font.Height  := 24;
    Font.Color   := clRed;
    WordWrap     := False;
    Alignment    := iejCenter;
    Text         := ImageEnMView1.ImageBottomText[idx] + ' ' + FloatToStr(trunc(rank)) + '%';
    TextOverflow := ieoShrink;
  end;
end;

ImageEnMView1.ReleaseBitmap(idx);


Overload 2 Example

// Search image (ImageEnView1) for multiple instances of the selected image in a TImageEnMView
idx := ImageEnMView1.SelectedImage;
ImageEnView1.LayersClear( False );

// perform template searching
count := ImageEnView1.IEBitmap.MatchTemplate( ImageEnMView1.GetTIEBitmap(idx), 95, rects, ranks );
for i := 0 to count - 1 do
begin
  // draw a red box around the found rectangle
  ImageEnView1.LayersAdd( ielkText, IEVisionRectToTRect( rects.getRect(i) ));
  with TIETextLayer( ImageEnView1.CurrentLayer ) do
  begin
    BorderColor  := clRed;
    BorderWidth  := 2;
    Opacity      := 0.66;
    Font.Height  := 21;
    Font.Color   := clRed;
    Font.Style   := [fsBold];
    WordWrap     := False;
    Alignment    := iejCenter;
    Text         := '#' + IntToStr(i + 1) + ' ' + FloatToStr(trunc(ranks[i])) + '%';
    TextOverflow := ieoShrink;
  end;
end;

ImageEnMView1.ReleaseBitmap(idx);