当前位置: 首页 > news >正文

基于OpenCV-车辆检测项目(简易版)

车辆检测

  • 1.项目介绍
  • 2. 读取一段视频
  • 3.通过形态学处理识别车辆
  • 4.描画轮廓
  • 5. 车辆计数并显示

本项目使用的视频地址链接

1.项目介绍

对一个视频进行车辆数量的检测,用到的知识有视频的读取,滤波器,形态学,添加直线、文本;项目流程为:1.读取一段视频。2.通过形态学处理识别车辆。3.对车辆进行计数。4.显示车辆统计信息。

2. 读取一段视频

在进行车辆检测之前,首先要把视频读进来。
代码如下:

import cv2
import numpy as np# 创建视频帧对象
cap = cv2.VideoCapture('./video/video.mp4')
# 检测视频是否被打开
if not cap.isOpened():print('video open failed')exit(0)
# 循环读取图片
while True:ret, frame = cap.read()# 检测是否正确读取视频帧if not ret:print('视频帧读取有误')break# 读取正确cv2.imshow('frame', frame)# 视频播放速度过快,该成正常速度# key = cv2.waitKey(1) & 0xff 播放过快key = cv2.waitKey(int(1000/cap.get(cv2.CAP_PROP_FPS))) & 0xffif key == 27:break # 按ESC退出# 释放资源
cap.release()
cv2.destroyAllWindows()

3.通过形态学处理识别车辆

先将彩色图像转化为灰度图,然后高斯滤波,接着去背景获得前景,接着通过腐蚀腐蚀图中小斑点,然后再膨胀,用闭运算去除图案里面的小方块。得到一个可以识别的图像。

def bodyResize(img):# 将图像转化为灰度图gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 使用高斯滤波去噪blur = cv2.GaussianBlur(gray, (5, 5), 0)# 去背景mask = bgsubmog.apply(blur)# 腐蚀去掉图中的小方块erode = cv2.erode(mask, kernel, iterations=1)# 膨胀放大dilate = cv2.dilate(erode, kernel, iterations=3)# 闭操作,去掉物体内部的小方块close = cv2.morphologyEx(dilate, cv2.MORPH_CLOSE, kernel)close = cv2.morphologyEx(close, cv2.MORPH_CLOSE, kernel)return close

处理过后如图所示:白色的为车辆。
在这里插入图片描述

4.描画轮廓

首先要检测出轮廓,然后根据得到的轮廓画矩形,为了防止矩形太多,过滤掉太小的矩形。

def drawContours(img, points):# 根据轮廓画矩形for (i, points) in enumerate(contours):#print(i, points)# 画最大外接矩形,太小就不画x, y, w, h = cv2.boundingRect(points)if w < min_w and h < min_h:continuecv2.rectangle(frame, (x, y), (x+w, y+h),(255, 0, 0), 2)

5. 车辆计数并显示

首先把车辆看成一个个矩形,然后算出矩形的中心点,中心点过直线就统计成一辆车,最后将计数打印在图片上。完整版代码如下。

import cv2
import numpy as np# 矩形最小宽高
min_w = 90
min_h = 90# 存储有效车辆的数组
cars = []
# 设置线高
line_high = 600
# 偏移量
offest = 9# 车的数量
count = 0def center(x, y, w, h):x1 = x+w/2y1 = y+h/2return x1, y1def bodyResize(img):# 将图像转化为灰度图gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 使用高斯滤波去噪blur = cv2.GaussianBlur(gray, (5, 5), 0)# 去背景mask = bgsubmog.apply(blur)# 腐蚀去掉图中的小方块erode = cv2.erode(mask, kernel, iterations=1)# 膨胀放大dilate = cv2.dilate(erode, kernel, iterations=3)# 闭操作,去掉物体内部的小方块close = cv2.morphologyEx(dilate, cv2.MORPH_CLOSE, kernel)close = cv2.morphologyEx(close, cv2.MORPH_CLOSE, kernel)return closedef drawContours(img, points):# 根据轮廓画矩形for (i, points) in enumerate(contours):#print(i, points)# 画最大外接矩形,太小就不画x, y, w, h = cv2.boundingRect(points)if w < min_w and h < min_h:continuecv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)# 创建视频帧对象
cap = cv2.VideoCapture('./video/video.mp4')
# 创建去背景的对象
bgsubmog = cv2.bgsegm.createBackgroundSubtractorMOG()
# 卷积核大小
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
# 检测视频是否被打开
if not cap.isOpened():print('video open failed')exit(0)
# 循环读取图片
while True:ret, frame = cap.read()# 检测是否正确读取视频帧if not ret:print('视频帧读取有误')break# 下面都是读取正确的车辆# 画直线,用来统计车cv2.line(frame, (10, line_high), (1270, line_high), (0, 0, 255), 2)# 进行形态学处理close = bodyResize(frame)# 检测轮廓contours, hier = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# 根据轮廓画矩形for (i, points) in enumerate(contours):# print(i, points)# 画最大外接矩形,太小就不画x, y, w, h = cv2.boundingRect(points)if w < min_w and h < min_h:continuecv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)# 统计车辆数量# 求出车的中心点cen_point = center(x, y, w, h)cars.append(cen_point)# 统计过直线的车的数量for (x, y) in cars:if(y > line_high - offest) and (y < line_high + offest):count = count + 1cars.remove((x, y))# print(count)# 将count打印在屏幕上cv2.putText(frame, "count = "+str(count), (500, 60), cv2.FONT_HERSHEY_SIMPLEX, 2, (255,0,0), 5)cv2.imshow('frame', frame)# cv2.imshow('resize', close)# 视频播放速度过快,该成正常速度# key = cv2.waitKey(1) & 0xff 播放过快key = cv2.waitKey(int(1000/cap.get(cv2.CAP_PROP_FPS))) & 0xffif key == 27:break  # 按ESC退出# 释放资源
cap.release()
cv2.destroyAllWindows(

在这里插入图片描述


此项目仅供个人练习使用,目的是加强对OpenCV的各种API的理解,本项目是基于传统图像处理,还存在较大缺陷,比如极端情况计数不准等问题,后续优化还可以依据深度学习等模型来训练,如有问题,欢迎在评论区讨论。

相关文章:

基于OpenCV-车辆检测项目(简易版)

车辆检测 1.项目介绍2. 读取一段视频3.通过形态学处理识别车辆4.描画轮廓5. 车辆计数并显示 本项目使用的视频地址链接 1.项目介绍 对一个视频进行车辆数量的检测&#xff0c;用到的知识有视频的读取&#xff0c;滤波器&#xff0c;形态学&#xff0c;添加直线、文本&#xff…...

用python获取海康摄像机视频

要调用海康摄像机视频&#xff0c;需要使用海康SDK提供的API。以下是一个简单的示例代码&#xff0c;可以连接到海康摄像机并获取视频流&#xff1a; python import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel from PyQt5.QtGui import QPixmap from PyQ…...

【Linux】遇事不决,可先点灯,LED驱动的进化之路---2

【Linux】遇事不决&#xff0c;可先点灯&#xff0c;LED驱动的进化之路---2 前言&#xff1a; 一、Pinctrl子系统重要概念 1.1 重要概念 1.1.1 pin controller 1.1.2 client device 1.1.3 补充概念 二、GPIO子系统重要概念 2.1 在设备树指定GPIO引脚 2.2 在驱动代码中…...

【计算机网络】数据链路层--点对点协议PPP

1.概念 2.构成 3.封装成帧 - 帧格式 4.透明传输 4.1字节填充法&#xff08;面向字节的异步链路&#xff09; 4.2.比特填充法&#xff08;面向比特的同步链路&#xff09; 5.差错检测 6.工作状态 7.小结...

【⑦MySQL】· 一文了解四大子查询

前言 ✨欢迎来到小K的MySQL专栏&#xff0c;本节将为大家带来MySQL标量/单行子查询、列子/表子查询的讲解✨ 目录 前言一、子查询概念二、标量/单行子查询、列子/表子查询三、总结 一、子查询概念 子查询指一个查询语句嵌套在另一个查询语句内部的查询&#xff0c;这个特性从My…...

ValSuite报告可以帮助改善您的验证过程的6种方式

热验证工艺是一项复杂而微妙的工作&#xff0c;但它是确保制药和生物技术产品的安全性和有效性的重要组成部分。同时&#xff0c;管理整个验证过程中产生的数据可能很费时&#xff0c;而且容易出错——这就是ValSuite的意义。 这款直观的验证软件简化了数据分析和报告&#xf…...

【机器学习】机器故障的二元分类模型-Kaggle竞赛

竞赛介绍 数据集描述 本次竞赛的数据集&#xff08;训练和测试&#xff09;是从根据机器故障预测训练的深度学习模型生成的。特征分布与原始分布接近&#xff0c;但不完全相同。随意使用原始数据集作为本次竞赛的一部分&#xff0c;既可以探索差异&#xff0c;也可以了解在训…...

ADB usage

查看手机设备的信息 获取设备的Android版本号 adb shell getprop ro.build.version.release 获取设备的API版本号 adb shell getprop ro.build.version.sdkAdb 获得 sdk版本 adb shell getprop ro.build.version.sdk27 Adb 获得Android版本 adb shell getprop ro.build.vers…...

利用有限元法(FEM)模拟并通过机器学习进行预测以揭示增材制造过程中热场变化:基于ABAQUS和Python的研究实践

1. 引言 增材制造&#xff08;Additive Manufacturing&#xff0c;AM&#xff09;近年来引起了大量的研究关注&#xff0c;这主要是因为它可以提供定制化、复杂结构的零件制造解决方案。在AM过程中&#xff0c;热场的分布和变化直接影响了零件的质量和性能。对此&#xff0c;采…...

Kafka与Flume的对比分析

Kafka与Flume的对比分析 一、Kafka和Flume1. Kafka架构2. Flume架构3. Kafka和Flume异同点 二、Kafka和Flume的性能对比1. 数据处理性能对比2. 大规模数据流处理的性能对比 三、性和稳定性对比1. 高可用集群的搭建KafkaFlume 2. 数据丢失和重复消费的问题处理KafkaFlume 四、适…...

docker启动redis哨兵报错(sentinel.conf is not writable: Permission denied)

Sentinel config file /usr/local/sentinel/sentinel.conf is not writable: Permission denied. Exiting… 用这个命令不报错&#xff1a;docker run --net host -p 6666:6666–name redis-sentinel -v /usr/mcc/redis/conf:/usr/local/sentinel/ -v /usr/mcc/redis/data/sent…...

如何编写优秀代码

最近在阅读别人写的代码&#xff0c;进行相应功能的修改。发现很多不规范或者比较绕的地方&#xff0c;总有那么几句看着多此一举&#xff0c;阅读别人的代码就是这样&#xff0c;有时候真的不懂写代码的人当时怎么想的。 例如有这么一段&#xff1a; 用户输入一个名字&#…...

信道编码:Matlab RS编码、译码使用方法

Matlab RS编码、译码使用方法 1. 相关函数 在MATLAB中进行RS编码的过程可以使用rsenc()函数或者comm.RSEncoder()函数。 1.1 rsenc()函数使用方法 在MATLAB中帮助中可以看到有三种使用形式&#xff0c;分别为 code rsenc(msg,n,k) code rsenc(msg,n,k,genpoly) code rs…...

数据结构第六章 图 6.1-6.3 错题整理

6.1 6.C 加上一个点实现非连通 去除每个边都是一颗不同的生成树 一共n条边 13.C n个顶点、e条边的无向图&#xff0c;森林。树的角度看&#xff0c;除了根节点没有一条边与其对应&#xff0c;其他顶点都对应一条边&#xff0c;用顶点-边得出有多少颗树 14.A II 等于 也可以…...

12 MFC常用控件(一)

文章目录 button 按钮设置默认按钮按下回车后会响应禁用开启禁用设置隐藏设置显示设置图片设置Icon设置光标 Cbutton 类创建按钮创建消息单选按钮多选按钮 编辑框组合框下拉框操作 CListBox插入数据获取当前选中 CListCtrl插入数据设置表头修改删除 button 按钮 设置默认按钮按…...

Springboot搭配Redis实现接口限流

目录 介绍 限流的思路 代码示例 必需pom依赖 自定义注解 redis工具类 redis配置类 主拦截器 注册拦截器 介绍 限流的需求出现在许多常见的场景中&#xff1a; 秒杀活动&#xff0c;有人使用软件恶意刷单抢货&#xff0c;需要限流防止机器参与活动 某 api 被各式各样…...

php中的双引号与单引号的基本使用

字符串,在各类编程语言中都是一个非常重要的数据类型 网页当中的图片,文字,特殊符号,HTMl标签,英文等都属于字符串 PHP字符串变量用于存储并处理文本, 在创建字符串之后&#xff0c;我们就可以对它进行操作。我们可以直接在函数中使用字符串&#xff0c;或者把它存储在变量中 字…...

【Neo4j教程之CQL命令基本使用】

&#x1f680; Neo4j &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;C…...

Apikit 自学日记:发起文档测试-TCP/UDP

进入某个TCP/UDP协议的API文档详情页&#xff0c;点击文档上方 测试 标签&#xff0c;即可进入 API 测试页&#xff0c;系统会根据API文档的定义的求头部、Query参数、请求体自动生成测试界面并且填充测试数据。 填写/修改请求参数 1.1设置请求参数 与发起HTTP协议测试类似&am…...

坚鹏:中国邮储银行金融科技前沿技术发展与应用场景第1期培训

中国邮政储蓄银行金融科技前沿技术发展与应用场景第1期培训圆满结束 中国邮政储蓄银行拥有优良的资产质量和显著的成长潜力&#xff0c;是中国领先的大型零售银行。2016年9月在香港联交所挂牌上市&#xff0c;2019年12月在上交所挂牌上市。中国邮政储蓄银行拥有近4万个营业网点…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...