Background_edit.mp4
This C++ application filters the background from a static image. It's written for a Raspberry Pi but can be used on any machine with OpenCV. It's a fast algorithm to detect moving objects in an image given a static background. The available OpenCV routines were too slow for our Raspberry Pi Zero, hence this faster solution.
The given times are with a Raspberry Pi 4 with a 32-bit OS, running at 1500 MHz.
To run the application, you have to:
- OpenCV installed. Install OpenCV 4.5
- Code::Blocks installed. (
$ sudo apt-get install codeblocks
)
To extract and run the application in Code::Blocks
$ mkdir MyDir
$ cd MyDir
$ wget https://github.com/Qengineering/Fast-Background-Substraction/archive/refs/heads/main.zip
$ unzip -j master.zip
Remove master.zip, LICENSE and README.md as they are no longer needed.
$ rm master.zip
$ rm LICENSE
$ rm README.md
Your MyDir folder must now look like this:
768x576.avi (example movie)
Background.cbp (code::blocks project file)
MainQeng.cpp (C++ source file with the new algorithm)
MainMOG2.cpp (C++ source file with exisiting OpenCV algorithms)
To run the application load the project file Background.cbp in Code::Blocks.
You can load and run either MainQeng.cpp or MainMOG2.cpp in the IDE.
The code speaks for itself. Here the bare bones.
//get black/white
cv::cvtColor(frame, bw_frame, COLOR_BGR2GRAY);
//go to float
bw_frame.convertTo(fImage, CV_32FC1);
//calculate Tau
f=Tcnt; f/=Xcnt;
Tcnt--; if(Tcnt<1) Tcnt=1;
//weighted background
cv::addWeighted(fImage, f, sum_frame, (1.0-f), 0.0, sum_frame);
//substrac current image from static background
cv::subtract(sum_frame,fImage,sub_frame);
//get a 8 bit black and white image
cv::convertScaleAbs(sub_frame,finalImage,1.5);
//create Background Subtractor objects
Ptr<BackgroundSubtractor> pBackSub;
pBackSub = createBackgroundSubtractorMOG2();
....
//update the background model
pBackSub->apply(frame, finalImage);
//create Background Subtractor objects
Ptr<BackgroundSubtractor> pBackSub;
pBackSub = createBackgroundSubtractorKNN();
....
//update the background model
pBackSub->apply(frame, finalImage);
Our algorithm adapts an average background over time. Every single frame updates this sum_frame
a little bit. The adaptation is needed for slowly changing (lighting) conditions like moving shadows. It will also remove static objects from the scene. A parked car will vanish after some time in the background. Until, of course, it drives away. The constant Tau defines the adaption rate. The higher this number, the faster something disappears in the background.
Rule of the thumb: T = 5/(Tau * FPS)
Given an FPS (Frames Per Second) of 30 and a Tau of 0.05, an object will completely vanish in the background in 3.3 Sec.
The given percentage is the ratio of white pixels, in other words, the moving object.
Because the algorithm works with grey values, it is sensitive to contrast. A person wearing a green sweater on the green grass will give a not that high response as the same person walking on the street. However, we gladly pay this small price for the speed the routine achieves.
If you want to use a camera please alter line 253 in main.cpp to
cv::VideoCapture cap(0); //RaspiCam
If you want to run a movie please alter line 253 in main.cpp to
cv::VideoCapture cap( "768x576.avi"); //Movie
- Zoran Zivkovic and Ferdinand van der Heijden. Efficient adaptive density estimation per image pixel for the task of background subtraction. Pattern recognition letters, 27(7):773–780, 2006. link
- Zoran Zivkovic. Improved adaptive gaussian mixture model for background subtraction. In Pattern Recognition, 2004. ICPR 2004. Proceedings of the 17th International Conference on, volume 2, pages 28–31. IEEE, 2004. link