计算机视觉|基于opencv的BackgroundSubtractorMOG2目标追踪

本文为原创,转载请表明出处,谢谢!
BackgroundSubtractorMOG2是以高斯混合模型为基础的背景/前景分割算法。它是以2004年和2006年Z.Zivkovic的两篇文章为基础的。这个算法的一个特点是它为每一个像素选择一个合适数目的高斯分布。(上一个方法中我们使用是K高斯分布)。这样就会对由于亮度等发生变化引起的场景变化产生更好的适应。和前面一样我们需要创建一个背景对象。但在这里我们我们可以选择是否检测阴影。如果detectShadows = True(默认值),它就会检测并将影子标记出来,但是这样做会降低处理速度。影子会被标记为灰色。
这里我们采用opencv实现视频追踪,对于opencv的安装、配置和使用,网上有很多教程,我们这里就不在说明。如果你对opencv不太了解,请自行查资料学习。话归正题,这里我将会分别从Python和c++实现BackgroundSubtractorMOG2,我使用的是opencv3.1linux版本。
Python代码:

import numpy as np import cv2 import time import datetimecap = cv2.VideoCapture(0)kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3)) fgbg = cv2.createBackgroundSubtractorMOG2() fourcc = cv2.VideoWriter_fourcc(*'XVID') frame1 = np.zeros((640,480)) out = cv2.VideoWriter(datetime.datetime.now().strftime("%A_%d_%B_%Y_%I_%M_%S%p")+'.avi',fourcc, 5.0, np.shape(frame1))while(1): ret, frame = cap.read() fgmask = fgbg.apply(frame) (_,cnts, _) = cv2.findContours(fgmask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) maxArea = 0 for c in cnts: Area = cv2.contourArea(c) if Area < maxArea : #if cv2.contourArea(c) < 500: (x, y, w, h) = (0,0,0,0) continue else: if Area < 1000: (x, y, w, h) = (0,0,0,0) continue else: maxArea = Area m=c (x, y, w, h) = cv2.boundingRect(m) cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) out.write(frame) cv2.imshow('frame',frame) k = cv2.waitKey(30)&0xff if k==27: break out.release() cap.release() cv2.destoryAllWindows()

c++版本:
VideoDetect.h
#pragma once #include #include using namespace std; using namespace cv; enum VIDEOTYPE { CAMERAVIDEO/*摄像头*/,FILEVIDEO/*视频*/ }; class MOG2Detector { public: MOG2Detector(); ~MOG2Detector(); /* VIDEOTYPE 指定摄像头或者文件 path 文件路径 WindowName opencv可视化窗口名称 */ MOG2Detector(VIDEOTYPE type,char * path = "E:/image/s.avi",char * WindowName = "Video"); //开始 void startDecect(); private: char * WinName; VIDEOTYPE VideoType; cv::VideoCapture capture; cv::Ptr fgbg; };

VideoDetect.cpp:
#include "stdafx.h" #include "MOG2Detector.h"MOG2Detector::MOG2Detector() { } MOG2Detector::~MOG2Detector() {}MOG2Detector::MOG2Detector(VIDEOTYPE type, char * path, char * WindowName) { if (type == CAMERAVIDEO) { capture.open(0); } else if (type == FILEVIDEO) { capture.open("E:/image/s.avi"); } else { cout << "Type is error, you can input CAMERAVIDEO or FILEVIDEO" << endl; return; }if (!capture.isOpened()) { std::cout << "video camera capture open fail! \n" << std::endl; exit(1); }fgbg = cv::createBackgroundSubtractorMOG2(); WinName = WindowName; }void MOG2Detector::startDecect() { cv::Mat frame, fgmask; //cnts存储边缘信息 std::vector > cnts; cv::namedWindow("video", 1); while (1) { capture.read(frame); fgbg->apply(frame, fgmask); //检测每一帧边缘 findContours(fgmask, cnts, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); float Area; Rect rect; vector m; for (int i = cnts.size() - 1; i >= 0; i--) { vector【计算机视觉|基于opencv的BackgroundSubtractorMOG2目标追踪】 c = cnts[i]; //获取面积 Area = contourArea(c); if (Area < 50)//50这个值根据需求设定,这里指的是目标的大小 { continue; } else { m = c; } rect = boundingRect(m); rectangle(frame, rect, Scalar(0, 255, 0), 2); } resize(frame, frame, Size(480, 320)); imshow("video", frame); char c = waitKey(33); if (c == 27) break; } //释放资源 capture.release(); cv::destroyWindow("video"); }

最近比较忙,等到有时间在完善这些代码,添加注释!
计算机视觉|基于opencv的BackgroundSubtractorMOG2目标追踪
文章图片

计算机视觉|基于opencv的BackgroundSubtractorMOG2目标追踪
文章图片

    推荐阅读