ImageEn, unit ievision

TIEVisionBackgroundSubtractor


Declaration

TIEVisionBackgroundSubtractor = interface(TIEVisionBase)


Description

Performs background/foreground segmentation.




Demos

Demo  Demos\IEVision\BackgroundSubtract\BackgroundSubtract.dpr
Demo  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 consts
  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;


Methods and Properties

Public Method  apply
Public Method  selectMethodGMG
Public Method  selectMethodMOG
Public Method  selectMethodMOG2
Public Method  selectMethodKNN


See Also

Public Method  createBackgroundSubtractor