OpenCV中实现了两个版本的高斯混合背景/前景分割方法(Gaussian Mixture-based Background/Foreground Segmentation Algorithm)[1-2],调用接口很明朗,效果也很好。
int main(){ VideoCapture video("1.avi"); Mat frame,mask,thresholdImage, output; video>>frame; BackgroundSubtractorMOG bgSubtractor(20,10,0.5,false); while(true){ video>>frame; ++frameNum; bgSubtractor(frame,mask,0.001); imshow("mask",mask); waitKey(10); } return 0; }
构造函数可以使用默认构造函数或带形参的构造函数:
BackgroundSubtractorMOG::BackgroundSubtractorMOG() BackgroundSubtractorMOG::BackgroundSubtractorMOG(int history, int nmixtures, double backgroundRatio, double noiseSigma=0)其中history为使用历史帧的数目,nmixtures为混合高斯数量,backgroundRatio为背景比例,noiseSigma为噪声权重。
而调用的接口只有重载操作符():
void BackgroundSubtractorMOG::operator()(InputArray image, OutputArray fgmask, double learningRate=0)其中image为当前帧图像,fgmask为输出的前景mask,learningRate为背景学习速率。
以下是使用BackgroundSubtractorMOG进行前景/背景检测的一个截图。
int main(){ VideoCapture video("1.avi"); Mat frame,mask,thresholdImage, output; //video>>frame; BackgroundSubtractorMOG2 bgSubtractor(20,16,true); while(true){ video>>frame; ++frameNum; bgSubtractor(frame,mask,0.001); cout<<frameNum<<endl; //imshow("mask",mask); //waitKey(10); } return 0; }
同样的,构造函数可以使用默认构造函数和带形参的构造函数
BackgroundSubtractorMOG2::BackgroundSubtractorMOG2() BackgroundSubtractorMOG2::BackgroundSubtractorMOG2(int history, float varThreshold, bool bShadowDetection=true )history同上,varThreshold表示马氏平方距离上使用的来判断是否为背景的阈值(此值不影响背景更新速率),bShadowDetection表示是否使用阴影检测(如果开启阴影检测,则mask中使用127表示阴影)。
使用重载操作符()调用每帧检测函数:
void BackgroundSubtractorMOG2::operator()(InputArray image, OutputArray fgmask, double learningRate=-1)参数意义同BackgroundSubtractorMOG中的operator()函数。
同时BackgroundSubtractorMOG2提供了getBackgroundImage()函数用以返回背景图像:
void BackgroundSubtractorMOG2::getBackgroundImage(OutputArray backgroundImage)
另外OpenCV的refman中说新建对象以后还有其他和模型油有关的参数可以修改,不过比较坑的是opencv把这个这些函数参数声明为protected,同时没有提供访问接口,所以要修改的话还是要自己修改源文件提供访问接口。
protected: Size frameSize; int frameType; Mat bgmodel; Mat bgmodelUsedModes;//keep track of number of modes per pixel int nframes; int history; int nmixtures; //! here it is the maximum allowed number of mixture components. //! Actual number is determined dynamically per pixel double varThreshold; // threshold on the squared Mahalanobis distance to decide if it is well described // by the background model or not. Related to Cthr from the paper. // This does not influence the update of the background. A typical value could be 4 sigma // and that is varThreshold=4*4=16; Corresponds to Tb in the paper. ///////////////////////// // less important parameters - things you might change but be carefull //////////////////////// float backgroundRatio; // corresponds to fTB=1-cf from the paper // TB - threshold when the component becomes significant enough to be included into // the background model. It is the TB=1-cf from the paper. So I use cf=0.1 => TB=0. // For alpha=0.001 it means that the mode should exist for approximately 105 frames before // it is considered foreground // float noiseSigma; float varThresholdGen; //correspondts to Tg - threshold on the squared Mahalan. dist. to decide //when a sample is close to the existing components. If it is not close //to any a new component will be generated. I use 3 sigma => Tg=3*3=9. //Smaller Tg leads to more generated components and higher Tg might make //lead to small number of components but they can grow too large float fVarInit; float fVarMin; float fVarMax; //initial variance for the newly generated components. //It will will influence the speed of adaptation. A good guess should be made. //A simple way is to estimate the typical standard deviation from the images. //I used here 10 as a reasonable value // min and max can be used to further control the variance float fCT;//CT - complexity reduction prior //this is related to the number of samples needed to accept that a component //actually exists. We use CT=0.05 of all the samples. By setting CT=0 you get //the standard Stauffer&Grimson algorithm (maybe not exact but very similar) //shadow detection parameters bool bShadowDetection;//default 1 - do shadow detection unsigned char nShadowDetection;//do shadow detection - insert this value as the detection result - 127 default value float fTau; // Tau - shadow threshold. The shadow is detected if the pixel is darker //version of the background. Tau is a threshold on how much darker the shadow can be. //Tau= 0.5 means that if pixel is more than 2 times darker then it is not shadow //See: Prati,Mikic,Trivedi,Cucchiarra,"Detecting Moving Shadows...",IEEE PAMI,2003.以下是使用BackgroundSubtractorMOG2检测的前景和背景:
参考文献:
[1] KaewTraKulPong, Pakorn, and Richard Bowden. "An improved adaptive background mixture model for real-time tracking with shadow detection." Video-Based Surveillance Systems. Springer US, 2002. 135-144.
[2] Zivkovic, Zoran. "Improved adaptive Gaussian mixture model for background subtraction." Pattern Recognition, 2004. ICPR 2004. Proceedings of the 17th International Conference on. Vol. 2. IEEE, 2004.