基于opencv的BackgroundSubtractorMOG2和BackgroundSubtractorKNN通过背景减除来实现目标追踪

  背景减除(Background Subtraction)是许多基于计算机视觉的任务中的主要预处理步骤。如果我们有完整的静止的背景帧,那么我们可以通过帧差法来计算像素差从而获取到前景对象。但是在大多数情况下,我们可能没有这样的图像,所以我们需要从我们拥有的任何图像中提取背景。当运动物体有阴影时,由于阴影也在移动,情况会变的变得更加复杂。为此引入了背景减除算法,通过这一方法我们能够从视频中分离出运动的物体前景,从而达到目标检测的目的。

 

MOG2

MOG2算法,也是高斯混合模型分离算法,是MOG的改进算法。它基于Z.Zivkovic发布的两篇论文,即2004年发布的“Improved adaptive Gausian mixture model for background subtraction”和2006年发布的“Efficient Adaptive Density Estimation per Image Pixel for the Task of Background Subtraction”中提出。该算法的一个重要特征是 它为每个像素选择适当数量的高斯分布,它可以更好地适应不同场景的照明变化等。

基本思路:

混合高斯模型:

将图像分为3-5个高斯模型,一个像素点来了,如果该像素点离任何一个高斯模型的距离大于其2倍的标准差,则为前景即运动物体,否则则是背景

步骤:第一步:初始各种参数

           第二步:使用T帧图像构造模型,对于第一个帧图像的第一个像素点,使用u1,σ1构造高斯模型

           第三步:对于一个新来的模型,如果该像素在高斯模型3*σ1内,则属于该高斯模型,对参数进行更新

           第四步:如果不满足该高斯模型,重新建立一个新的高斯模型


//构造高斯混合模型
Ptr<BackgroundSubtractor> ptrMOG2 = createBackgroundSubtractorMOG2();

//getStructuringElement构造形态学使用的kernel
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
//运用高斯模型进行拟合,在两个标准差内设置为0,在两个标准差外设置为255
ptrMOG2->apply(frame, bgMask_MOG2);

//使用形态学的开运算做背景的去除
morphologyEx(bgMask_MOG2, bgMask_MOG2, MORPH_OPEN, kernel);

完整项目代码,可以进行读写视频:

#include <iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/opencv.hpp>
#include<cstdio>
using namespace std;
using namespace cv;



int main()
{
	VideoCapture video = VideoCapture("F:\\计算机视觉\\c5.mp4");

	VideoWriter write;
	double fps = video.get(CV_CAP_PROP_FPS); //获取视频帧率
	double pauseTime = 1000 / fps; //两幅画面中间间隔
	int w = static_cast<int>(video.get(CV_CAP_PROP_FRAME_WIDTH));
	int h = static_cast<int>(video.get(CV_CAP_PROP_FRAME_HEIGHT));
	cv::Size S(w, h);

	write.open("testMOGMask.avi", -1, fps, S, true);
	if (!video.isOpened()) {
		cout << "could not load video file ..." << endl;
		return -1;
	}

	Mat frame, bgMask_MOG2, bgMask_KNN, background;
	Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));

	namedWindow("highway_test", WINDOW_AUTOSIZE);
	namedWindow("background_mask_by_MOG2", WINDOW_AUTOSIZE);

	Ptr<BackgroundSubtractor> ptrMOG2 = createBackgroundSubtractorMOG2();

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

		ptrMOG2->apply(frame, bgMask_MOG2);
		morphologyEx(bgMask_MOG2, bgMask_MOG2, MORPH_OPEN, kernel);

		imshow("background_mask_by_MOG2", bgMask_MOG2);
		write.write(bgMask_MOG2);
		char c = waitKey(50);
		if (c == 27) {
			break;
		}
	}
	//waitKey(0);
	write.release();
	video.release();
	cv::destroyWindow("video");
	return 0;
}

         

 

                        

 

KNN

KNN算法,即K-nearest neigbours - based Background/Foreground Segmentation Algorithm。2006年,由Zoran Zivkovic 和Ferdinand van der Heijden在论文"Efficient adaptive density estimation per image pixel for the task of background subtraction."中提出。

Ptr<BackgroundSubtractor> ptrKNN = createBackgroundSubtractorKNN();
ptrKNN->apply(frame, bgMask_KNN);

完整代码,可以读取视频,写入视频,并提取前后景

//以下代码用OpenCV实现了视频中背景消除和提取的建模,涉及到KNN(K近邻算法)
#include <iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/opencv.hpp>
#include<cstdio>
using namespace std;
using namespace cv;



int main()
{
	VideoCapture video = VideoCapture("F:\\计算机视觉\\c5.mp4");

	VideoWriter write;
	double fps = video.get(CV_CAP_PROP_FPS); //获取视频帧率
	double pauseTime = 1000 / fps; //两幅画面中间间隔
	int w = static_cast<int>(video.get(CV_CAP_PROP_FRAME_WIDTH));
	int h = static_cast<int>(video.get(CV_CAP_PROP_FRAME_HEIGHT));
	cv::Size S(w, h);

	write.open("testKNNMASK.avi", -1, fps, S, true);
	if (!video.isOpened()) {
		cout << "could not load video file ..." << endl;
		return -1;
	}

	Mat frame, bgMask_KNN, background;

	namedWindow("highway_test", WINDOW_AUTOSIZE);
	//namedWindow("background_mask_by_MOG2", WINDOW_AUTOSIZE);
	//namedWindow("background_by_KNN", WINDOW_AUTOSIZE);
	namedWindow("background_mask_by_KNN", WINDOW_AUTOSIZE);

	Ptr<BackgroundSubtractor> ptrKNN = createBackgroundSubtractorKNN();

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

		ptrKNN->apply(frame, bgMask_KNN);
		//ptrKNN->getBackgroundImage(background);

		//imshow("background_by_KNN", background);
		imshow("background_mask_by_KNN", bgMask_KNN);
		write.write(bgMask_KNN);
		char c = waitKey(50);
		if (c == 27) {
			break;
		}
	}
	write.release();
	video.release();
	cv::destroyWindow("video");
	return 0;
}

原视频如上图所示,下面是效果视频:

 

    

 

 

 

 

 

 

 


 

  • 6
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值