Background Image
Background Image
Namespace
Emgu.CV
References
EMGU Reference
EMGU cv Reference
OpenCV Use Reference
Downloads
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
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
- 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.