本文为原创,转载请表明出处,谢谢!
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");
}
最近比较忙,等到有时间在完善这些代码,添加注释!
文章图片
文章图片
推荐阅读
- 人脸识别|【人脸识别系列】| 实现自动化妆
- 前沿论文|论文精读(Neural Architecture Search without Training)
- 深度学习|深度学习笔记总结
- 网络|简单聊聊压缩网络
- 计算机视觉|深度摄像头:一:深度了解深度摄像头
- opencv|网络爬虫入门练习
- OpenCV|【OpenCV 完整例程】89. 带阻滤波器的传递函数
- OpenCV|【OpenCV 完整例程】90. 频率域陷波滤波器
- OpenCV|【OpenCV 完整例程】91. 高斯噪声、瑞利噪声、爱尔兰噪声
- 卷积|吃透空洞卷积(Dilated Convolutions)