Python + OpenCV 简单车辆统计

news2024/9/23 15:19:08

目录

1 源码

2 运行结果


 Python + OpenCV 简单车辆统计

IDE : PyChram

1 源码

函数 car_count() 简单车辆统计

# 这是一个示例 Python 脚本。

# 按 Shift+F10 执行或将其替换为您的代码。
# 按 双击 Shift 在所有地方搜索类、文件、工具窗口、操作和设置。
import cv2
import numpy
import time


def mouse_callback(event, x, y, flags, userdata):
    print(event, x, y, flags, userdata)


def mouse_control():
    cv2.namedWindow('mouse', cv2.WINDOW_NORMAL)
    cv2.resizeWindow('mouse', 640, 360)
    img = numpy.zeros((360, 640, 3), numpy.uint8)
    cv2.setMouseCallback('mouse', mouse_callback, '123')
    while True:
        cv2.imshow('mouse', img)
        key = cv2.waitKey(1)
        if key == ord('q'):
            break
    cv2.destroyAllWindows()


def test():
    """

    :return:
    """
    print("hello test")
    win_name = "frame"
    cv2.namedWindow(win_name, cv2.WINDOW_NORMAL)
    cv2.resizeWindow(win_name, 640, 480)
    cap = cv2.VideoCapture(0)
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    vm = cv2.VideoWriter('output.mp4', fourcc, 20, (640, 480))

    if not cap.isOpened():
        print("video capture err")
        exit()
    while True:
        ret, frame = cap.read()

        if ret:
            vm.write(frame)
            cv2.imshow(win_name, frame)

            if cv2.waitKey(1) & 0xff == ord('q'):
                break
        else:
            break
    cap.release()
    vm.release()
    cv2.destroyAllWindows()


def test_split_merge():
    img = numpy.zeros((480, 640, 3), numpy.uint8)
    b, g, r = cv2.split(img)
    b[10:100, 10:100] = 255
    g[10:100, 10:100] = 255

    img2 = cv2.merge((b, g, r))
    # 在图像上绘制文本
    font = cv2.FONT_HERSHEY_SIMPLEX
    text = 'Hello, OpenCV!'
    org = (50, 50)
    font_scale = 1

    color = (255, 0, 0)  # BGR
    thickness = 2
    cv2.putText(img, text, org, font, font_scale, color, thickness, cv2.LINE_AA)
    cv2.line(img, (10, 10), (100, 100), (255, 111, 222))
    cv2.imshow("img", numpy.hstack((img, img2)))
    cv2.waitKey(0)
    cv2.destroyAllWindows()


def image_flip(flip_code):
    image = cv2.imread('dog.png')
    image = cv2.flip(image, flip_code)
    image = cv2.rotate(image, cv2.ROTATE_180)
    cv2.imshow('image', image)
    cv2.waitKey(0)


def warp_affine():
    dog = cv2.imread('dog.png')
    h, w, ch = dog.shape
    # m = numpy.float32([[1, 0, 100], [0, 1, 0]])
    m = cv2.getRotationMatrix2D((w / 2, h / 2,), 15, 1.0)
    new = cv2.warpAffine(dog, m, (w, h))
    cv2.imshow('new', new)
    cv2.waitKey(0)


def print_hi(name):
    # 在下面的代码行中使用断点来调试脚本。
    print(f'Hi, {name}')  # 按 Ctrl+F8 切换断点。
    warp_affine()


def calculate_rectangle_center(x, y, width, height):
    """
    根据矩形的起点坐标、宽和高计算中心点的函数

    参数:
    x, y -- 矩形起点的坐标
    width -- 矩形的宽度
    height -- 矩形的高度

    返回:
    cx, cy -- 矩形中心点的坐标
    """
    cx = int(x + width / 2)
    cy = int(y + height / 2)
    return cx, cy


def car_count():
    print('car count')
    count = 0
    cap = cv2.VideoCapture('./car.mp4')
    if not cap.isOpened():
        print('video open fail')
        exit()
    # 创建一个基于高斯混合模型(Gaussian Mixture Model, GMM)的背景减法器对象
    bgs = cv2.createBackgroundSubtractorMOG2()
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))

    while True:

        ret, frame = cap.read()

        if not ret:
            # 如果到达视频末尾,则重置视频捕获对象以从头开始播放
            cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
            # 重新读取第一帧
            ret, frame = cap.read()
            count = 0
            # 可选:如果不想立刻重头播放,可以在这里添加一些延时
            time.sleep(2)  # 等待2秒

        if ret is True:
            if frame is None:
                break
            f_w = 640
            f_h = 480
            # 调整帧的大小
            resized_frame = cv2.resize(frame, (f_w, f_h), interpolation=cv2.INTER_AREA)
            # 灰度化处理
            gray = cv2.cvtColor(resized_frame, cv2.COLOR_BGR2GRAY)

            # 去噪
            blur = cv2.GaussianBlur(gray, (3, 3), 5)
            # 使用前面创建的背景减法器对象bgs来对一个视频帧frame进行处理
            fg_mask = bgs.apply(blur)
            # 腐蚀
            erode = cv2.erode(fg_mask, kernel)
            # 膨胀
            dilate = cv2.dilate(erode, kernel)
            # 闭运算
            close = cv2.morphologyEx(dilate, cv2.MORPH_CLOSE, kernel)
            # 查找轮廓
            contours, hierarchy = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
            # 绘制轮廓
            # 你可以调整第三个参数来绘制所有轮廓或只绘制特定级别的轮廓
            # -1 表示绘制所有轮廓
            # cv2.drawContours(resized_frame, contours, -1, (0, 255, 0), 3)
            # 限制宽高
            w_limit = 40
            h_limit = 40
            # 画线的起点和终点
            line_sx = 10
            line_sy = f_h - 100
            line_ex = f_w - 10
            line_ey = line_sy
            offset = 3
            # 画线
            cv2.line(resized_frame, (line_sx, line_sy), (line_ex, line_ey), (0, 0, 255), 2)
            cars = []
            for contour in contours:
                # 最大外接矩形
                (x, y, w, h) = cv2.boundingRect(contour)
                # 过滤掉小矩形
                if w < w_limit or h < h_limit:
                    continue
                if y < (f_h / 2):
                    continue
                # print(f"Contour: x={x}, y={y}, width={w}, height={h}")
                cv2.rectangle(resized_frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
                cen_point = calculate_rectangle_center(x, y, w, h)
                cars.append(cen_point)
                cv2.circle(resized_frame, cen_point, 2, (0, 255, 0), -1)
            for (x, y) in cars:
                if (line_ey - offset) < y < (line_ey + offset):
                    count += 1
                    cars.remove((x, y))
                    # print(count)
            cv2.putText(resized_frame, 'Cars Count:' + str(count), (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
            cv2.imshow('resized_frame', resized_frame)

        if cv2.waitKey(2) & 0xFF == 27:
            break

    cap.release()
    cv2.destroyAllWindows()


# 按装订区域中的绿色按钮以运行脚本。
if __name__ == '__main__':
    car_count()

# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
2 运行结果

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

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

相关文章

Mojo语言的运用

1.Mojo语言概述 1.1什么是Mojo语言&#xff1f; Mojo语言是一种现代的动态编程语言&#xff0c;主要用于Web开发。它结合了多种语言的优点&#xff0c;如JavaScript、Perl和Lua&#xff0c;旨在为开发者提供&#xff1a; 简洁的语法&#xff1a;易于学习和使用&#xff0c;适…

课程设计——Python+OpenCV数字图像处理[车牌识别]

Python opencv 车牌识别 数字图像处理课程设计作业Python3OpenCV使用tkinter搭建界面tmp/文件夹是数字图像处理过程chepai/文件夹是车牌图片pic/文件夹是程序界面图PPT文件是验收时要讲的程序是从网上学习的并自己弄的&#xff0c;不完善&#xff0c;识别率不高 开发环境配置…

Java核心篇之JVM探秘:垃圾回收算法与垃圾收集器

系列文章目录 第一章 Java核心篇之JVM探秘&#xff1a;内存模型与管理初探 第二章 Java核心篇之JVM探秘&#xff1a;对象创建与内存分配机制 第三章 Java核心篇之JVM探秘&#xff1a;垃圾回收算法与垃圾收集器 第四章 Java核心篇之JVM调优实战&#xff1a;Arthas工具使用及…

QT creator与VS2019 QT加载模块方法

QT creator与VS2019加载模块方法 QT creator&#xff0c;pro文件添加 VS2019 QT

JavaScript中的面向对象编程

OPP在JavaScript的表现方式&#xff1a;原型 传统的OPP&#xff1a;类 ● 对象&#xff08;实例&#xff09;由类实例化&#xff0c;类的功能类似于蓝图&#xff0c;通过蓝图来实现建筑&#xff08;实例&#xff09; ● 行为&#xff08;方法&#xff09;从类复制到所有实例 …

子进程继承父进程文件描述符导致父进程打开设备文件失败

开发过程中有时会遇到需要在程序中执行三方程序或者shell脚本&#xff0c;一般会通过system(), popen(), exec簇来完成该功能。我们知道以上方法会通过fork创建子进程后在子进程中执行相应指令。如图1为某个示例流程&#xff0c;具体的程序执行流程如图2所示&#xff0c;线程my…

Android ListView

ListView ListView是以列表的形式展示具体内容的控件&#xff0c;ListView能够根据数据的长度自适应显示&#xff0c;如手机通讯录、短消息列表等都可以使用ListView实现。如图1所示是两个ListView&#xff0c;上半部分是数组形式的ListView&#xff0c;下半部分是简单列表Lis…

WPF学习(5) -- WPF绑定

一、双向绑定 1.代码示例 <Window x:Class"学习.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expres…

批量导出word,并导出一个zip文件

系统导出功能&#xff0c;多条数据分别导出word&#xff0c;多个word打包到一个zip进行导出&#xff0c;直接拷贝过去可用&#xff0c;如果缺包自行查找。 参考&#xff1a; Java使用word模板导出word_java根据模板导出word-CSDN博客. Action(value "exportToWordZip&qu…

高阶数据结构——并查集

1. 并查集的介绍 并查集是一种树型的数据结构&#xff0c;用于处理一些不相交集合的合并及查询问题&#xff08;即所谓的并、查&#xff09;。 在一些应用问题中&#xff0c;需要将n个不同的元素划分成一些不相交的集合。开始时&#xff0c;每个元素自成一个单元素集合&#…

springboot+vue 开发记录(九)后端打包部署运行

本篇文章主要内容是后端项目写好了&#xff0c;怎么打包部署到服务器上运行。 文章目录 1. 在服务器上安装Docker2. 在Docker中装MySQL3. 在Docker中设置网桥&#xff0c;实现容器间的网络通信4. 修改后端配置文件5. 修改pom.xml文件6. 打包7. 编写DockerFile文件8. 上传文件到…

STFT:解决音频-视频零样本学习 (ZSL) 中的挑战

传统的监督学习方法需要大量的标记训练实例来进行训练,视听零样本学习的任务是利用音频和视频模态对对象或场景进行分类&#xff0c;即使在没有可用标记数据的情况下。为了解决传统监督方法的限制&#xff0c;提出了广义零样本学习&#xff08;Generalized Zero-Shot Learning,…

暴雨让服务器不怕热҈热҈热҈热҈

在AI算力呈几何倍数增长的趋势下&#xff0c;算力逐渐朝着“高性能、高密度、高耗能“发展。在高耗能的算力下&#xff0c;AI服务器功率已逐步逼近风冷散热极限&#xff0c;而液冷作为更加高效、低能耗的制冷技术&#xff0c;逐渐成为了高密度算力散热场景的首选方案。 液冷的…

Spring源码中的模板方法模式

1. 什么是模板方法模式 模板方法模式&#xff08;Template Method Pattern&#xff09;是一种行为设计模式&#xff0c;它在操作中定义算法的框架&#xff0c;将一些步骤推迟到子类中。模板方法让子类在不改变算法结构的情况下重新定义算法的某些步骤。 模板方法模式的定义&…

Linux内核编译安装 - Deepin,Debian系

为什么要自己编译内核 优点 定制化&#xff1a;你可以根据自己的硬件和需求配置内核&#xff0c;去掉不必要的模块&#xff0c;优化性能。性能优化&#xff1a;移除不需要的驱动程序和特性&#xff0c;减小内核体积&#xff0c;提高系统性能。最新特性和修复&#xff1a;获取…

网络(二)——套接字编程

文章目录 理解源IP地址和目的IP地址认识端口号认识TCP/UDP协议网络字节序socket编程接口socket 常见APIsockaddr结构 理解源IP地址和目的IP地址 在IP数据包头部中, 有两个IP地址, 分别叫做源IP地址, 和目的IP地址&#xff1b; 源IP即发送方的地址&#xff0c;目的IP即接受方的…

[译] Rust标准库有些特殊,让我们改它

本篇是对 RustConf 2023中的The standard library is special. Let’s change that.这一视频的翻译与整理, 过程中为符合中文惯用表达有适当删改, 版权归原作者所有. 今天我将讨论Rust的标准库,更具体地说,是关于标准库有何特殊之处,以及为什么我们应该改变这一点。首先声明一下…

探索 Prompt 的世界:让你的 AI 更智能

探索 Prompt 的世界&#xff1a;让你的 AI 更智能 引言什么是 Prompt&#xff1f;Prompt 的重要性如何编写有效的 Prompt1. 清晰明确2. 包含关键细节3. 提供上下文 实践中的 Prompt 技巧1. 多次迭代2. 实验不同风格3. 结合实际应用 总结 引言 随着人工智能&#xff08;AI&…

通过vm可以访问那些属性——06

1.通过vue实例都可以访问那些属性&#xff1f;&#xff08;通过vm都可以vm.什么&#xff09; vue实例中的属性很多。有的以$开始&#xff0c;有的以_开始。 所有以$开始的属性&#xff0c;可以看做是公开的属性&#xff0c;这些属性是提供给程序员使用的 所有以_开始的属性&…

PyTorch是使用GPU和CPU优化的深度学习张量库——torchvision

torchvision datasets torchvision.datasets 包含了许多标准数据集的加载器。例如&#xff0c;CIFAR10 和 ImageFolder 是其中两个非常常用的类。 CIFAR10 CIFAR10 数据集是一个广泛使用的数据集&#xff0c;包含10类彩色图像&#xff0c;每类有6000张图像&#xff08;5000张…