服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - OpenCV基于背景减除实现行人计数

OpenCV基于背景减除实现行人计数

2022-08-17 10:24Zero___Chen C/C++

本文主要介绍了如何使用OpenCV C++对视频中的人流量进行统计。文中的示例代码讲解详细,对我们学习OpenCV有一定的帮助,需要的可以了解一下

前言

本文将使用OpenCV C++ 对视频中的人流量进行统计。

一、图像预处理

OpenCV基于背景减除实现行人计数

原图如图所示。本案例的需求是想要统计画面中的人流量。画面中走动的行人可以看作是前景,那么我们就需要将前景、背景分割出来。我们可以使用OpenCV提供的BackgroundSubtractorMOG2 高斯混合模型,将行人从画面中分割出来,然后提取轮廓就可以统计人流量了。

Ptr<BackgroundSubtractorMOG2>MOG = createBackgroundSubtractorMOG2();
MOG->apply(frame, mask);

OpenCV基于背景减除实现行人计数

使用上面两行代码就可以创建高斯混合背景提取器。传入原图,返回背景减除结果。如上图所示。接下来只需对上图进行一些简单操作,再提取轮廓就可以进行人流统计了。

threshold(mask, mask, 200, 255, THRESH_BINARY );

morphologyEx(mask, mask, MORPH_OPEN, kernel);

dilate(mask, mask, kernel1);

进行二值化、形态学等操作可以将行人作为一个独立个体分割出来。效果如图。

OpenCV基于背景减除实现行人计数

 

二、对象计数

1.轮廓提取

将上面的二值图像进行轮廓检测,然后统计有效轮廓就可以完成对象计数了。

    vector<vector<Point>>contours;
  vector<vector<Point>>EffectiveContours;    
  findContours(mask, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
  for (int i = 0; i < contours.size(); i++)
  {            
      double area = contourArea(contours[i]);
  
      if (area > 300)
      {        
          EffectiveContours.push_back(contours[i]);
      }
      
  }

2.效果显示

	char text[10];
	for (int i = 0; i < EffectiveContours.size(); i++)
	{
		RotatedRect rect = minAreaRect(EffectiveContours[i]);

		Rect box = rect.boundingRect();

		rectangle(frame, Rect(box.x, box.y, box.width, box.height), Scalar(0, 255, 0), 2);

		sprintf_s(text, "%s%d", "Current:", EffectiveContours.size());

		putText(frame, text, Point(10, 30), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 255, 0), 2);
	}

OpenCV基于背景减除实现行人计数

最终效果如图所示。

 

三、源码

#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main()
{

	VideoCapture capture;
	capture.open("1.avi");

	if (!capture.isOpened())
	{
		cout << "Can not open video source!" << endl;
		system("pause");
		return -1;
	}

	Ptr<BackgroundSubtractorMOG2>MOG = createBackgroundSubtractorMOG2();

	Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 5));
	Mat kernel1 = getStructuringElement(MORPH_RECT, Size(7, 3));

	Mat frame, mask;
	while (capture.read(frame))
	{
		MOG->apply(frame, mask);

		threshold(mask, mask, 200, 255, THRESH_BINARY );

		morphologyEx(mask, mask, MORPH_OPEN, kernel);

		dilate(mask, mask, kernel1);

		vector<vector<Point>>contours;
		vector<vector<Point>>EffectiveContours;	
		findContours(mask, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
		for (int i = 0; i < contours.size(); i++)
		{			
			double area = contourArea(contours[i]);

			if (area > 300)
			{		
				EffectiveContours.push_back(contours[i]);
			}
			
		}

		char text[10];
		for (int i = 0; i < EffectiveContours.size(); i++)
		{
			RotatedRect rect = minAreaRect(EffectiveContours[i]);

			Rect box = rect.boundingRect();

			rectangle(frame, Rect(box.x, box.y, box.width, box.height), Scalar(0, 255, 0), 2);

			sprintf_s(text, "%s%d", "Current:", EffectiveContours.size());

			putText(frame, text, Point(10, 30), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 255, 0), 2);
		}
		imshow("frame", frame);
		imshow("mask", mask);

		char key = waitKey(10);
		if (key == 27)
		{
			break;
		}
	}

	destroyAllWindows();
	capture.release();
	system("pause");
	return 0;
}

 

总结

本文使用OpenCV C++ 基于背景减除进行人流计数,关键步骤有以下几点。

1、使用BackgroundSubtractorMOG2 将前景从背景中分割出来。

2、将分割出来的前景进行轮廓提取,从而统计出人流量。

到此这篇关于OpenCV基于背景减除实现行人计数的文章就介绍到这了,更多相关OpenCV行人计数内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/Zero___Chen/article/details/122268185

延伸 · 阅读

精彩推荐
  • C/C++C++类基本语法实例分析

    C++类基本语法实例分析

    这篇文章主要介绍了C++类基本语法实例分析,非常适合初学者学习借鉴,需要的朋友可以参考下...

    C++教程网5712021-01-29
  • C/C++C/C++语言中的头文件汇总

    C/C++语言中的头文件汇总

    这篇文章主要汇总了C/C++语言中的头文件,方便各位朋友更好的工作和学习,有需要的朋友可以参考下...

    刘XX8862021-09-09
  • C/C++C语言实现24点游戏源代码

    C语言实现24点游戏源代码

    这篇文章主要为大家详细介绍了C语言实现24点游戏源代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    andywen00903652021-08-04
  • C/C++C++动态数组类的封装实例

    C++动态数组类的封装实例

    这篇文章主要介绍了C++动态数组类的封装,很重要的概念,需要的朋友可以参考下...

    C++教程网11152021-01-28
  • C/C++详解C++编程中断言static_assert的使用

    详解C++编程中断言static_assert的使用

    这篇文章主要介绍了C++编程中断言static_assert的使用,断言在debug时非常有用,是C++入门学习中的基础知识,需要的朋友可以参考下...

    C++教程网4732021-03-23
  • C/C++Visual Studio Code上添加小程序自动补全插件的操作方法

    Visual Studio Code上添加小程序自动补全插件的操作方法

    这篇文章主要介绍了Visual Studio Code上添加小程序自动补全插件的操作方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要...

    Space Tripper6512021-10-29
  • C/C++C语言之初始if语句详解

    C语言之初始if语句详解

    本文主要介绍C语言中的if语句,这里详细介绍了if 语句并提供了简单的示例代码,希望能帮助编程入门的小伙伴学习,希望能够给你带来帮助...

    涛声依旧灬11922021-12-24
  • C/C++vc提示unexpected end of file found的原因分析

    vc提示unexpected end of file found的原因分析

    这篇文章主要介绍了vc提示unexpected end of file found的原因分析,给出了几点常见错误原因的分析,需要的朋友可以参考下...

    好人一个9642021-02-26