Background Image

From Emgu CV: OpenCV in .NET (C#, VB, C++ and more)
Jump to: navigation, search

Background Image

Namespace

Emgu.CV

References

EMGU Reference
EMGU cv Reference
OpenCV Use Reference

Downloads

Source Code V1.1

Example

The following example shows the use of the RunningAvg() image method call within EMGU. The function of this method is to allow a background image to be produced. This background image will contain static objects within a series of images presented. This can be further used to determine movement within the image.


Software

NameName


Pre-Requisites

The code provided should run straight out of the Emgu.Example folder (V2.4.2), extract it to this location. If the code fails to execute re-reference the EMGU libraries and include the required opencv dlls in the bin directory. Note that the project is set to build to the output path "..\..\..\bin\" you may wish to change this if you don't extract to the EMGU.Example folder.

A web camera is required to run this source code.

EMGU Coding Level: While the coding is not advanced the rated level for this example is Beginer/Intermediate. The code is simple and well commented although to understand the use of the method call some experience with EMGU is expected.


The Code

The code provided in this sample is basic there is little or no error checking. Support is available through the Forums but please try and examine the code before saying it doesn't work for you. The code is not optimised instead is better formatted to provided an understanding of the stages involved.

The program sets up image acquisition through the default camera available to the system. It acquires a frame before starting to run the averaging process. Each frame is accumulated and added together with a set weight. Movement is removed from the image as the frames accumulate as static objects that show consistent values start producing heavy weights. Development could allow a calibration phase to be set up once a camera is in place. This could form background image which is then used to locate movement within a frame through background subtraction.


The Code: Variables

The _capture variable simply holds details about the image acquisition device

        Capture _capture;


The Image variables hold information about the current frame, previous frame, their difference, and the background being formed. They are named suitably for their role.

        Image<Bgr, Byte> Frame; //current Frame from camera
        Image<Gray, float> Gray_Frame; //gray_frame form camera
        Image<Gray, float> Background; //Average Background being formed
        Image<Gray, float> Previous_Frame; //Previiousframe aquired
        Image<Gray, float> Difference; //Difference between the two fra

The two variables alpha and threshold are used to classify movement within the frame. The threshold sets the difference caused by movement to be considered, while alpha is the weighting used for each frame. The greater the alpha the less movement will be suppressed but a background image will be formed quickly. Having an alpha rating of 0.003 as demonstrated sould allow a background image to be progressively formed. This is useful in complex movement situations where whole backgrounds will change.

        double alpha = 0.003; //stores alpha for thread access
        int Threshold = 60; //stores threshold for thread access


The Code: Methods

The capture device is initialised to the default device in the public Form1() method. This code is not designed to deal with camera capture specifics see here for further reference. The key method of interest is the ProcessFrame() method. This is where the movement between frames is established and the background formed. It is split up into two simple parts. this first looks to see if a frame has been acquired before. A series of at least 2 frames are required to perform difference calculations and averaging calculation. The Image variable Frame is used to check to see if it is null to achieve this, alternatively a boolean flag or frame count could be used if cameras where to be paused and restarted.

            if (Frame == null) //we need at least one fram to work out running average so acquire one before doing anything
            {
                //display the frame aquired
                Frame = _capture.RetrieveBgrFrame(); //we could use RetrieveGrayFrame if we didn't care about displaying colour image
                DisplayImage(Frame.ToBitmap(), captureBox); //display the image using thread safe call

                //copy the frame to previousframe
                //Previous_Frame = Frame.Convert<Gray, Byte>().Convert<Gray, float>(); //we can only convert one aspect at a time so wel call convert twice
                Background = Frame.Convert<Gray, Byte>().Convert<Gray, float>(); //we can only convert one aspect at a time so wel call convert twice
            }


Once a previous frame is acquired it is compared to the current frame using the AbsDiff() method which will find find changes between frames. The Background image is then updated using the RunningAvg() method call.

//acquire the frame
                Frame = _capture.RetrieveBgrFrame(); //we could use RetrieveGrayFrame if we didn't care about displaying colour image
                DisplayImage(Frame.ToBitmap(), captureBox); //display the image using thread safe call

                //create a gray copy for processing
                Gray_Frame = Frame.Convert<Gray, Byte>().Convert<Gray, float>(); //we can only convert one aspect at a time so wel call convert twice

                //cvAbsDiff(pFrameMat, pBkMat, pFrMat);
                Difference = Background.AbsDiff(Gray_Frame); //find the absolute difference 

                DisplayImage(Difference.ToBitmap(), ABSview); //display the absolute difference 

                //CvInvoke.cvRunningAvg(Difference, Background, 0.003, Background); 
                /*Play with the alpha weighting 0.001 */
                Background.RunningAvg(Difference, alpha); //performe the cvRunningAvg frame acumullation
                DisplayImage(Background.ToBitmap(), resultbox); //display the image using thread safe call


The remaining four methods deal with form interaction (Alpha_Value_Scroll()) and thread safe drawing of images to picture boxes on the form (DisplayImage()). The final method OnClosing() event override simply ensures the capture device is disposed of in the form closing process.

Methods Available

Used

  • Image()
  • ThresholdBinary()
  • ToBitmap()
  • Convert()
  • AbsDiff()
  • RunningAvg()


See the Online Documentation for all methods available


Bugs

  1. Sometimes the images will not display correctly when the form is maximised this is down to the load on the system in painting the images to 3 picture boxes.