OpenCv之车辆统计项目

news2024/12/26 10:54:09

目录

一、加载视频

二、去除背景

三、通过形态学识别车辆

四、对车辆统计


一、加载视频

代码如下:

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 视频加载
cap = cv2.VideoCapture('2.mp4')

# 循环读取视频帧
while True:
    ret,frame = cap.read()
    if ret == True:
        cv2.imshow('video',frame)

    key = cv2.waitKey(1)
    # 用户按esc退出
    if key == 27:
        break

# 释放资源
cap.release()
cv2.destroyAllWindows()


二、去除背景

背景减除(Background Subtraction)是许多基于计算机视觉的任务中的主要预处理步骤,如果我们有完整的静止的背景帧,那么我们可以通过帧差法来计算像素差从而获得到前景对象。

但是在大多数情况下,我们可能没有这样的图像,所以我们需要从我们拥有的任何图像中提取背景。当运动物体有阴影时,由于阴影也在运动,情况会变的更加复杂,为此引入了背景减除法,通过这一方法我们能够从视频中分离出运动的物体前景,从而达到目标检测的目的。

cv2.BackgroundSubtractorMOG2()用法:

  • 这是一个以混合高斯模型为基础的前景/背景分割算法。它是 P.KadewTraKuPong 和 R.Bowden 在2001年提出的。
  • 它使用 K(K = 3 或 5)个高斯分布混合对背景像素进行建模。使用这些颜色(在整个视频中)存在时间的长短作为混合的权重。背景的颜色一般持续的时间最长,而且更加静止。
  • 在编写代码时,我们需要使用函数:mog = cv2.bgsegm.createBackgroundSubtractorMOG() 创建一个背景对象。
  • 这个函数有些可选参数,比如要进行建模场景的时间长度,高斯混合成分的数量,阈值等。将它们全部设置为默认值,然后在整个视频中我们是需要使用 mask = mog.apply(frame) 就可以得到前景的掩膜了。
  • 移动的物体会被标记为白色,背景会被标记为黑色的。
     

代码如下:

cap = cv2.VideoCapture('video.mp4')

bgsubmog = cv2.bgsegm.createBackgroundSubtractorMOG()

while True:
    ret, frame = cap.read()
    
    if(ret == True):
        # 灰度处理
        cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # 高斯去噪
        blur = cv2.GaussianBlur(frame, (3, 3), 5)
        mask = bgsubmog.apply(blur)
        cv2.imshow('video', mask)
        
    key = cv2.waitKey(1)
    if(key == 27):                  # Esc退出
        break

cap.release()
cv2.destroyAllWindows()

 

三、通过形态学识别车辆

代码如下:

 

cap = cv2.VideoCapture('video.mp4')

bgsubmog = cv2.bgsegm.createBackgroundSubtractorMOG()

# 形态学kernel
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))

while True:
    ret, frame = cap.read()
    
    if(ret == True):
        # 灰度处理
        cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # 高斯去噪
        blur = cv2.GaussianBlur(frame, (3, 3), 5)
        mask = bgsubmog.apply(blur)
        # 腐蚀
        erode = cv2.erode(mask, kernel)
        # 膨胀
        dilate = cv2.dilate(erode, kernel, 3)
        # 闭操作
        close = cv2.morphologyEx(dilate, cv2.MORPH_CLOSE, kernel)
        close = cv2.morphologyEx(close, cv2.MORPH_CLOSE, kernel)
        
        contours, h = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE,)
        
        for (i, c) in enumerate(contours):
            (x, y, w, h) = cv2.boundingRect(c)
            cv2.rectangle(frame, (x, y), (x+w, y+h), (0,0,255), 2)
            
        cv2.imshow('video', frame)
        
    
    key = cv2.waitKey(1)
    if(key == 27):                  # Esc退出
        break

cap.release()
cv2.destroyAllWindows()

 

 根据图中效果来看,会出现很多小的检测框,接下来就是处理重合检测框以及去掉一些多余的检测框,类似于去重

四、对车辆统计

import cv2
import numpy as np
import matplotlib.pyplot as plt


# 去除背景
cap = cv2.VideoCapture('2.mp4')

bgsubmog = cv2.bgsegm.createBackgroundSubtractorMOG()
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))

min_w = 90
min_h = 90

line_high = 600
# 设置一个偏移量
offset = 7

cars = []
# 车的数量
car_num = 0
# 计算外接矩形的中心点
def center(x,y,w,h):
    x1 = int(w/2)
    y1 = int(h/2)
    cx = int(x) + x1
    cy = int(y) + y1
    return cx,cy
while True:
    ret, frame = cap.read()

    if (ret == True):
        # 灰度处理
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # 高斯去噪
        blur = cv2.GaussianBlur(gray, (3, 3), 5)
        mask = bgsubmog.apply(blur)
        # cv2.imshow('video', mask)

        #腐蚀操作
        erode = cv2.erode(mask,kernel)
        # 膨胀
        dialte = cv2.dilate(erode,kernel,iterations=2)
        # 消除内部方块
        # 闭运算(先膨胀再腐蚀)
        close = cv2.morphologyEx(dialte,cv2.MORPH_CLOSE,kernel)

        #查找轮廓
        result,contours,h = cv2.findContours(close,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

        # 画出检测线
        cv2.line(frame,(10,line_high),(1200,line_high),(255,255,0),3)

        #画出所有检测的轮廓
        for contour in contours:
            #画出最大外接矩形
            (x,y,w,h) = cv2.boundingRect(contour)
            # 判断外接矩形的宽高大小来过滤掉小矩形
            is_valid = (w >= min_w) & (h >= min_h)
            if not is_valid:
                continue
            #代码能走到这表示是符合要求的车
            # 要求坐标点都是整数
            # 画出矩形
            cv2.rectangle(frame,(int(x),int(y)),(int(x+w),int(y+h)),(0,0,255),2)

            # 把车抽象为一点,即外接矩形的中心点
            cpoint = center(x,y,w,h)
            cars.append(cpoint)
            cv2.circle(frame,(cpoint),5,(0,0,255),-1)
            # 判断汽车是否过检测线
            for (x,y) in cars:
                if y > (line_high - offset) and y < (line_high + offset):
                    #落入有效区间
                    #计数+1
                    car_num+=1
                    cars.remove((x,y))
        cv2.putText(frame,'Vehicle Count:' + str(car_num),(500,60),cv2.FONT_HERSHEY_SIMPLEX,2,(0,0,255),5)
        cv2.imshow('frame',frame)



    key = cv2.waitKey(1)
    if (key == 27):  # Esc退出
        break

# 释放资源
cap.release()
cv2.destroyAllWindows()

运行结果如下:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/779190.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Vue】day03-VueCli(脚手架)

day03 一、今日目标 1.生命周期 生命周期介绍 生命周期的四个阶段 生命周期钩子 声明周期案例 2.综合案例-小黑记账清单 列表渲染 添加/删除 饼图渲染 3.工程化开发入门 工程化开发和脚手架 项目运行流程 组件化 组件注册 4.综合案例-小兔仙首页 拆分模块-局部…

Java-API简析_java.net.Proxy类(基于 Latest JDK)(浅析源码)

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/131881661 出自【进步*于辰的博客】 因为我发现目前&#xff0c;我对Java-API的学习意识比较薄弱…

Element Ui 时间组件

很多时候在我们做项目的时候一般都会用到时间组件&#xff0c;其次js中&#xff1a;new dateNow new Date();得到的是Thu Jul 28 2022 15:04:32 GMT0800 (中国标准时间)&#xff0c;都需要去转换自己需要的时间格式。 接下来介绍Element Ui中的一个组件: <el-date-picker…

windows 服务器允许 ping

打开 Widnows 防火墙&#xff0c;高级 – 入站规则 找到以下 4 条规则&#xff0c;一条一条的点击右边的 &#xff1a; 启用规则 文件和打印机共享(回显请求 - ICMPv4-In) 文件和打印机共享(回显请求 - ICMPv6-In) 虚拟机监控(回显请求 - ICMPv6-In) 虚拟机监控(回显请求- IC…

【Linux网络编程】- 认识 ‘’协议‘‘ | 网络版本计算器

目录 一、“协议” 的概念 二、结构化数据的传输 三、序列化和反序列化 序列化和反序列化的目的 四、网络版本计算器 服务端&#xff08;server&#xff09; 协议定制&#xff08;protocal&#xff09; 客户端&#xff08;client&#xff09; 服务器处理请求逻辑&#…

【Unity3D】地面网格特效

1 前言 本文实现了地面网格特效&#xff0c;包含以下两种模式&#xff1a; 实时模式&#xff1a;网格线宽度和间距随相机的高度实时变化&#xff1b;分段模式&#xff1a;将相机高度分段&#xff0c;网格线宽度和间距在每段中对应一个值。 本文完整资源见→Unity3D地面网格特效…

C++ —— 类与对象(上)

前言 由于C在C语言的基础上移植了新的编程理念&#xff0c;所以我们先回顾一下C语言所遵循的旧的理念。一般来说&#xff0c;计算机语言要处理两个概念——数据和算法。数据是程序使用和处理的信息&#xff0c;而算法是程序使用的方法。C语言与当前最主流的语言一样&#xff0…

关于 Qt中的QString内容存在\u0000使用QChart(0x00)消除 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/131860574 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软…

Maven 基础之简介,基础配置

Maven 基本概念 Maven 是基于项目对象模型&#xff08;Project Object Model&#xff09;&#xff0c;可以通过一小段描述信息来管理项目的构建&#xff0c;报告和文档的软件项目管理工具。 Maven 主要有 2 个功能&#xff1a;「项目构建」和「依赖管理」。 &#x1f58b; 说…

Godot 4 源码分析 - 增加管道通信

学习研究Godot 4&#xff0c;很爽&#xff0c;虽然很庞杂&#xff0c;但相对于自己的水平来说&#xff0c;很强大&#xff0c;尤其是vulkan这块直接打包可用&#xff0c;省得自己从头琢磨。 一点一点地消化、优化与完善&#xff0c;最终才能成为自己的。 这段时间就在Godot的…

POSIX线程编程

死在山野的风里&#xff0c;活在自由的梦里 本专栏参考教材是四川轻化工大学陈年老师的linux实验指导手册&#xff08;含学习通的一些程序笔记&#xff09;。 POSIX线程编程 1.线程是什么2.创建线程创建一个用户级的线程&#xff0c;实现在线程中更改进程&#xff08;主线程&a…

Bean小结

Bean是Spring框架中最核心的两个概念之一&#xff08;另一个是面向切面编程AOP&#xff09;。 Bean 定义 Spring 官方文档对 bean 的解释是&#xff1a; In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC contain…

从Vue2到Vue3【三】——Composition API(第三章)

系列文章目录 内容链接从Vue2到Vue3【零】Vue3简介从Vue2到Vue3【一】Composition API&#xff08;第一章&#xff09;从Vue2到Vue3【二】Composition API&#xff08;第二章&#xff09;从Vue2到Vue3【三】Composition API&#xff08;第三章&#xff09;从Vue2到Vue3【四】C…

webrtc QOS方法二.4(flexfec 实现可优化点)

一、冗余报文和媒体报文组织结构优化点 以单帧10个媒体报文&#xff0c;冗余度20%为例。这里webrtc输出要有10个媒体包2个冗余包。webrtc输出的报文序列如下&#xff1a; 代码实现如下&#xff1a; UlpfecGenerator::AddPacketAndGenerateFec&#xff1a;攒够足够的帧 Forwar…

使用springboot进行后端开发100问

properties和yaml文件怎么互转 安装插件 properties文件和yaml文件区别 properties 文件通过“.”和“”赋值&#xff0c;值前不加空格&#xff0c;yaml通过“:”赋值&#xff0c;值前面加一个空格&#xff1b;yaml文件缩进用空格&#xff1b; properties只支持键值对&#x…

C++实现LRU(逐句讲解)

使用双向链表解决此问题&#xff0c;因为双向链表可以很容易的获取到头结点和尾结点。题目要求 get 和 put 要在O(1)的时间复杂度下运行&#xff0c;很显然要用set或map。根据题意&#xff0c;应使用map。 unordered_map<int,Node*> cache; map->first为Node中的key&a…

查看RabbitMQ日志---trace插件的使用

我的RabbitMQ是安装在docker里面的 所以我以下的方法都是根据这个路径去操作的 如果RabbitMQ安装在其他地方 请自行百度 1. 显示正在运行的RabbitMQ容器的名称或ID&#xff1a; docker ps这将启动所有正在运行的 Docker 容器&#xff0c;并包含 RabbitMQ 容器的信息。 使用…

【Docker】Docker的数据管理

目录 一、Docker 的数据管理1.1数据卷1.2 数据卷容器1.3端口映射1.4容器互联&#xff08;使用centos镜像&#xff09; 二、Docker镜像的创建2.1基于现有镜像创建2.2&#xff0e;基于本地模板创建2.3 基于Dockerfile 创建联合文件系统&#xff08;UnionFS&#xff09;镜像加载原…

【云原生】Docker网络及Cgroup资源控制

一、Docker网络 1.docker网络实现原理 Docker使用Linux桥接&#xff0c;在宿主机虚拟一个Docker容器网桥(docker0)&#xff0c;Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址&#xff0c;称为Container-IP&#xff0c;同时Docker网桥是每个容器的默认网关。…

【Linux网络】 网络套接字(二)socket编程_UDP网络程序

目录 socket 编程接口socket 常见的APIsockaddr结构 UDP网络程序简单例子服务端代码编写服务端创建套接字服务端绑定运行服务器测试启动服务端 客户端代码编写客户端创建套接字启动客户端本地测试INADDR_ANY服务端接收信息发回到客户端如何进行网络测试 socket 编程接口 socke…