ImageEn, unit imageenproc |
|
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\ImageAnalysis\SeparateObjects\SeparateObjects.dpr |
| Demos\ImageEditing\EveryMethod\EveryMethod.dpr |
// 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