基于opencv的车辆统计

news2024/12/29 9:53:15

车辆统计)

  • 一、项目背景
  • 二、整体流程
  • 三、常用滤波器的特点
  • 四、背景减除
  • 五、形态学
    • 开运算
    • 闭运算
  • 六、项目完整代码
  • 七、参考资料

一、项目背景

检测并识别视频中来往车辆的数量
最终效果图:

二、整体流程

  1. 加载视频
  2. 图像预处理(去噪、背景减除、形态学)
  3. 对车辆进行统计
  4. 显示车辆统计信息(增加水印)

车辆识别中首先对灰度化的视频帧进行去噪。二值化的目的是简化图像,并突出图像中的主要特征,可以减少后续处理的复杂性。
接下来用高斯模糊滤波去除不均匀的细小的噪声。常用滤波器特点总结如下:

三、常用滤波器的特点

  1. 方盒滤波(cv2.boxFilter)与均值滤波(cv2.blur)
    均值滤波需要额外的归一化过程
  2. 高斯滤波(cv2.GaussianBlur)
    高斯滤波的核心思想是让临近的像素具有更高的重要度。对周围像素计算加权平均值,较近的像素具有较大的权重值。
    尤其高斯噪声效果明显,对椒盐噪声效果不好
  3. 中值滤波(medianBlur)
    每个像素的值被替换为其邻域中所有像素值的中值,对椒盐噪音效果明显
  4. 双边滤波(bilateralFilter)
    对图像的边缘信息能更好的保存,双边滤波和高斯滤波不同的就是:双边滤波既利用了位置信息又利用了像素信息来定义滤波窗口的权重,而高斯滤波只用了位置信息。
    双边滤波可以保留边缘,同时可以对边缘内的区域进行平滑处理。
    双边滤波的作用就相当于做了美颜

四、背景减除

背景减除(Background Subtraction)是许多基于计算机视觉的任务中的主要预处理步骤。如果我们有完整的静止的背景帧,那么我们可以通过帧差法来计算像素差从而获取到前景对象。但是在大多数情况下,我们可能没有这样的图像,所以我们需要从我们拥有的任何图像中提取背景。当运动物体有阴影时,由于阴影也在移动,情况会变的变得更加复杂。为此引入了背景减除算法,通过这一方法我们能够从视频中分离出运动的物体前景,从而达到目标检测的目的。

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

得到前景掩模后,对视频帧进行开运算,以进一步除图像中的噪声、填充小孔和连接物体。

五、形态学

开运算

原理:先进行腐蚀操作,然后进行膨胀操作。腐蚀操作可以去除图像中的小细节和噪声,而膨胀操作可以保持物体的整体形状。
特点:
可以有效去除图像中的小白点(前景噪声)和连接细小的物体。
能够平滑物体的边缘并保持物体的整体形状。
可以用于断开物体之间的连接以及分割物体。

闭运算

原理:先进行膨胀操作,然后进行腐蚀操作。膨胀操作可以填充物体中的小孔和裂缝,而腐蚀操作可以保持物体的整体形状。
特点:
可以填充图像中的小孔和裂缝,使得物体更加完整。
可以连接物体之间的断裂部分,使它们形成连续的整体。
有助于平滑物体的边缘并保持其整体形状。

比较:
应用场景:开运算主要用于去除噪声和细小物体,闭运算主要用于填充小孔和连接物体。
效果:开运算更适合去除细小的噪声和连接细小的物体,闭运算更适合填充小孔和连接断裂的物体。
形状保持:两者都可以保持物体的整体形状,但开运算可能会略微削弱物体的尺寸,而闭运算则可能略微增加物体的尺寸。
在实际应用中,开运算和闭运算常常结合使用,以便达到更好的图像处理效果,例如先进行开运算去除噪声,然后进行闭运算填充孔洞,以得到更加干净和完整的物体。

图像预处理完成后,用外接矩形画出车辆轮廓,识别出的图像中较小的轮廓忽略掉。统计车辆数据时判断外接矩形的中心点是否通过检测线统计经过检测线的车辆数目。

六、项目完整代码

# 去背景
# 加载视频
import cv2
import numpy as np

cap = cv2.VideoCapture('./video.mp4')
bgsubmog = cv2.bgsegm.createBackgroundSubtractorMOG()
# 形态学kernel,相当于设置卷积核为5x5的矩形元素卷积核
kernel= cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
min_w = 90
min_h = 90
cars = []
# 检测线高, 和视频的宽高有关系
line_high = 620
# 线的偏移量
offset = 7
carno = 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)
        # 去掉了一些干扰噪声
        erode = cv2.erode(mask, kernel)
        # 再把图像还原回来, 执行膨胀操作
        dilate = cv2.dilate(erode, kernel, iterations=2)
        
        # 闭操作, 把物体内部的小块
        close = cv2.morphologyEx(dilate, cv2.MORPH_CLOSE, kernel, iterations=2)
        
        # 查找轮廓
        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 (i, c) in enumerate(contours):
            (x, y, w, h) = cv2.boundingRect(c)
            cv2.rectangle(frame, (int(x), int(y)), (int(x + w), int(y + h)), (0, 0, 255), 2)
            
            # 通过外接矩形的宽高大小来过滤掉小轮廓.
            is_valid = (w >= min_w) and (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
                    carno += 1
                    cars.remove((x, y))
                    print(carno)
        # 打印计数信息
        cv2.putText(frame, 'Vehicle Count:' + str(carno), (500, 60), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0), 5)
        cv2.imshow('frame', frame)
        
    key = cv2.waitKey(10)
    if key == 'q':
        break
cap.release()
cv2.destroyAllWindows()

七、参考资料

https://blog.csdn.net/great_yzl/article/details/119645423#%E5%9F%BA%E7%A1%80%E7%90%86%E8%AE%BA
https://blog.csdn.net/qq_27261889/article/details/80822270
https://blog.csdn.net/Vermont_/article/details/108424547

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

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

相关文章

详解typora配置亚马逊云科技Amazon S3图床

欢迎免费试用亚马逊云科技产品&#xff1a;https://mic.anruicloud.com/url/1333 当前有很多不同的博客社区&#xff0c;不同的博客社区使用的编辑器也不尽相同&#xff0c;大概可以分为两种&#xff0c;一种是markdown格式&#xff0c;另外一种是富文本格式。例如华为云开发者…

【项目学习01_2024.05.08_Day06】

学习笔记 5 新增课程5.1 需求分析5.1.1 业务流程5.1.2 数据模型 5.2 接口定义5.3 接口开发5.3.1 保存课程基本信息5.3.2 保存营销信息 5.4 接口测试 5 新增课程 5.1 需求分析 5.1.1 业务流程 5.1.2 数据模型 5.2 接口定义 5.3 接口开发 根据需求分析&#xff0c;新增课程表…

Python中的类和对象的概念理解和创建方法1——基本概念的理解和具体程序实例

Python中的类和对象的概念理解和创建方法1——基本概念的理解和具体程序实例 目录 Python中的类和对象的概念理解和创建方法1——基本概念的理解和具体程序实例一、类和对象的概念二、类和对象的关系2.1 两者辩证关系2.2 两者内部的对应关系 三、类和对象的优势3.1 多态性3.2 封…

添加一个索引要投产,需要哪些步骤?

编程一生 致力于写大家都能看懂的、有深度的 技术文章 05/2024 01 开场白 亚马逊有个bar raiser文化。就是说新招来的人一定要超过之前入职人员的平均水平&#xff0c;宁缺毋滥。越来越多的公司在推行这种文化。在这种氛围下&#xff1a;“虽然我不懂&#xff0c;但是活儿是能出…

Spring自定义配置属性类

以一个minio的配置类为例 首先&#xff0c;由于minio模块被很多微服务需要&#xff0c;因此封装了一个starter&#xff0c;当背的微服务需要的时候就进行引入。 以下是starter模块的结构图 一、spring.factories文件 org.springframework.boot.autoconfigure.EnableAutoConf…

【管理篇】如何管理情绪?

目录标题 为什么要特别关注激动和愤怒两种情绪呢&#xff1f;管理自己的情绪大致的步骤三层脑结构爬行脑情绪脑视觉脑 大家说的情绪管理&#xff0c;基本上都是对于情绪激动、生气甚至是愤怒的管理&#xff1b;日常所说的情绪化&#xff0c;一般也是指某个人特别容易情绪激动&a…

Java | Leetcode Java题解之第78题子集

题目&#xff1a; 题解&#xff1a; class Solution {List<Integer> t new ArrayList<Integer>();List<List<Integer>> ans new ArrayList<List<Integer>>();public List<List<Integer>> subsets(int[] nums) {dfs(0, nums…

Ansible--Templates 模块 Tags模块 Roles模块

一 Templates 模块 ①Jinja是基于Python的模板引擎。Template类是Jinja的一个重要组件&#xff0c;可看作一个编译过的模 板文件&#xff0c;用来产生目标文本&#xff0c;传递Python的变量给模板去替换模板中的标记。 ②在配置文件中&#xff0c;会有一些数据&#xff08;如…

YOLOv8改进 | 独家创新篇 | 利用MobileNetV4的UIB模块二次创新C2f(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是利用MobileNetV4的UIB模块二次创新C2f&#xff0c;其中UIB模块来自2024.5月发布的MobileNetV4网络&#xff0c;其是一种高度优化的神经网络架构&#xff0c;专为移动设备设计。它最新的改动总结主要有两点&#xff0c;采用了通用反向瓶…

rust打包编译为mac或者linux可执行文件,发送到别的电脑不能运行

如果使用rust项目编译为linux或者mac可执行文件&#xff0c;发送到别的电脑之后&#xff0c;不可以直接运行&#xff0c;而是显示一个空白文件&#xff0c;双击也没有反应&#xff0c;其实这是因为这个文件没有可执行权限导致的&#xff0c;添加可执行权限就可以了&#xff1a;…

沙盘Sandboxie v5.56.4

菜鸟高手裸奔工具沙盘Sandboxie是一款国外著名的系统安全工具&#xff0c;它可以让选定程序在安全的隔离环境下运行&#xff0c; 只要在此环境中运行的软件&#xff0c;浏览器或注册表信息等都可以完整的进行清空&#xff0c;不留一点痕迹。同时可以防御些 带有木马或者病毒的…

24证券从业资格报名照片要求✅如何上传?

✨24证券从业报名今天下午3点开始喽&#xff01; 话说&#xff0c;每次都有人证券报名照片不符合规格导致报名不通过&#xff0c;建议大家提前了解一下注意事项和要求&#xff01; 之前考过还需要上传照片吗&#xff1f; ✅老考生之前传过照片不用上传了。 ✅首次注册过但没有考…

EMAP的Root工程及其他工具

首先右击项目导航&#xff0c;新建EMAP系统配置 上方辅助工具功能&#xff1a; 1 2 3 4 5 6 7 8 9 10 查看重复数据模型:显示为放大镜标识&#xff0c;可以显示所有应用中相同…

mysql oceanbase数据库alter语句阻塞,解决方案

获取当前阻塞事件 select d.trx_started, a.thread_id, b.processlist_id, a.SQL_text from performance_schema.events_statements_current ajoin performance_schema.threads b on a.thread_id b.thread_idjoin information_schema.processlist c on b.processlist_id c.i…

Sealos急速部署生产用k8s集群

最近一段时间部署k8s全部使用sealos了&#xff0c;整体使用感觉良好&#xff0c;基本没有什么坑。推荐给大家。 使用 Sealos&#xff0c;可以安装一个不包含任何组件的裸 Kubernetes 集群。 最大的好处是提供 99 年证书&#xff0c;用到我跑路是足够了。不用像之前kubeadm安装…

使用Docker安装Whistle Web Debugging Proxy

大家好&#xff0c;继续给大家分享如何使用docker来安装Whistle Web Debugging Proxy&#xff0c;关于Whistle Web Debugging Proxy的介绍和使用&#xff0c;大家可以参考下面文章&#xff0c;希望本文能够给大家的工作带来一定帮助。 Whistle Web Debugging Proxy介绍及使用 …

echarts 处理数据

假如 我数据是这样式的 一个数组里边包含两个对象 var data [{ "gender": "female", "height": 161.2, "weight": 51.6 }, { "gender": "female", "height": 167.5, "weight": 59 }] 想转换…

Redis进阶学习

Redis进阶学习 一、Redis事务1.2 Redis监控1.3 Jedis连接1.4 SpringBoot整合1.5 自定义RedisTemple1.6 Redis.conf详解 二、 Redis持久化2.1 RDB2.2 AOF进程 三、Redis发布订阅3.1 Redis主从复制3.2 集群环境配置3.3、复制原理3.4、宕机后主动变为主机3.5、哨兵模式 四、Redis缓…

文件属性与目录-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板

文件属性与目录 1、七种文件类型 普通文件&#xff08;regular file&#xff09; 普通文件中的数据存在系统磁盘中&#xff0c;可以访问文件中的内容&#xff0c;文件中的内容以字节为单位进行存储于访问。 文本文件 ASCII 码字符 常见的.c、.h、.sh、.txt 等 这些都是文本文…

设计模式之单例模式详解

单例模式 描述&#xff1a;单例&#xff08;Singleton&#xff09;模式的定义&#xff1a;指一个类只有一个实例&#xff0c;且该类能自行创建这个实例的一种模式。 核心特点 单例类只有一个实例对象&#xff1b;该单例对象必须由单例类自行创建&#xff1b;单例类对外提供一…