opencv:动态目标检测--BackgroundSubtractorMOG2 C++

BackgroundSubtractorMOG2基于自适应混合高斯背景建模,具有一定的抗光照干扰的能力,参数配置如下

Ptr<BackgroundSubtractorMOG2> bgsubtractor = createBackgroundSubtractorMOG2();
// 用于训练背景的帧数,如果不手动设置learning rate,history就被用于计算当前的learning rate,
// history越大,learning rate越低,背景更新越慢
bgsubtractor->setHistory(500);
// 方差阈值,主要用于判断前景还是背景,值越大,灵敏度越低
// 如果光照变化明显,如阳光下的水面,建议设为25,36
bgsubtractor->setVarThreshold(16);
// 是否检测有影子,开启后会增加算法复杂度
bgsubtractor->setDetectShadows(true);
// 高斯模型个数,默认5个,最多8个
bgsubtractor->setBackgroundRatio(4);
// 高斯背景模型权重和阈值,nmixtures个模型按权重重排序后,
// 只取模型权重累加值大于backgroundRatio的前几个作为背景模型
bgsubtractor->setNMixtures(5);
// 新建高斯模型的方差初始值,默认15
bgsubtractor->setVarInit(15);
// 背景更新时,用于限制高斯模型方差的最大值,默认20
bgsubtractor->setVarMax(20);
// 背景更新时,用于限制高斯模型方差的最小值,默认4
bgsubtractor->setVarMin(4);
// 方差阈值,用于已经存在的匹配的模型,如果不存在则新建一个
bgsubtractor->setVarThresholdGen(100);
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>

using namespace std;
using namespace cv;

//图像分割
int labelTargets(Mat& src, Mat& mask, int thresh = 100);

int main()
{
	const char* fn = "D:\\vs-projects\\moving\\vtest.avi";
	VideoCapture cap;
	Mat source, image, foreGround, backGround, fgMask;
	Ptr<BackgroundSubtractorMOG2> pBgModel = createBackgroundSubtractorMOG2();
	pBgModel->setHistory(20);
	pBgModel->setVarThreshold(100);
	pBgModel->setDetectShadows(false);

	//打开视频
	cap.open(fn);
	if (!cap.isOpened())
	{
		cout << "无法打开视频文件:" << fn << endl;
		return;
	}

	for (;;)
	{
		//获取视频帧
		cap >> source;
		if (source.empty())
			break;
		resize(source, image, Size(source.cols / 2, source.rows / 2), INTER_LINEAR);
		//转为灰度图
		//cvtColor(image, image, COLOR_BGR2GRAY);
		
		if (foreGround.empty())
			foreGround.create(image.size(), image.type());
		
		//背景更新
		pBgModel->apply(image, fgMask);

		//图像处理
		GaussianBlur(fgMask, fgMask, Size(5, 5), 0);
		threshold(fgMask, fgMask, 30, 255, THRESH_BINARY);

		foreGround = Scalar::all(0);
		//image和fgMask重叠以后把fgMask像素值为0对应image中的点变为透明,而保留其他点
		image.copyTo(foreGround, fgMask);

		//imshow("src", foreGround);
		//waitKey(20);

		//标记找到的运动目标
		int nTargets = labelTargets(image, fgMask);
		//cout << "共检测到" << nTargets << "个目标" << endl;
	 }
	
}
int labelTargets(Mat& src, Mat& mask, int thresh)
{
	//以下是图像分割
	Mat seg = mask.clone();
	vector<vector<Point>> cnts;
	findContours(seg, cnts, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

	//以下进行筛选
	float area;
	Rect rect;
	int count = 0;
	string strCount;
	for (int i = cnts.size() - 1; i >= 0; i--)
	{
		vector<Point> c = cnts[i];
		area = contourArea(c);
		if (area < thresh)
			continue;
		count++;
		//包围特征点的矩形框的坐标和长宽信息
		rect = boundingRect(c);
		//输出矩形框的坐标和面积
		cout << "位置:(" << rect.x << "," << rect.y << ")面积:" << rect.width * rect.height << endl;
		//在原图上画出矩形框
		rectangle(src, rect, Scalar(0, 0, 0xff), 1);

		stringstream ss;
		ss << count;
		ss >> strCount;
		putText(src, strCount, Point(rect.x, rect.y), CV_FONT_HERSHEY_PLAIN, 0.5, Scalar(0, 0xff, 0));

		imshow("src", src);
		waitKey(20);
	}
	return count;
}
  • 7
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,cv2.error是OpenCV库中的一个错误类型。在引用中,报错信息是"OpenCV(4.8.0) D:\a\opencv-python\opencv-python\opencv\modules\core\src\alloc.cpp:73: error: (-4:Insufficient memory)",意味着内存不足。而在引用中,报错信息是"OpenCV(4.8.0) D:\a\opencv-python\opencv-2:Unspecified error) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Cocoa support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function 'cvShowImage'",意味着函数未实现或缺少相关支持库。 这些错误通常是由于OpenCV库的版本不匹配或者缺少相关依赖库引起的。解决这些错误的方法如下: 1. 内存不足错误: - 检查系统内存使用情况,确保有足够的可用内存。 - 如果内存不足,可以尝试释放一些内存或者增加系统内存。 - 如果问题仍然存在,可以尝试降低图像或数据的分辨率,以减少内存使用量。 2. 函数未实现或缺少支持库错误: - 确认OpenCV库的版本是否与代码兼容。如果版本不匹配,可以尝试升级或降级OpenCV库。 - 检查是否缺少相关的支持库。根据错误信息中提到的支持库,可以尝试安装libgtk2.0-dev和pkg-config等库,并重新运行cmake或配置脚本。 请注意,具体的解决方法可能因具体情况而异。建议根据错误信息中提供的详细信息和您的系统环境进行进一步调查和尝试。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值