motion detection (foreground detection) (i) ViBe
Zouxy09@qq.com
Http://blog.csdn.net/zouxy09
Because of monitoring the development of the demand, the current prospects of the research is still many, there have been many new methods and ideas. The personal understanding of the following is probably summed up as follows:
Frame difference, background subtraction (GMM, CodeBook, sobs, Sacon, VIBE, W4, multi-frame averaging ...) ), optical flow (sparse optical flow, dense optical flow), motion competition (motion Competition), motion template (Motion history image), Time entropy ... Wait a minute. If you add their improved version, it's a big family.
A simple comparative analysis of some of the above methods can be found in the following examples:
Http://www.cnblogs.com/ronny/archive/2012/04/12/2444053.html
As to which of the best, look at the use of the environment bar, there are some applications more, some in some cases better performance. These need to be tested for their own use. Oh.
Recommend a good library: http://code.google.com/p/bgslibrary/contains a variety of background subtraction method, you can let yourself do a lot less definitely work.
There are a lot of analysis on the Wang Xianrong blog:
Http://www.cnblogs.com/xrwang/archive/2010/02/21/ForegroundDetection.html
The following blog on the reprinted Wang Xianrong above several, and then add their own analysis of two articles:
Http://blog.csdn.net/stellar0
This paper mainly focuses on one of the background subtraction methods: ViBe. STELLAR0 's blog on the analysis of Vibe, I am no longer verbose here, the specific theory can refer to:
http://www2.ulg.ac.be/telecom/research/vibe/
http://blog.csdn.net/stellar0/article/details/8777283
http://blog.csdn.net/yongshengsilingsa/article/details/6659859
Http://www2.ulg.ac.be/telecom/research/vibe/download.html
http://www.cvchina.info/2011/12/25/vibe/
"Vibe:a Universal background subtraction algorithm for video sequences"
"Vibe:a powerful technique for background detection and subtraction in video sequences"
Vibe is a pixel-level video background modeling or foreground detection algorithm, the effect is better than several familiar algorithms, the hardware memory footprint is very simple. I previously based on STELLAR0 code (here, thank you very much stellar0) rewritten into a mat format code, and now put up to communicate with you, specifically as follows: (test pass in vs2010+opencv2.4.2)
ViBe.h
#pragma once
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace CV;
using namespace std;
#define Num_samples //number of samples per pixel
#define Min_matches 2 //#min指数
#define RADIUS/ / Sqthere radius
#define Subsample_factor //Sub-sampling probability
class Vibe_bgs
{public
:
VIBE_BGS ( void);
~vibe_bgs (void);
void init (const Mat _image); Initialize
void processfirstframe (const Mat _image);
void Testandupdate (const Mat _image); Update
Mat getmask (void) {return m_mask;};
Private:
Mat m_samples[num_samples];
Mat M_foregroundmatchcount;
Mat m_mask;
};
ViBe.cpp
#include <opencv2/opencv.hpp> #include <iostream> #include "ViBe.h" using namespace std;
using namespace CV; int c_xoff[9] = {-1, 0, 1,-1, 1,-1, 0, 1, 0}; The neighbor point of x int c_yoff[9] = {-1, 0, 1,-1, 1,-1, 0, 1, 0}; Neighbor Point of y vibe_bgs::vibe_bgs (void) {} vibe_bgs::~vibe_bgs (void) {}/**************** Assign space and init *********** /void Vibe_bgs::init (const Mat _image) {for (int i = 0; i < num_samples; i++) {M_samples
[I] = Mat::zeros (_image.size (), CV_8UC1);
} M_mask = Mat::zeros (_image.size (), CV_8UC1);
M_foregroundmatchcount = Mat::zeros (_image.size (), CV_8UC1);
}/**************** Init model from first frame ********************/void Vibe_bgs::p rocessfirstframe (const Mat _image)
{RNG rng;
int row, col; for (int i = 0, i < _image.rows; i++) {for (int j = 0; J < _image.cols; J + +) {for (int k = 0; K &L T Num_samples; k++) {//Random pick up num_samples pixel in neighbourhood To construct the model int random = rng.uniform (0, 9);
row = i + c_yoff[random];
if (Row < 0) row = 0;
if (row >= _image.rows) row = _image.rows-1;
Col = j + c_xoff[random];
if (Col < 0) col = 0;
if (Col >= _image.cols) col = _image.cols-1;
M_samples[k].at<uchar> (i, j) = _image.at<uchar> (row, col); }}}}/**************** Test a new frame and update model ********************/void Vibe_bgs::testandupdate (const M
At _image) {rng rng;
for (int i = 0; i < _image.rows; i++) {for (int j = 0; J < _image.cols; J + +) {int matches (0), count (0);
Float Dist; while (matches < min_matches && Count < num_samples) {dist = ABS (m_samples[count].at<uchar> (I,
j)-_image.at<uchar> (i, j));
if (Dist < RADIUS) matches++;
count++; } if (matches >= min_matches) {//It is a background pixel M_foregroundmatchcouNt.at<uchar> (i, j) = 0;
Set background pixel to 0 m_mask.at<uchar> (i, j) = 0;
If a pixel is a background point, then it has 1/defaultsubsamplingfactor probability to update its model sample value int random = rng.uniform (0, Subsample_factor);
if (random = = 0) {random = Rng.uniform (0, Num_samples);
M_samples[random].at<uchar> (i, j) = _image.at<uchar> (i, j);
}//also has the probability of 1/defaultsubsamplingfactor to update the model sample value of its neighbor point random = rng.uniform (0, Subsample_factor);
if (random = = 0) {int row, col;
Random = Rng.uniform (0, 9);
row = i + c_yoff[random];
if (Row < 0) row = 0;
if (row >= _image.rows) row = _image.rows-1;
Random = Rng.uniform (0, 9);
Col = j + c_xoff[random];
if (Col < 0) col = 0;
if (Col >= _image.cols) col = _image.cols-1;
Random = Rng.uniform (0, Num_samples);
M_samples[random].at<uchar> (row, col) = _image.at<uchar> (i, j); }} else {
It is a foreground pixel m_foregroundmatchcount.at<uchar> (i, j) + +;
Set background pixel to 255 m_mask.at<uchar> (i, j) = 255; If a pixel is detected continuously n times as a foreground, it is assumed that a stationary area is being misjudged as motion, updating it to the background point if (m_foregroundmatchcount.at<uchar> (i, J) >) {int
Random = Rng.uniform (0, Subsample_factor);
if (random = = 0) {random = Rng.uniform (0, Num_samples);
M_samples[random].at<uchar> (i, j) = _image.at<uchar> (i, j); }
}
}
}
}
}
Main.cpp
This was based on//' vibe:a powerful RANDOM technique to ESTIMATE ' BACKGROUND in VIDEO sequences '/by Olivier Ba Rnich and Marc Van droogenbroeck//AUTHOR:ZOUXY//DATE:2013-4-13//homepage:http://blog.csdn.net/zouxy09//Ema il:zouxy09@qq.com #include "opencv2/opencv.hpp" #include "ViBe.h" #include <iostream> #include <cstdio> u
Sing namespace CV;
using namespace Std;
int main (int argc, char* argv[]) {Mat frame, gray, mask;
Videocapture capture;
Capture.open ("Video.avi");
if (!capture.isopened ()) {cout<< "No camera or video input!\n" <<endl;
return-1;
} VIBE_BGS Vibe_bgs;
int count = 0;
while (1) {count++;
Capture >> frame;
if (Frame.empty ()) break;
Cvtcolor (frame, Gray, Cv_rgb2gray);
if (count = = 1) {vibe_bgs.init (gray);
Vibe_bgs.processfirstframe (gray); cout<< "Training GMM complete!"
<<endl;
} else {vibe_bgs.testandupdate (gray);
Mask = Vibe_bgs.getmask (); MoRphologyex (Mask, Mask, Morph_open, Mat ());
Imshow ("Mask", mask);
} imshow ("Input", frame);
if (cvwaitkey () = = ' Q ') break;
} return 0; }