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

news2024/12/25 12:52:15

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

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:
            break
        mog.apply(frame, None, 0.01)
        frameNum = frameNum - 1
        if 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_img


def filterMask(img, a=None):
    kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (3, 3))

    # Fill any small holes
    img = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)
    #img = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)

    # Remove noise
    img = cv.morphologyEx(img, cv.MORPH_OPEN, kernel)

    # Dilate to merge adjacent blobs
    img = cv.dilate(img, kernel, iterations=6)
    return img

def 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) and
            x > (detection_line_x) and x < (detection_line_x + detection_line_length)):
            cars_detected = cars_detected + 1
            print(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.coloradmin.cn/o/1126097.html

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

相关文章

通过执行mysql命令查看mysql版本

第一种一条SQL命令搞定 SELECT version() 第二种操作方式 在终端输入命令即可查询 命令&#xff1a;mysql -V 第三种操作方式 在终端输入命令[也就是进入数据库的命令] 命令&#xff1a;mysql -uroot -p 第三种操作方式 需要进入数据库内输入命令进行查询&#xff1b; 命…

逐字稿 | 视频理解论文串讲(下)【论文精读】

1 为什么研究者这么想把这个双流网络替换掉&#xff0c;想用3D 卷积神经网络来做&#xff1f; 大家好&#xff0c;上次我们讲完了上半部分&#xff0c;就是 2D 网络和一些双流网络以及。它们的。变体。今天我们就来讲一下下半部分&#xff0c;就是 3D 网络和 video Transformer…

layui框架实战案例(24):layedit工具栏添加查看源代码按钮的解决方案

layUI框架实战案例系列文章 layui框架实战案例(21)&#xff1a;layui上传的哪些事(layui.upload组件、 file文件域、php后台上传)layui框架实战案例(20)&#xff1a;常用条件判断和信息展示技巧(图片预览、动态表格、短信已读未读、链接分享、信息脱敏、内置框架页)layui框架实…

企业如何防止文件泄密(图文+视频讲解)

数字化浪潮的推动下&#xff0c;企业文件已经成为企业竞争的核心资产之一。同时&#xff0c;文件泄密事件也频频发生&#xff0c;给企业带来了巨大的经济损失和声誉损失。 那如何有效地防止文件泄密已成为企业亟待解决的重要问题&#xff01;在查阅了大量资料后&#xff0c;小编…

Linux进程间通信之匿名管道

Linux进程间通信之匿名管道 进程间通信介绍1. 进程间通信的目的2. 进程间通信发展 什么是管道匿名管道1. 什么是匿名管道2. 匿名管道样例详解3. 原理4. 单个父进程与多个子进程管道间通信建立子进程任务相关的头文件主文件的建立执行结果 5. 管道读写规则6. 管道特点 进程间通信…

基于图像识别的跌倒检测算法 计算机竞赛

前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于图像识别的跌倒检测算法 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng-senior/…

分布式事务及CAP和BASE定理

一、分布式事务 单体应用肯定就不存在分布式事务了&#xff0c;只有在分布式微服务系统中&#xff0c;各个服务之间通过RPC调用后&#xff0c;每个微服务有自己和数据库的连接&#xff0c;各个微服务的回滚不影响其他的微服务事务&#xff0c;这几必须使用分布式事务来解决分布…

CASAIM自动激光3D测量系统助力海外家电组装企业IQC来料检测装配尺寸测量

随着家电产品的不断创新发展&#xff0c;海外家电组装企业也面临着越来越高的质量标准&#xff0c;几何尺寸测量与控制是保证产品交付质量的基础。零部件、外壳壳体经过国内或东南亚其他地区生产好后&#xff0c;为了确保产品质量和一致性&#xff0c;外协件物料需要送往组装厂…

FDWS9510L-F085车规级 PowerTrench系列 P沟道增强型MOS管

PowerTrench MOSFET 是优化的电源开关&#xff0c;可提高系统效率和功率密度。 它们组合了小栅极电荷 (Qg)、小反向恢复电荷 (Qrr) 和软性反向恢复主体二极管&#xff0c;有助于快速切换交流/直流电源中的同步整流。 采用屏蔽栅极结构&#xff0c;可提供电荷平衡。 利用这一先进…

吃瓜教程2|线性模型

线性回归 “广义的线性模型”&#xff08;generalized linear model&#xff09;&#xff0c;其中&#xff0c;g&#xff08;*&#xff09;称为联系函数&#xff08;link function&#xff09;。 线性几率回归&#xff08;逻辑回归&#xff09; 线性判别分析 想让同类样本点的…

biocParallel学习

我好像做了一个愚蠢的测试 rm(listls()) suppressPackageStartupMessages({library(SingleCellExperiment)library(scMerge)library(scater)library(Matrix) })setwd("/Users/yxk/Desktop/test/R_parallel/") load("./data/exprsMat.RData") load(".…

文心一言 VS 讯飞星火 VS chatgpt (119)-- 算法导论10.3 4题

四、用go语言&#xff0c;我们往往希望双向链表的所有元素在存储器中保持紧凑&#xff0c;例如&#xff0c;在多数组表示中占用前m 个下标位置。(在页式虚拟存储的计算环境下&#xff0c;即为这种情况。)假设除指向链表本身的指针外没有其他指针指向该链表的元素&#xff0c;试…

laravel框架介绍(二) 打开站点:autoload.php报错

Laravel&#xff1a;require..../vendor/autoload.php错误的解决办法 打开站点&#xff1a;http://laraveltest.com:8188/set_api-master/public/ set_api-master\public\index.php文件内容为&#xff1a; 解决办法&#xff1a; 1. cd 到该引用的根目录&#xff0c;删除 compo…

【JavaEE初阶】 常见的锁策略详解

文章目录 &#x1f6ec;常见的锁策略&#x1f334;乐观锁 vs 悲观锁&#x1f38b;读写锁&#x1f333;重量级锁 vs 轻量级锁&#x1f384;自旋锁&#xff08;Spin Lock&#xff09;&#x1f340;公平锁 vs 非公平锁&#x1f38d;可重入锁 vs 不可重入锁 &#x1f6eb;相关面试题…

超级马里奥

欢迎来到程序小院 超级马里奥 玩法&#xff1a;点击鼠标左键进行马里奥跳跃&#xff0c;带着马里奥跳跃不同的障碍物&#xff0c;统计分数&#xff0c;快去玩变态超级玛丽吧^^。开始游戏https://www.ormcc.com/play/gameStart/193 html <canvas id"gamescene"&g…

软件测试( 基础篇)

前言 从这篇博文开始&#xff0c;我们将作为一名刚刚加入测试团队的菜鸟&#xff0c;开始一次测试之旅。 在这里我们将讨论以下问题&#xff1a; 软件测试的生命周期 如何描述一个bug 如何定义bug的级别 bug的生命周期 产生争执怎么办 软件测试的生命周期 先回顾一个点&#…

TortoiseSVN安装与配置教程:使用内网穿透实现公网提交文件到本地SVN服务器

文章目录 前言1. TortoiseSVN 客户端下载安装2. 创建检出文件夹3. 创建与提交文件4. 公网访问测试 前言 TortoiseSVN是一个开源的版本控制系统&#xff0c;它与Apache Subversion&#xff08;SVN&#xff09;集成在一起&#xff0c;提供了一个用户友好的界面&#xff0c;方便用…

SpringBoot整合redis实现过期Key监控处理(最简单模式)

前言&#xff1a;写这篇文章的目的主要是这方面的知识我是第一次实际运用到&#xff0c;在项目里面有个功能&#xff0c;需要登录的时候根据手机号发送短信验证码&#xff0c;我看了公司的代码是用redis过期key监控实现的&#xff0c;由于之前没有接触过这类&#xff0c;现在写…

Java CC 解析 SQL 语法示例

示例&#xff1a;SimpleSelectParser 解析 select 11; 输出 2&#xff1b; 0&#xff09;总结 编写 JavaCC 模板&#xff0c;*.jj 文件。 编译生成代码文件。 移动代码文件到对应的包下。 调用生成的代码文件。 1&#xff09;JavaCC 模板 main/javacc/SimpleSelectParse…

C# Socket通信从入门到精通(3)——单个异步TCP客户端C#代码实现

前言: Socket通信中有tcp通信,并且tcp有客户端,tcp客户端程序又分为同步通信和异步通信,所谓同步通信其实就是阻塞式通信,比如客户端调用接收服务器数据函数以后,如果服务器没有发送数据给客户端,则客户端程序会一直阻塞一直到客户端接收到服务器的数据为止;所谓异步通…