Subtracting background in OpenCV (C ++)

I want to implement a background averaging method. I have 50 frames of images taken in one second, and some of the frames contain lightning, which I want to extract as a foreground. The frames are taken from a fixed camera, and the frames are taken as shades of gray. I want to do this:

  • Get wallpaper
  • After that, compare each frame with the background model to determine if there is lighting in this frame or not.

I read several documents on how to do this using cvAcc (), but I find it hard to figure out how to do this. I would appreciate a piece of code that will help me and links to documents that can help me understand how I can implement this.

Thank you in advance.

+7
source share
1 answer

We had the same task in one of our projects.

To get the base model, we simply create the BackgroundModel class, grab the first (say) 50 frames and calculate the middle frame to avoid pixel errors in the background model.

For example, if you get an 8-bit grayscale image (CV_8UC1) from your camera, you initialize your model CV_16UC1 to avoid cropping.

cv::Mat model = cv::Mat(HEIGHT, WIDTH, CV_16UC1, cv::Scalar(0)); 

Now, expecting the first frames to be calculated by your model, simply add each frame to the model and count the number of frames received.

 void addFrame(cv::Mat frame) { cv::Mat convertedFrame; frame.convertTo(convertedFrame, CV_16UC1); cv::add(convertedFrame, model, model); if (++learnedFrames >= FRAMES_TO_LEAN) { // FRAMES_TO_LEARN = 50 createMask(); } } 

The createMask () function calculates the middle frame that we use for the model.

 void createMask() { cv::convertScaleAbs(model, mask, 1.0 / learnedFrames); mask.convertTo(mask, CV_8UC1); } 

Now you just send all the frames through the BackgroundModel class to the subtract () function. If the result is an empty cv :: Mat, the mask is still computed. Otherwise, you get a subtracted frame.

 cv::Mat subtract(cv::Mat frame) { cv::Mat result; if (++learnedFrames >= FRAMES_TO_LEAN) { // FRAMES_TO_LEARN = 50 cv::subtract(frame, mask, result); } else { addFrame(frame); } return result; } 

Last but not least, you can use the Scalar Sum (const Mat & mtx) to calculate the sum of the pixel and decide whether it will be a frame with a highlight on it.

+18
source

All Articles