ImageEn, unit imageenproc

TImageEnProc.SeparateObjects

TImageEnProc.SeparateObjects


Declaration

function SeparateObjects(Quality: Integer = 4; MergeCommonAreas: Boolean = True; MinSize: Integer = 0): TList; overload;
function SeparateObjects(Quality: Integer; MergeCommonAreas: Boolean; BackgroundColorBegin, BackgroundColorEnd: TRGB; MinSize: Integer = 0): TList; overload;


Description

Create a list (TList) of TRect pointers where each rectangle encloses an "object" detected in an image. An object is a separate shape or image within a picture. It works best when separating photos or simple objects upon a white or black background. The background cannot contain a pattern.

Parameter Description
Quality The contour search routine definition. Minimum value is 1, suggested is 4. Lower values increases speed, but it might fail to recognize complex objects like characters
MergeCommonAreas If true, when two rectangles intersect they are merged. When false, two rectangles are merged only if they are inclusive
BackgroundColorBegin and BackgroundColorEnd The background color range. This helps the function to separate the background and the objects
MinSize Specifies a minimum size to allow for objects. Any objects smaller than this (in both horizontal and vertical dimensions) will be ignored

Note: You must free the returned list as follows:
  rects := ImageEnView1.Proc.SeparateObjects();
  ..process rects..
  // free rects
  for i := 0 to rects.Count-1 do
    dispose( PRect( rects[i] ));
  rects.free;


Demos

Demo  Demos\ImageAnalysis\SeparateObjects\SeparateObjects.dpr
Demo  Demos\ImageEditing\EveryMethod\EveryMethod.dpr


Example

// Count blobs in an image
Test Image:




// Show layer rects around objects
var
  rects: TList;
  i: integer;
begin
  ImageEnView1.Proc.ConvertToBWThreshold(80);     // <= 80 = sensible parameter
  rects := ImageEnView1.Proc.SeparateObjects(4, false);
  ImageEnView1.Proc.Undo(); // Revert image

  for i := 0 to rects.Count-1 do
  begin
    // Add Layer
    with PRect(rects[i])^ do
      ImageEnView1.LayersAdd( iesRectangle, Rect( Left, Top, Right + 1, Bottom + 1), clRed, 2 );
    dispose( PRect( rects[i] ));
  end;
  rects.free;
  ImageEnView1.Update();

  ShowMessage('Found ' + IntToStr( rects.Count ) + ' objects');
End;

// Draw red box onto image
var
  rects: TList;
  i: integer;
  r: TRect;
begin
  ImageEnView1.Proc.ConvertToBWThreshold(80);     // <= 80 = sensible parameter
  rects := ImageEnView1.Proc.SeparateObjects(4, false);

  // Needed to draw red rectangles around found objects!
  ImageEnView1.Proc.ConvertTo24Bit();

  for i := 0 to rects.Count-1 do
  begin
    r := PRect(rects[i])^;

    // draw boxes
    with ImageEnView1.IEBitmap.Canvas do
    begin
      Pen.Color := clRed;
      Brush.Style := bsClear;
      Rectangle( r.Left, r.Top, r.Right + 1, r.Bottom + 1 );
    end;

    dispose( PRect( rects[i] ));
  end;
  rects.free;
  ImageEnView1.Update();

  ShowMessage('Found ' + IntToStr( rects.Count ) + ' objects');
End;

Result:



SeparateObjects vs. Blob Detection

// Load test image
ImageEnView1.IO.LoadFromFile( 'D:\TestImage.jpg' );

  


// SEPARATE OBJECTS
// Show detected objects in the image
ImageEnView1.Proc.SaveUndo();
ImageEnView1.Proc.ConvertToBWThreshold( 80 );    // Better detection
rects := ImageEnView1.Proc.SeparateObjects( 4, True, 10 );
ImageEnView1.Proc.Undo();                        // Get full color image back
for i := 0 to rects.Count - 1 do
begin
  r := PRect(rects[i])^;

  // draw boxes
  with ImageEnView1.IEBitmap.Canvas do
  begin
    Pen.Color := clRed;
    Brush.Style := bsClear;
    Rectangle( r.Left, r.Top, r.Right + 1, r.Bottom + 1 );
  end;

  dispose( PRect( rects[i] ));
end;

// Output object count
ImageEnView1.Proc.TextOut( Align_Text_Near_Left, Align_Text_Near_Top, Format( 'Objects: %d', [ rects.Count ]), 'Arial', 10, clRed, [fsBold] );
ImageEnView1.Update();
rects.free;

 




// BLOB DETECTION
detector := IEVisionLib().createBlobDetector();
detector.setFilterByInertia( False, 0.1, 3.4e+38 );
detector.setFilterByConvexity( False, 0.95, 3.4e+38 );
keyPoints := detector.detect( ImageEnView1.IEBitmap.GetIEVisionImage() );
// Draw points onto image
for i := 0 to keyPoints.size() - 1 do
begin
  kp := keyPoints.getKeyPoint(i);

  // Draw onto bitmap
  with ImageEnView1.IEBitmap.Canvas do
  begin
    Pen.Color := clRed;
    Pen.Width := 2;
    Brush.Style := bsClear;
    x1 := kp.pt.x - kp.size / 2;
    y1 := kp.pt.y - kp.size / 2;
    x2 := kp.pt.x + kp.size / 2;
    y2 := kp.pt.y + kp.size / 2;
    Ellipse( Round(x1), Round(y1), Round(x2), Round(y2));
  end;
end;
ImageEnView1.Proc.TextOut( Align_Text_Near_Left, Align_Text_Near_Top, Format( 'Found: %d', [ KeyPoints.size ]), 'Arial', 12, Text_Color, [fsBold] );
ImageEnView1.Update();

 


See Also

 TIEVisionBlobDetector
 CreateRGB
 TRGB2TColor
 TColor2TRGB