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

news/2024/5/18 22:52:53/文章来源:https://blog.csdn.net/vivo01/article/details/133999797

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

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.luyixian.cn/news_show_376420.aspx

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

相关文章

微机原理与接口技术-第七章输入输出接口

文章目录 I/O接口概述I/O接口的典型结构基本功能 I/O端口的编址独立编址统一编址 输入输出指令I/O寻址方式I/O数据传输量I/O保护 16位DOS应用程序DOS平台的源程序框架DOS功能调用 无条件传送和查询传送无条件传送三态缓冲器锁存器接口电路 查询传送查询输入端口查询输出端口 中…

err -110 while initial SD card failed enmmm否系解决方案

1.情况表述 之前把 sd卡从小容量换成了大容量 且运行正常 过了一两个月 发现启动失败 报错&#xff1a;mmc0: error -110 whilst initialising SD card 给出报错图片 2.相关解决方案 给出链接 讲的很有道理&#xff0c;但是 我在bash中没有找到对应内核的驱动文件 SD卡…

【JavaScript】JavaScript基础详解(文末送书)

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

Java 线程池调度周期性任务“异常“探究

背景 在做性能监控需求的过程中&#xff0c;会存在很多监控任务需要定时执行。比如在卡顿监控的实现中&#xff0c;我们需要每50ms 执行一次主线程调用栈的任务&#xff0c;此时由于任务本身可能存在一些耗时&#xff0c;可能需要对任务下次调度的时间做一些调整&#xff0c;避…

有没有人声和背景音乐分离的神器?

做视频剪辑&#xff0c;二次创作的朋友&#xff0c;需要去除视频中的背景音乐&#xff0c;保留人声&#xff1b;或者去除人声&#xff0c;保留背景音乐。随着用户需求的增多&#xff0c;科技的发展&#xff0c;让我们能通过智能的人声分离软件来实现&#xff0c;下面就来看看如…

XPS的锂电池表征技巧-科学指南针

XPS作为一种表面表征手段&#xff0c;这是它一个很大的限制&#xff0c;同时也是它一个很大的优势&#xff0c;正所谓“其术专则其艺必精”。限于笔者专业背景&#xff0c;此次主要讲述XPS在锂离子电池中的应用。 而由于XPS测试是一种表面分析手段&#xff0c;故其在锂离子电池…

Qt中QFile、QByteArray QDataStream和QTextStream区别及示例

在Qt中&#xff0c;QFile、QByteArray、QDataStream和QTextStream是常用的文件和数据处理类。 主要功能和区别 QFile&#xff1a; QFile是用于读写文本和二进制文件以及资源的I/O设备。可以单独使用QFile&#xff0c;或者更方便地与QTextStream或QDataStream一起使用。 通常在…

最新2023版完美可用的聚合支付系统源码,全开源无后门,适合二开

最新2023版完美可用的聚合易支付系统源码&#xff0c;全开源无后门&#xff0c;真正安全可用。 更新日志&#xff1a; 1.新增微信公众号消息提醒功能 2.重构转账付款功能&#xff0c;支持通过插件扩展 3.商户后台新增代付功能 4.后台新增付款记录列表 5.支付宝插件新增预…

嵌入式养成计划-46----QT--简易版网络聊天室实现--QT如何连接数据库

一百一十九、简易版网络聊天室实现 119.1 QT实现连接TCP协议 119.1.1 基于TCP的通信流程 119.1.2 QT中实现服务器过程 使用QTcpServer实例化一个服务器对象设置监听状态&#xff0c;通过listen()函数&#xff0c;可以监听特定的主机&#xff0c;也可以监听所有客户端&#x…

C++23:多维视图(std::mdspan)

C23&#xff1a;多维视图&#xff08;std::mdspan&#xff09; 介绍 在 C23 中&#xff0c;std::mdspan 是一个非拥有的多维视图&#xff0c;用于表示连续对象序列。这个连续对象序列可以是一个简单的 C 数组、带有大小的指针、std::array、std::vector 或 std::string。 这…

外汇天眼:如何快速玩转外汇市场?这个技巧你必须知道!

在外汇市场中&#xff0c;决定交易成功与否的关键在于投资者的技能和知识扎不扎实&#xff0c;这对投资者获取利润至关重要。然而对于投资者来说&#xff0c;外汇交易市场又是一个复杂且多变的市场&#xff0c;要在外汇市场中获得成功并不容易&#xff0c;需要深入地了解、不断…

部署Vue项目到githubPage中

上传Vue项目到githubPage 例如: 看我发布的地址 前提条件 1. github上有一个仓库并且仓库下有两个分支(main 和 gh-pages) 1.1 main分支保存你的vue项目源码(react或者其他框架的都行) 1.2 gh-pages分支保存的是你项目打包之后的代码(如Vue项目打包完之后是个dist包,…

【Javascrpt】比较,逻辑运算符

目录 比较运算符 逻辑运算符 &&(与&#xff09; ||&#xff08;或&#xff09; 两真&#xff08;||左侧为真&#xff0c;||右侧为真&#xff09; 两假&#xff08;||左侧为假&#xff0c;右侧为假&#xff09; 一真一假&#xff08;||一侧为假&#xff0c;另一侧为…

数据集的特征提取

1、 特征提取 1.1、 将任意数据&#xff08;如文本或图像&#xff09;转换为可用于机器学习的数字特征 注&#xff1a;特征值化是为了计算机更好的去理解数据 字典特征提取(特征离散化)文本特征提取图像特征提取&#xff08;深度学习将介绍&#xff09; 2 特征提取API sklear…

物联网AI MicroPython传感器学习 之 GC7219点阵屏驱动模块

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; 一、产品简介 LED-8 * 32点阵屏显示板由 4 块单色 8x8 共阴红色点阵单元组成&#xff0c;通过 SPI 菊花链模式将多块显示屏连接后可以组成更大的分辨率显示屏幕&#xff0c;任意组合分辨率。可用于简单仪表显…

1、VMware虚拟机及网络配置

一、VMware虚拟网络编辑器 1、选择NAT模式并配置子网 2、进入NAT设置&#xff0c;配置网关 3、宿主机网络适配器设置 二、创建虚拟机 在这里插入图片描述 三、开启虚拟机&#xff0c;安装操作系统 在该网段内配置静态ip&#xff0c;指定网关为前面NAT配置的网关地址…

Java8 BiConsumer<T, U> 函数接口浅析分享(含示例,来戳!)

文章目录 Java8 BiConsumer<T, U> 函数接口浅析分享&#xff08;含示例&#xff0c;来戳&#xff01;&#xff09;源码accept 方法示例示例一示例二 andThen 方法示例示例一示例二 示例相关代码类dohandler 方法student.javaStudentScore.javaStudentScoreDto.java Java8…

运行报错(三)git bash报错fatal: detected dubious ownership in repository at

报错现象 在运行git 命令时&#xff0c;出现报错 “fatal: detected dubious ownership in repository at” 报错原因 文件夹的所有者和现在的用户不一致 栗子&#xff1a; 文件夹的所有者是root&#xff0c;而当前用户是admin 解决方案 方法一、 将文件夹的所有者替换成ad…

【JAVA学习一:基础语法】

记录学习过程和代码编写&#xff0c;小白纯属记录。 目录 一、运算符 二、数组 三、面向对象 一、运算符 赋值运算符 public class Demo01 { public static void main(String[] args){ System.out.println(11); System.out.println(1-1); System.out.printl…

【Javascript】运算符(赋值,算术,自增,自减)

目录 赋值 算术 单个变量&#xff1a; 多个变量&#xff1a; 在字符串&#xff0c;数组中充当连接符 自符串与字符串 数组与数组 数组与字符串 自增与自减 前置 自增 自减 后置 自增 自减 赋值 var a 1;算术 单个变量&#xff1a; var a 1;a 1;console.l…