实现 YOLO 目标计数 | 含代码示例

news2024/10/7 13:06:58

点击下方卡片,关注“小白玩转Python”公众号

在YOLO算法的无数应用中,我们想聚焦于一个真实的场景:道路车辆计数。这个用例对于智能城市的交通规划和决策具有重要意义。在这篇文章中,我们将带您一步步实现YOLO目标检测和计数,使用车辆跟踪作为我们的实际示例。

bad76c53aa2134b8eef49fc15a15e4b8.jpeg

什么是目标计数?

目标计数是计算机视觉中的一个关键应用,旨在识别和计数图像或视频中的特定对象,如人、动物或车辆。该技术在计算机视觉中具有广泛的应用前景,例如:

  • 交通监控:目标计数可用于测量车流量,从而做出更好的交通管理决策。

  • 零售业:通过计数商店内的客户流量,企业可以了解客户购物行为,提升销售效率。

  • 安全监控:目标计数可用于监控公共场所的人流,增强安全性和安保措施。

b4c39edc7ad2f8f193ce03cf7bca28dd.jpeg

实现目标计数的四个步骤

目标计数过程通常包括四个主要步骤:

  1. 图像预处理:该步骤通过去噪、过滤和增强等技术处理输入图像或视频帧,以提高计数准确性。

  2. 目标检测:此步骤旨在识别预处理图像或视频中的特定对象。流行的目标检测算法包括Faster R-CNN、YOLO(You Only Look Once)和SSD(Single Shot MultiBox Detector)。

  3. 目标跟踪:在该步骤中,在连续图像帧序列中跟踪相同的对象。常见的目标跟踪算法包括KCF(Kernelized Correlation Filter)、TLD(Tracking, Learning, and Detection)和MOSSE(Minimum Output Sum of Squared Error)。目标跟踪确保在动态视频的连续帧中不会多次计数相同的对象。

  4. 目标计数:最后一步涉及计算检测到的和跟踪到的对象数量。

为什么YOLOv8适合目标计数?

YOLO是计算机视觉中一个强大的目标检测工具。虽然YOLO主要用于目标检测,但它也可以用于目标计数,如在实时监控视频流中计数出现的人和车。与传统的目标检测算法如R-CNN系列相比,YOLOv8提供了多项优势,使其非常适合用于目标计数应用。

ab734816dec520a67cc45c0ad746d9a8.png

实时性能

YOLOv8的主要优势之一是其实时目标检测能力。由于其“仅看一次”的特性,YOLO模型无需多次扫描图像,而是将图像一次性划分为多个网格,对每个网格进行分类和回归,从而实现目标检测。此实时性能使YOLOv8非常适合需要即时反馈的应用,如自动驾驶、视频监控和机器人视觉。

高准确性

YOLOv8的另一个优势是其高准确性。传统的目标检测算法通常依赖于多阶段处理,这可能导致每个阶段的累积误差。YOLOv8避免了这一问题,通过在一步内完成所有任务。此外,YOLOv8考虑了对象的上下文,即使在涉及遮挡或重叠的复杂场景中也能保持高准确性。

使用YOLOv8实现目标计数

要使用YOLOv8进行目标计数,我们首先需要检测视频的每一帧中的对象并获得其类别和位置。然而,为了避免在连续帧中多次计数相同的对象,我们还需要采用目标跟踪算法。

💡 目标跟踪算法旨在跨一系列视频帧跟踪一个或多个对象。有多种类型的目标跟踪算法,包括基于光流的方法、基于特征的方法和基于模型的方法。基于光流的方法特别常见,因为它们通过比较两个连续帧来估计每个像素的运动方向和距离,从而实现有效的目标跟踪。

但是,这种方法有一个挑战:如何处理对象的进入和退出。例如,一个人可能从屏幕左侧进入,然后从右侧退出。在这种情况下,我们应将此人计为1,而不是2。为了解决这个问题,我们可以建立规则,例如只有当对象完全进入屏幕时才开始跟踪和计数,当对象完全离开屏幕时停止跟踪和计数。

实践操作:YOLO目标计数

在接下来的部分中,我们将演示如何使用Ultralytics提供的YOLOv8模型,在一分钟的道路监控视频(street.mp4)中计数出现的人和车辆。

输出将是一个带有注释的视频(street_object_counting.mp4),显示每一帧中出现和消失的人和车辆。Ultralytics不仅提供YOLO模型,还在其PIP包中提供了目标计数等高级功能,使开发人员更容易利用YOLO模型。

您可以从以下链接下载完整的Google Colab Notebook代码:yolov8_object_counting.ipynb。

515efec6b133f35a06fe1d6a01ea24ad.jpeg

首先,通过下载测试视频并安装所需的PIP依赖项来设置运行环境。

23b919b3f027f4aaab49fbf6e6626f5b.jpeg

$ curl -o /content/street.mp4 https://basicai-asset.s3.amazonaws.com/www/blogs/yolov8-object-counting/street.mp4
$ pip install ultralytics

然后,输入以下代码片段。

import cv2
from ultralytics import YOLO
from ultralytics.solutions import object_counter as oc

导入必要的Python对象,包括用于读写视频文件的cv2,YOLO用于检测和跟踪每个视频帧中的人和车辆,以及object_counter用于在每个帧中注释出现的人和车辆以生成视频结果。

input_video_path = "street.mp4"
output_video_path = "street_object_counting.mp4"


video_capture = cv2.VideoCapture(input_video_path)
assert video_capture.isOpened(), "Illegal or non-existing video file"


video_width, video_height, video_fps = (
    int(video_capture.get(p))
    for p in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)
)


video_writer = cv2.VideoWriter(
    output_video_path, cv2.VideoWriter_fourcc(*"mp4v"), video_fps, (video_width, video_height)
)

使用VideoCapture逐帧读取视频,并使用VideoWriter生成与源视频相同分辨率和帧率的结果视频。

yolo = YOLO("yolov8n.pt")


object_counter = oc.ObjectCounter()
object_counter.set_args(
    view_img=True,
    reg_pts=[(0, 540), (1280, 540)],
    classes_names=yolo.names,
    draw_tracks=True
)


while video_capture.isOpened():
    success, frame = video_capture.read()
    if not success:
        break


    tracks = yolo.track(frame, persist=True, show=False, classes=[0, 2])
    frame = object_counter.start_counting(frame, tracks)
    video_writer.write(frame)

创建一个YOLO模型对象和一个ObjectCounter对象。然后,使用VideoCapture逐帧读取源视频中的所有帧。利用YOLO检测和跟踪每帧中出现的人和车辆,并使用ObjectCounter在每帧中注释出现的人和车辆。最后,使用VideoWriter将注释的帧写入输出视频流。

重要参数:

  • set_args.reg_pts: 计数区域或线。只有出现在指定区域内或穿过指定线的对象才会被计数。这里,我们指定了一条位于帧底部的水平线。

  • track.persist: 由于需要跨帧对象跟踪(避免在不同帧中多次计数同一个人或车辆),需要保留所有先前帧的检测结果。

  • track.classes: 指定要检测和跟踪的对象类型。0代表人,1代表车辆。

video_capture.release()
video_writer.release()
cv2.destroyAllWindows()

最后,释放相关资源。查看示例视频:https://video.wixstatic.com/video/4b3c31_bdf261c811bc47d78cf59b7a37209451/720p/mp4/file.mp4

拓展问答

Q1: 我很好奇,在现实场景中实现这个过程时面临的最大难题是什么?A1: 最常见的问题之一是处理遮挡(对象被其他对象部分或完全遮挡),这会使模型难以准确检测和计数它们。另一个挑战是确保模型不会在不同帧中多次计数同一个对象。这需要一些巧妙的预处理和对YOLO模型的精细调整。拥有一个稳健的目标跟踪算法也至关重要!

Q2: 我正在做一个涉及自然栖息地中野生动物计数的项目。你认为这种基于YOLO的方法适合吗?A2: 绝对可以!YOLOv8的一个很棒的特点是它非常多才多艺。有了合适的训练数据,您可以教它检测和计数几乎任何类型的对象。无论是野生动物、生产线上产品,还是显微镜下的细胞,YOLO都能胜任。关键是要有一个与您的用例特定相关的良好标注数据集。

Q3: 我最近听说了很多关于Google Colab的事情。你能解释一下它是什么以及为什么如此受欢迎吗?A3: Google Colab是一个革命性的基于云的Jupyter笔记本环境,允许您运行Python代码并使用Google强大的计算资源(包括GPU和TPU)来训练深度学习模型,且完全免费!它非常用户友好,预装了Python库,无缝集成Google Drive,并支持Markdown和LaTeX。难怪Colab在机器学习爱好者和数据科学家中如此受欢迎。

Q4: 我一直在低光条件下尝试目标计数,但准确性无法达到要求。有何建议可以改进?A4: 低光场景确实是目标检测和计数的一个难题。有几个技巧可以尝试。考虑在预处理步骤中应用一些图像增强技术。直方图均衡化或伽马校正可以显著提高暗图像中的细节。另一个帮助方法是使用一个专门在包含低光图像的数据集上训练的YOLO模型,这样它会更好地应对这些挑战性条件。

·  END  ·

HAPPY LIFE

33e66ed1a21b7a6eec532f8e61debb7c.png

本文仅供学习交流使用,如有侵权请联系作者删除

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

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

相关文章

工业路由器在新能源数字化中的应用:重塑能源行业的未来

随着全球对可再生能源和能源效率的追求日益加强,新能源数字化已成为推动行业发展的关键因素。在这一变革的浪潮中,工业路由器以其卓越的性能和独特的功能,成为新能源数字化不可或缺的核心组件。本文将深入探讨工业路由器在新能源数字化中的应…

对话:用言语构建深刻的思想碰撞

对话:用言语构建深刻的思想碰撞 在写书中,对话是一种有力的工具,能与读者进行有效的沟通和交流,引发深思和反思。它不仅是信息传递的方式,更是加深情感、探讨主题和吸引读者参与的桥梁。你应从读者的角度思考&#xf…

【学习AI-相关路程-工具使用-自我学习-jetsoncudapytorch-开发工具尝试-基础样例 (3)】

【学习AI-相关路程-工具使用-自我学习-jetson&cuda&pytorch-开发工具-安装尝试-基础样例 (3)】 1、前言2、环境说明3、自我总结(1)了解整体过程阶段 1: 硬件设置阶段 2: 软件准备阶段 3: 数据准备阶段 4: 模型设计和训练阶…

在Spring 当中存在的八大模式

在Spring 当中存在的八大模式 文章目录 在Spring 当中存在的八大模式每博一文案1. 简单工厂模式2. 工厂方法模式3. 单例模式4. 代理模式5. 装饰器模式6. 观察者模式7. 策略模式8. 模板方法模式最后: 每博一文案 我认为 “知世故而不世故” 才是真正意义上的成熟。回…

Python功能强大的构建系统库之buildout使用详解

概要 在软件开发过程中,管理项目依赖和构建环境是一项复杂而重要的任务。Python buildout库是一种强大的构建系统,能够帮助开发者自动化地管理项目的依赖、生成可重复的开发环境,并简化部署过程。本文将详细介绍buildout库,包括其安装方法、主要特性、基本和高级功能,以及…

csdn的insCode怎么用IDE和linux终端

1.进入insCode,选择工作台 找到我的项目,没有项目的话可以新建一个。 选择在IDE中编辑,界面如下: 右边有个终端,点击即可出现linux的xterm终端。

区块链技术和应用

文章目录 前言 一、区块链是什么? 二、区块链核心数据结构 2.1 交易 2.2 区块 三、交易 3.1 交易的生命周期 3.2 节点类型 3.3 分布式系统 3.4 节点数据库 3.5 智能合约 3.6 多个记账节点-去中心化 3.7 双花问题 3.8 共识算法 3.8.1 POW工作量证明 总结 前言 学习长…

算法:树状数组

文章目录 面试题 10.10. 数字流的秩327. 区间和的个数315. 计算右侧小于当前元素的个数 树状数组可以理解一种数的存储格式。 面试题 10.10. 数字流的秩 假设你正在读取一串整数。每隔一段时间,你希望能找出数字 x 的秩(小于或等于 x 的值的个数)。 请实现数据结构…

Volatile的内存语义

1、volatile的特性 可见性:对一个volatile变量的读,总能够看到任意一个线程对这个volatile变量的写入。 原子性:对任意单个volatile变量的读/写具有原子性,但类似于volatile这种复合操作不具有原子性。 接下来我们用程序验证。…

如何用Java实现SpringCloud Alibaba Sentinel的熔断功能?

在Java中使用Spring Cloud Alibaba Sentinel实现熔断功能的步骤如下&#xff1a; 添加依赖 在项目的pom.xml文件中添加Spring Cloud Alibaba Sentinel的依赖&#xff1a; <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud…

强烈推荐 20.7k Star!企业级商城开源项目强烈推荐!基于DDD领域驱动设计模型,助您快速掌握技术奥秘,实现业务快速增长

更多资源请关注纽扣编程微信公众号 1 项目简介 商城是个从零到一的C端商城项目&#xff0c;包含商城核心业务和基础架构两大模块,推出用户、消息、商品、订单、优惠券、支付、网关、购物车等业务模块&#xff0c;通过商城系统中复杂场景&#xff0c;给出对应解决方案。使用 …

Linux_应用篇(08) 信号-基础

本章将讨论信号&#xff0c;虽然信号的基本概念比较简单&#xff0c;但是其所涉及到的细节内容比较多&#xff0c;所以本章篇幅也会相对比较长。 事实上&#xff0c;在很多应用程序当中&#xff0c;都会存在处理异步事件这种需求&#xff0c;而信号提供了一种处理异步事件的方法…

使用VirtualBox+vagrant创建CentOS7虚拟机

1.VirtualBox 1.1.什么是VirtualBox VirtualBox 是一款开源虚拟机软件。VirtualBox 是由德国 Innotek 公司开发&#xff0c;由Sun Microsystems公司出品的软件&#xff0c;使用Qt编写&#xff0c;在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。 1.2.下载Virtual…

优先级队列(堆)的实现

1.什么是优先级队列 队列是一种先进先出(FIFO)的数据结构&#xff0c;但有些情况下&#xff0c;操作的数据可能带有优先级&#xff0c;一般出队 列时&#xff0c;可能需要优先级高的元素先出队列&#xff0c;该中场景下&#xff0c;使用队列显然不合适&#xff0c;比如&#x…

Atlas 200I DK A2安装MindSpore Ascend版本

一、参考资料 mindspore快速安装 二、重要说明 经过博主多次尝试多个版本&#xff0c;Atlas 200I DK A2无法安装MindSpore Ascend版本。 也有其他博主测试&#xff0c;也未尝成功&#xff0c;例如&#xff1a;【MindSpore易点通漫游世界】在Atlas 200I DK A2 (CANN6.2.RC2)…

【汽车之家注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

构建php环境

目录 php简介 官网php安装包 选择下载稳定版本 &#xff08;建议使用此版本&#xff0c;文章以此版本为例&#xff09; 安装php解析环境 准备工作 安装依赖 zlib-devel 和 libxml2-devel包。 安装扩展工具库 安装 libmcrypt 安装 mhash 安装mcrypt 安装php 选项含…

Java——简易图书管理系统

本文使用 Java 实现一个简易图书管理系统 一、思路 简易图书管理系统说白了其实就是 用户 与 图书 这两个对象之间的交互 书的属性有 书名 作者 类型 价格 借阅状态 而用户可以分为 普通用户 管理员 使用数组将书统一管理起来 用户对这个数组进行操作 普通用户可以进…

BUUCTF靶场[Web] [极客大挑战 2019]Havefun1、[HCTF 2018]WarmUp1、[ACTF2020 新生赛]Include

[web][极客大挑战 2019]Havefun1 考点&#xff1a;前端、GET传参 点开网址&#xff0c;发现是这个界面 点击界面没有回显&#xff0c;老规矩查看源代码&#xff0c;看到以下代码 代码主要意思为&#xff1a; 用get传参&#xff0c;将所传的参数给cat&#xff0c;如果catdog…

c++中的命名空间与缺省参数

一、命名空间 1、概念&#xff1a;在C/C中&#xff0c;变量、函数和后面要学到的类都是大量存在的&#xff0c;这些变量、函数和类的名称将都存 在于全局作用域中&#xff0c;可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化&#xff0c; 以避免命名冲突或…