TIEVisionBackgroundSubtractor
Declaration
TIEVisionBackgroundSubtractor = interface(TIEVisionBase)
Description
An interface to perform background/foreground segmentation.
Note: A shortcut method for this is available:
SubtractImageBackground
| Demos\IEVision\BackgroundSubtract\BackgroundSubtract.dpr |
| Demos\IEVision\BackgroundSubtractImage\BackgroundSubtractImage.dpr |
Video Example
// Demo TImageEnViews:
// ImageEnView1: Captured video
// ImageEnView4: Image to use as background
// ImageEnView2: Foreground Mask
// ImageEnView3: Output with replaced background
// Capture button
procedure TMainForm.CaptureButtonClick(Sender: TObject);
var
w, h: integer;
f: AnsiString;
begin
VideoInputForm.Connect;
// start capture
ImageEnView1.IO.DShowParams.Run;
// set up background subtractor
m_backgroundSubtractor.selectMethodMOG2();
end;
// We have a new frame
procedure TMainForm.ImageEnView1DShowNewFrame(Sender: TObject);
var
fgmask: TIEVisionImage;
learningRate: double;
begin
// copy current sample to ImageEnView bitmap
ImageEnView1.IO.DShowParams.GetSample(ImageEnView1.IEBitmap);
// get foreground mask
if CheckBoxLearning.Checked then
learningRate := -1
else
learningRate := 0;
fgmask := m_backgroundSubtractor.apply(ImageEnView1.IEBitmap.GetIEVisionImage(), learningRate);
ImageEnView2.IEBitmap.AssignIEVisionImage(fgmask);
// replace background using foreground mask
ImageEnView4.Proc.ResampleTo(ImageEnView3.IEBitmap, ImageEnView1.IEBitmap.Width, ImageEnView1.IEBitmap.Height, rfNone);
ImageEnView3.Proc.Merge(ImageEnView1.IEBitmap, ImageEnView2.IEBitmap);
// refresh viewers
ImageEnView1.Update();
ImageEnView2.Update();
ImageEnView3.Update();
end;
Image Example
(*
Remove the background from an image based on a background only source image
SubtractorObject : A TIEVisionBackgroundSubtractor object, e.g. initialized in FormCreate using m_backgroundSubtractor := IEVisionLib.createBackgroundSubtractor();
BackgroundImage : Image of background only
ForegroundImage : Image with subject (in front of background)
DestMask : If specified, is filled with the removal mask, an ie8g image, where 0 (black) is background, 127 (gray) is shadow and 255 (white) is foreground. Can be NIL
DestImage : If specified, is filled with the subject with background removed (alpha channel). Can be NIL
Threshold : The cut-off for the MOG2 algorithm. Smaller values return more background. Larger values return more transparency.
RemoveShadows : Whether a detection algorithm is used to detect shadows and either mark them as gray in the DestMask or remove them
RemoveNoise : Removes any isolated pixels smaller than the specified size (or 0 to skip)
Feathering : Soften the edges of the subject (or 0 to skip)
*)
const
// RemoveShadows Constants
Shadows_Ignore = 0;
Shadows_Detect = 1;
Shadows_Detect_and_Remove = 2;
//
procedure SubtractBackgroundFromImage(SubtractorObject: TIEVisionBackgroundSubtractor;
BackgroundImage: TIEBitmap;
ForegroundImage: TIEBitmap;
DestMask: TIEBitmap;
DestImage: TIEBitmap;
Threshold: double = 16;
RemoveShadows: Integer = Shadows_Detect_and_Remove;
RemoveNoise: Integer = 3;
Feathering: Integer = 0 );
var
fgmask: TIEVisionImage;
maskBmp: TIEBitmap;
nullProgress: TProgressRec;
abort: Boolean;
begin
maskBmp := nil;
try
// setup background subtractor
SubtractorObject.selectMethodMOG2( 500, Threshold, RemoveShadows in [ Shadows_Detect, Shadows_Detect_and_Remove ]);
// "Learn" background
SubtractorObject.Apply( BackgroundImage.GetIEVisionImage(), 1 );
// Pass subject and get foreground mask
fgmask := SubtractorObject.Apply( ForegroundImage.GetIEVisionImage(), 0 );
if DestMask = nil then
maskBmp := TIEBitmap.create
else
maskBmp := DestMask;
maskBmp.AssignIEVisionImage(fgmask);
if RemoveShadows = Shadows_Detect_and_Remove then
begin
// Shadows will show in the mask as gray (R,G,B = 127). Convert them all to Black
nullProgress := NullProgressRec( abort, False );
_ConvertToBWThreshold( maskBmp, 228, nullProgress );
if RemoveNoise > 0 then
begin
// Remove isolated B and W pixels smaller than "RemoveNoise"
IERemoveIsolatedPixels1Bit( maskBmp, 0, 0 , MAXINT, MAXINT, True , RemoveNoise, True, nil, nil);
IERemoveIsolatedPixels1Bit( maskBmp, 0, 0 , MAXINT, MAXINT, False, RemoveNoise, True, nil, nil);
end;
// Revert to ie8g so we can assign to Alpha channel
maskBmp.PixelFormat := ie8g;
end;
if assigned( DestImage ) then
begin
DestImage.Assign( ForegroundImage );
// Use the mask as the alpha channel
DestImage.AlphaChannel.Assign( maskBmp );
// Smooth edges
DestImage.FeatherAlphaEdges( Feathering );
end;
finally
if DestMask = nil then
FreeAndNil( maskBmp );
end;
end;
procedure TMainForm.btnSubtractClick(Sender: TObject);
begin
if fBackgroundSubtractor = nil then
fBackgroundSubtractor := IEVisionLib.createBackgroundSubtractor();
SubtractBackgroundFromImage( fBackgroundSubtractor,
IENBackground.IEBitmap,
IENSubject.IEBitmap,
nil, // Don't want mask
IENOutput.IEBitmap,
16,
Shadows_Detect_and_Remove,
3,
5 );
IENOutput.Update();
end;
See Also
◼createBackgroundSubtractor