基于opencv的BackgroundSubtractorMOG2和BackgroundSubtractorKNN通过背景减除来实现目标追踪
原标题:基于opencv的BackgroundSubtractorMOG2和BackgroundSubtractorKNN通过背景减除来实现目标追踪
原文来自:CSDN 原文链接:https://blog.csdn.net/ding_programmer/article/details/102881342
背景减除(Background Subtraction)是许多基于计算机视觉的任务中的主要预处理步骤。如果我们有完整的静止的背景帧,那么我们可以通过帧差法来计算像素差从而获取到前景对象。但是在大多数情况下,我们可能没有这样的图像,所以我们需要从我们拥有的任何图像中提取背景。当运动物体有阴影时,由于阴影也在移动,情况会变的变得更加复杂。为此引入了背景减除算法,通过这一方法我们能够从视频中分离出运动的物体前景,从而达到目标检测的目的。
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算法,即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; }
原视频如上图所示,下面是效果视频:
免责声明:本文来自互联网新闻客户端自媒体,不代表本网的观点和立场。
合作及投稿邮箱:E-mail:editor@tusaishared.com
热门资源
Python 爬虫(二)...
所谓爬虫就是模拟客户端发送网络请求,获取网络响...
TensorFlow从1到2...
原文第四篇中,我们介绍了官方的入门案例MNIST,功...
TensorFlow从1到2...
“回归”这个词,既是Regression算法的名称,也代表...
机器学习中的熵、...
熵 (entropy) 这一词最初来源于热力学。1948年,克...
TensorFlow2.0(10...
前面的博客中我们说过,在加载数据和预处理数据时...
智能在线
400-630-6780
聆听.建议反馈
E-mail: support@tusaishared.com