Python Opencv实践 - 车辆统计(2)检测线绘制,车辆数量计数和显示

        针对我所使用的视频,对上一节的代码进行了修改,增加了更多参数。

Python Opencv实践 - 车辆统计(1)读取视频,移除背景,做预处理_亦枫Leonlew的博客-CSDN博客示例中的图像的腐蚀、膨胀和闭运算等需要根据具体视频进行实验得到最佳效果。https://blog.csdn.net/vivo01/article/details/133756184?spm=1001.2014.3001.5502        主要参数有,检测窗口过滤大小的变量min/max_w/h,检测线的位置和长度(detection_line_x/y/length),检测线上下偏移量阈值(detection_line_offset)。

        由于没有使用深度学习来识别车辆,只是通过传统的计算机视觉方法处理图像后,通过搜索轮廓来实现车辆检测。因此所有参数都是针对我所使用的视频进行了优化,实际运行中,还是会存在无法检测出部分车辆的问题。所有对图像的处理方法和相关参数,需要大家根据自己的视频来进行优化。对于我所使用的视频,我没有直接用MOG2来做背景移除,而是先通过Canny提取边缘后再进行背景移除处理,这一点只是实验出来对我所使用的视频来说效果最好,并非网上所看教程的做法。

import cv2 as cv
import numpy as np#读取视频文件
videoFile = "../../SampleVideos/TrafficHEB.mp4"
video = cv.VideoCapture(videoFile)
FPS = 15
DELAY = int(1000 / FPS)
kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (3,3))
min_w = 82
min_h = 82
max_w = 160
max_h = 160
detection_line_length = 1500
detection_line_x = (1920 - detection_line_length) / 2
detection_line_y = 900
detection_line_offset = 1
cars_detected = 0#训练MOG2背景移除对象
def trainBgSubtractor(train_video, mog, frameNum):#train_video = cv.VideoCapture(videoFile)while True:ret, frame = train_video.read()if ret == False:breakmog.apply(frame, None, 0.01)frameNum = frameNum - 1if frameNum <= 0:break#train_video.release()#增加对比度
def imageAdjust(img, clipLimit = 1.5, gridSize = (3,3)):clahe = cv.createCLAHE(clipLimit, gridSize)adjusted_img = clahe.apply(img)return adjusted_imgdef filterMask(img, a=None):kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (3, 3))# Fill any small holesimg = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)#img = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)# Remove noiseimg = cv.morphologyEx(img, cv.MORPH_OPEN, kernel)# Dilate to merge adjacent blobsimg = cv.dilate(img, kernel, iterations=6)return imgdef rectCenter(x, y, w, h):return x + w / 2, y + h / 2#移除背景
#参考资料:https://blog.csdn.net/u014737138/article/details/80389977
#mog = cv.bgsegm.createBackgroundSubtractorMOG()
mog = cv.createBackgroundSubtractorMOG2(history=100, detectShadows=True)
#trainBgSubtractor(video, mog, 100)
while True:cars_positions = []ret,frame = video.read()if ret == False:break;#变为灰度图做高斯滤波frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)frame_gray = cv.Canny(frame_gray, 65, 160)frame_gray = cv.GaussianBlur(frame_gray, (3,3), 3)#frame_gray = cv.medianBlur(frame_gray, 3)frame_gray = imageAdjust(frame_gray, 15, (3,3))foreground_mask = mog.apply(frame_gray, None, -1)foreground_mask[foreground_mask < 240] = 0#foreground_mask = cv.dilate(foreground_mask, kernel, iterations=2)forground_mask = cv.GaussianBlur(foreground_mask, (3,3), 3)foreground_mask = filterMask(foreground_mask)#画出检测线cv.line(frame,(int(detection_line_x), int(detection_line_y)),(int(detection_line_x + detection_line_length),int(detection_line_y)),(0,50,200))#查找轮廓contours,hierarchy = cv.findContours(foreground_mask, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_TC89_L1)#contours,hierarchy = cv.findContours(foreground_mask, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)#绘制轮廓for contour in contours:(x,y,w,h) = cv.boundingRect(contour)#过滤掉小的轮廓框if w >= min_w and h >= min_h and w <= max_w and h <= max_h:cv.rectangle(frame, (int(x),int(y)), (int(x + w), int(y + h)), (0,255,0), 2)#画出车辆中心点centerX,centerY = rectCenter(x, y, w , h)cv.circle(frame, (int(centerX), int(centerY)), 4, (0,0,255), -1)#将车辆加入检测到的车辆列表中cars_positions.append((centerX, centerY))#检测车辆中心点是否通过检测线for (x,y) in cars_positions:if (y > (detection_line_y - detection_line_offset) and y < (detection_line_y + detection_line_offset) andx > (detection_line_x) and x < (detection_line_x + detection_line_length)):cars_detected = cars_detected + 1print(cars_detected)#输出文字cv.putText(frame, 'Vehicle Detected:' + str(cars_detected), (900, 50), cv.FONT_HERSHEY_SIMPLEX, 2, (0,255,0), 5)cv.imshow("Traffic Original", frame)cv.imshow("Traffic Processing", foreground_mask)if cv.waitKey(DELAY) == 27:break;
video.release()
cv.destroyAllWindows();

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

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

相关文章

操作系统-浅谈CPU与内存

目录 计算机的基本组成CPU内存虚拟内存内存分段内存分页 CPU与内存的交互过程高速缓存cache 所有图片均来自&#xff1a;小林coding 计算机的基本组成 计算机由软件和硬件组成 硬件由CPU(中央处理器&#xff09;存储器(内存外存&#xff09;外部设备组成。 软件由应用软件和系…

【算法】模拟退火算法(SAA,Simulated Annealing Algorithm)

模拟退火算法&#xff08;SAA&#xff09;简介 模拟退火算法&#xff08;SAA&#xff0c;Simulated Annealing Algorithm&#xff09;的灵感来源于工艺铸造流程中的退火处理&#xff0c;随着铸造温度升高&#xff0c;分子运动趋于无序&#xff0c;徐徐冷却后&#xff0c;分子运…

ES6初步了解Symbol的用法

ES6中为我们新增了一个原始数据类型Symbol&#xff0c;让我为大家介绍一下吧&#xff01; Symbol它表示是独一无二的值 Symbol要如何创建 第一种创建方式&#xff1a; let sy Symbol()第二种创建方式&#xff1a; let sy Symbol.for()具体独一无二在哪呢&#xff1f;它们的地…

开源思维导图白板工具

https://okso.app https://drawio.com https://tldraw.com https://excalidraw.com

18 Transformer 的动态流程

博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from333.1007.0.0 b 站直接看 配套 github 链接&#xff1a;https://github.com/nickchen121/Pre-training-language-model 配套博客链接&#xff1a;https://www.cnblogs.com/nickchen121/p/15105048.html 机…

npm install 报node-sass command failed

一、前言 最近在前端项目Vue项目install时会出现node-sass command failed的错误&#xff0c;原因是NodeJS和node-sass的版本不对应导致的&#xff0c;本文将给出解决方案。 二、解决方案 以下是NodeJS和node-sass版本的对照关系&#xff1a;

C++前缀和算法的应用:摘水果 原理源码测试用例

本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 题目 在一个无限的 x 坐标轴上&#xff0c;有许多水果分布在其中某些位置。给你一个二维整数数组 fruits &#xff0c;其中 fruits[i] [positioni, amounti] 表示共…

1221. 四平方和--(暴力,二分)

题目&#xff1a; 1221. 四平方和 - AcWing题库 思路1&#xff1a;暴力 暴力枚举 1.枚举顺序为从a到c&#xff0c;依次增大。 2.tn-a*a-b*b-c*c&#xff0c;求得dsqrt(t) 3.判断求出的d是否成立。d要求&#xff1a;d*dt&&d>c #include<iostream> #include&…

pytorch实战---IMDB情感分析

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

原始航片匀色调色方法

使用PhotoRC 2.0软件&#xff0c;对原始航片进行批量匀色&#xff0c;可以自动处理和人机交互&#xff0c;保留exif信息。 软件下载链接&#xff1a; https://pan.baidu.com/s/1Jj4cMpq8xzYvSa1hhozH-g?pwdndfm 提取码&#xff1a;ndfm

知识点滴 - Email地址不区分大小写

电子邮件地址本身对字符大小写不敏感。这意味着实际的电子邮件地址&#xff0c;如 "exampleemail.com"&#xff0c;并不区分字母的大小写。无论你输入的是大写字母还是小写字母&#xff0c;它仍然会到达同一个电子邮件账户。例如&#xff0c;如果您的电子邮件地址是 …

Linux 用户必备的 Git 图形化工具

Git 是一个免费的开源分布式版本控制系统&#xff0c;用于软件开发和其他几个版本控制任务。它旨在根据速度、效率和数据完整性来处理从小到大的项目。 Linux 用户主要可以通过命令行管理 Git&#xff0c;但是&#xff0c;有几个图形用户界面 (GUI) Git 客户端可以促进在 Linux…

DevOps持续集成-Jenkins(3)

文章目录 DevOpsDevOps概述Jenkins实战3&#xff1a;实战1和实战2的加强版&#xff08;新增SonarQube和Harbor&#xff09;⭐环境准备⭐项目架构图对比Jenkins实战1和实战2&#xff0c;新增内容有哪些&#xff1f;SonarQube教程采用Docker安装SonarQube &#xff08;在Jenkins所…

linux-防火墙

目录 一、防火墙概念 1.软件防火墙 2.iptables默认规则 3.iptables的五链 4.iptables动作 5.四表五链 6.iptables实例 一、防火墙概念 linux下防火墙一般分为软件防火墙、硬件防火墙 硬件防火墙&#xff1a;在硬件的级别实现防火墙过滤功能&#xff0c;性能高&#xf…

centos服务器搭建安装Gitlab教程使用教程

1、更新服务器&#xff1a; sudo yum update -y && sudo yum upgrade -y 2、下载Gitlab的RPM包 https://packages.gitlab.com/gitlab/gitlab-cece表示开源el表示centos 选64位el8对应CentOS8 本教程以centos8为例&#xff0c;在服务器中&#xff0c;下载centos8的…

基于Android 10系统的瑞芯微RK3399K烧写镜像实录

基于Android 10系统的瑞芯微RK3399K烧写镜像实录 1. 前言2. 官网及相关资料3. 烧写固件所需软件4. 直接烧写单一固件步骤5. 固件文件6. Windows下烧写准备6.1 安装 RK USB 驱动6.2 连接设备 7. 烧写固件7.1 烧写统一固件 update.img7.2 烧写分区映像 8. Linux下烧写8.1 upgrade…

STM32 HAL库串口使用printf

STM32 HAL库串口使用printf 背景配置说明在usart.h中添加在usart.c中添加在工程中选中微库&#xff1a; 测试 背景 在我们使用CubeMX生成好STM32 HAL库工程之后&#xff0c;我们想使用printf函数来打印一些信息&#xff0c;配置如下&#xff1a; 配置说明 在usart.h中添加 …

水电站与数据可视化:洞察未来能源趋势的窗口

在信息时代的浪潮中&#xff0c;数据可视化正成为推动能源领域发展的重要工具。今天&#xff0c;我们将带您一起探索水电站与数据可视化的结合&#xff0c;如何成为洞察未来能源趋势的窗口。水电站作为传统能源领域的重要组成部分&#xff0c;它的运行与管理涉及大量的数据。然…

03 vi编辑器

vi编辑器的三种模式: 不同的模式下机键动作解释的意义是不一样的 编辑模式 插入模式 末行模式 文件的打开和关闭保存 移动光标

【强烈推荐】视频转gif、图片拼gif,嘎嘎好用,免费免费真的免费,亲测有效,无效过来打我

问题描述 最近遇到一个需求是需要将视频生成gif&#xff0c;这个看上去不是很难&#xff0c;所以有了以下的解决办法 解决办法 首先想到的当然是自己写一个&#xff0c;用了两套代码&#xff1a; from moviepy.editor import *# 读取视频文件 video_clip VideoFileClip(&quo…