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

目录
  • 前言
  • 一、图像预处理
  • 二、对象计数
    • 1.轮廓提取
    • 2.效果显示
  • 三、源码
  • 总结

前言

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

一、图像预处理

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

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

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

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

morphologyEx(mask, mask, MORPH_OPEN, kernel);

dilate(mask, mask, kernel1);

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

二、对象计数

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);
	}

最终效果如图所示。

三、源码

#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行人计数内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python+OpenCV内置方法实现行人检测

    您是否知道 OpenCV 具有执行行人检测的内置方法? OpenCV 附带一个预训练的 HOG + 线性 SVM 模型,可用于在图像和视频流中执行行人检测. 今天我们使用Opencv自带的模型实现对视频流中的行人检测,只需打开一个新文件,将其命名为 detect.py ,然后加入代码: # import the necessary packages from __future__ import print_function import numpy as np import argparse i

  • 使用OpenCV实现道路车辆计数的使用方法

    今天,我们将一起探讨如何基于计算机视觉实现道路交通计数. 在本教程中,我们将仅使用Python和OpenCV,并借助背景减除算法非常简单地进行运动检测. 我们将从以下四个方面进行介绍: 1. 用于物体检测的背景减法算法主要思想. 2. OpenCV图像过滤器. 3. 利用轮廓检测物体. 4. 建立进一步数据处理的结构. 背景扣除算法 有许多不同的背景扣除算法,但是它们的主要思想都很简单. 假设有一个房间的视频,在某些帧上没有人和宠物,那么此时的视频基本为静态的,我们将其称为背景(backgrou

  • 基于opencv的行人检测(支持图片视频)

    基于方向梯度直方图(HOG)/线性支持向量机(SVM)算法的行人检测方法中存在检测速度慢的问题,如下图所示,对一张400*490像素的图片进行检测要接近800毫秒,所以hog+svm的方法放在视频中进行行人检测时,每秒只能检测1帧图片,1帧/s根本不能达到视频播放的流畅性. 本文采用先从视频每帧的图像中提取出物体的轮廓(也可以对前后两针图片做差,只对有变化的部分进行检测,其目的一样,都是减少运算的面积),再对每个轮廓进行HOG+SVM检测,判断是否为行人.可以大大的缩减HOG+SVM的面积,经实

  • opencv实现机器视觉检测和计数的方法

    引言 在机器视觉中,有时需要对产品进行检测和计数.其难点无非是对于产品的图像分割. 由于之前网购的维生素片,有时候忘了今天有没有吃过,就想对瓶子里的药片计数...在学习opencv以后,希望实现对于维生素片分割计数算法.本次实战在基于形态学的基础上又衍生出基于距离变换的分水岭算法,使其实现的效果更具普遍性. 基于形态学的维生素片检测和计数 整体思路: 读取图片 形态学处理(在二值化前进行适度形态学处理,效果俱佳) 二值化 提取轮廓(进行药片分割) 获取轮廓索引,并筛选所需要的轮廓 画出轮廓,显示

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

    目录 前言 一.图像预处理 二.对象计数 1.轮廓提取 2.效果显示 三.源码 总结 前言 本文将使用OpenCV C++ 对视频中的人流量进行统计. 一.图像预处理 原图如图所示.本案例的需求是想要统计画面中的人流量.画面中走动的行人可以看作是前景,那么我们就需要将前景.背景分割出来.我们可以使用OpenCV提供的BackgroundSubtractorMOG2 高斯混合模型,将行人从画面中分割出来,然后提取轮廓就可以统计人流量了. Ptr<BackgroundSubtractorMOG2>

  • OpenCV利用背景建模检测运动物体

    本文实例为大家分享了OpenCV利用背景建模检测运动物体的具体代码,供大家参考,具体内容如下 #include <opencv\highgui.h> #include <stdio.h> int main( int argc, char** argv ){ IplImage* pFrame = NULL; IplImage* pFrImg = NULL; IplImage* pBkImg = NULL; CvMat* pFrameMat = NULL; CvMat* pFrMat

  • 详解opencv去除背景算法的方法比较

    目录 背景减除法 (1)BackgroundSubtractorMOG (2)BackgroundSubtractorMOG2 (3)BackgroundSubtractorGMG 帧差法 最近做opencv项目时,使用肤色分割的方法检测目标物体时,背景带来的干扰非常让人头痛.于是先将背景分割出去,将影响降低甚至消除.由于初次接触opencv,叙述不当的地方还请指正. 背景减除法 (以下文字原文来源于https://docs.opencv.org/3.4.7/d8/d38/tutorial_bg

  • OpenCV实现背景分离(证件照背景替换)

    目录 实现原理 功能函数代码 C++测试代码 完整改进代码 本文主要介绍了OpenCV实现背景分离(证件照背景替换),具有一定的参考价值,感兴趣的可以了解一下 实现原理 图像背景分离是常见的图像处理方法之一,属于图像分割范畴.如何较优地提取背景区域,难点在于两个: 背景和前景的分割.针对该难点,通过人机交互等方法获取背景色作为参考值,结合差值均方根设定合理阈值,实现前景的提取,PS上称为蒙版:提取过程中,可能会遇到前景像素丢失的情况,对此可通过开闭运算或者提取外部轮廓线的方式,将前景内部填充完毕

  • OpenCV基于距离变换和分水岭实现图像分割

    目录 一.图像分割 二.基于距离变换和分水岭的图像分割 代码实现 图像处理效果 一.图像分割 图像分割是根据灰度.颜色.纹理和形状等特征,把图像分成若干个特定的.具有独特性质的区域,这些特征在同一区域内呈现出相似性,而在不同区域间呈现出明显的差异性,并提出感兴趣目标的技术和过程. 它是由图像处理到图像分析的关键步骤.从数学角度来看,图像分割是将数字图像划分成互不相交的区域的过程.图像分割的过程也是一个标记过程,即把属于同一区域的像索赋予相同的编号. 其目的是将图像中像素根据一定的规则分为若干(N

  • C#实现基于加减按钮形式控制系统音量及静音的方法

    本文实例讲述了C#实现基于加减按钮形式控制系统音量及静音的方法.分享给大家供大家参考.具体如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices

  • opencv平均背景法详解

    本文实例为大家分享了opencv平均背景法的具体代码,供大家参考,具体内容如下 #include<opencv2/opencv.hpp> #include<opencv2/highgui/highgui.hpp> #include<opencv2/imgproc/imgproc.hpp> using namespace std; using namespace cv; IplImage *IavgF, *IdiffF, *IprevF, *IhiF, *IlowF; I

  • Python OpenCV 基于图像边缘提取的轮廓发现函数

    基础知识铺垫 在图像中,轮廓可以简单的理解为连接具有相同颜色的所有连续点(边界)的曲线,轮廓可用于形状分析和对象检测.识别等领域. 轮廓发现的原理:先通过阈值分割提取目标物体,再通过边缘检测提取目标物体轮廓. 一个轮廓就是一系列的点(像素),这些点构成了一个有序的点集合. 使用 cv2.findContours 函数可以用来检测图像的边缘. 函数原型说明 contours, hierarchy = cv2.findContours(image, mode, method[, contours[,

  • Python OpenCV基于霍夫圈变换算法检测图像中的圆形

    目录 第一章:霍夫变换检测圆 ① 实例演示1 ② 实例演示2 ③ 霍夫变换函数解析 第二章:Python + opencv 完整检测代码 ① 源代码 ② 运行效果图 第一章:霍夫变换检测圆 ① 实例演示1 这个是设定半径范围 0-50 后的效果. ② 实例演示2 这个是设定半径范围 50-70 后的效果,因为原图稍微大一点,半径也大了一些. ③ 霍夫变换函数解析 cv.HoughCircles() 方法 参数分别为:image.method.dp.minDist.param1.param2.mi

  • Python Opencv基于透视变换的图像矫正

    本文实例为大家分享了Python Opencv基于透视变换的图像矫正,供大家参考,具体内容如下 一.自动获取图像顶点变换(获取图像轮廓顶点矫正) 图像旋转校正思路如下 1.以灰度图读入2.腐蚀膨胀,闭合等操作3.二值化图像4.获取图像顶点5.透视矫正 #(基于透视的图像矫正) import cv2 import math import numpy as np def Img_Outline(input_dir):     original_img = cv2.imread(input_dir)

随机推荐