OpenCV之视频分析与对象跟踪(二) 背景消除建模(BSM)

 

要分析背景不怎么变化的视频的时候可以用BSM 
基本原理:利用前几帧(或一帧)的图像作为背景模型,后续的帧图像与背景模型比较,得到的差异就是前景对象了。 
两个常用的算法:图像分割(GMM – 高斯混合模型), 机器学习(KNN –K个最近邻)

代码:

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char**) {
	VideoCapture capture;
	capture.open(0);
	if (!capture.isOpened()) {
		printf("could not find the video file...\n");
		return -1;
	}
	// create windows
	Mat frame;
	Mat bsmaskMOG2, bsmaskKNN;
	namedWindow("input video", CV_WINDOW_AUTOSIZE);
	namedWindow("MOG2", CV_WINDOW_AUTOSIZE);
	namedWindow("KNN Model", CV_WINDOW_AUTOSIZE);

	Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));

	// intialization BS
	Ptr<BackgroundSubtractor> pMOG2 = createBackgroundSubtractorMOG2();
	/*
	Ptr<backgroundsubtractormog2>
	cv::createBackgroundSubtractorMOG2  (     
						int     history = 500,  //用于训练背景的帧数,默认为500帧,如果不手动设置learningRate
						,history就被用于计算当前的learningRate,此时history越大,learningRate越小,背景更新越慢;
						double  varThreshold = 16,  //方差阈值,用于判断当前像素是前景还是背景。一般默认16
						,如果光照变化明显,如阳光下的水面,建议设为25,36,具体去试一下也不是很麻烦,值越大,灵敏度越低;
						bool    detectShadows = true   //是否检测影子,设为true为检测,false为不检测,
						检测影子会增加程序时间复杂度,如无特殊要求,建议设为false;
)   
	*/
	Ptr<BackgroundSubtractor> pKNN = createBackgroundSubtractorKNN();

	while (capture.read(frame)) {
		imshow("input video", frame);

		// MOG BS
		pMOG2->apply(frame, bsmaskMOG2);

		/*
		virtual void cv::BackgroundSubtractor::apply    (     
				InputArray  image,		//image 源图
				OutputArray     fgmask,  //fmask 前景(二值图像)
				double  learningRate = -1   //learningRate 学习速率,
				,值为0-1,为0时背景不更新,为1时逐帧更新,默认为-1,即算法自动更新
				) 
		*/

		morphologyEx(bsmaskMOG2, bsmaskMOG2, MORPH_OPEN, kernel, Point(-1, -1));
		imshow("MOG2", bsmaskMOG2);

		// KNN BS mask
		// 最后一个参数 (0-1之间表示学习背景模型时长,-1表示opencv自动设置学习时长
		//,0表示不更改背景模型,1表示背景模型按照最后一帧重新初始化)
		pKNN->apply(frame, bsmaskKNN,-1);
		imshow("KNN Model", bsmaskKNN);
		char c = waitKey(100);
		if (c == 27) {
			break;
		}
	}

	capture.release();
	waitKey(0);
	return 0;
}

效果图:

一开始两种算法的差异

稳定后的效果:

おすすめ

転載: blog.csdn.net/CJ_035/article/details/81952305