YOLO8实战:yolov8实现行人跟踪计数

本篇文章首先介绍YOLOV8实现人流量跟踪计数的原理,文末附代码下载地址

yolo8人流量统计

引言:行人跟踪统计是智能监控系统中的重要功能,可以广泛应用于人流控制、安全监控等领域。传统的行人跟踪算法往往受到光照、遮挡等因素的干扰,难以实现准确跟踪。随着深度学习技术的发展,目标检测模型逐渐成为行人跟踪的主流方案。本文介绍使用 YOLOv8 目标检测模型实现行人跟踪统计的方法。

一、YOLOv8模型介绍

YOLOv8 是 ultralytics 公司在 2023 年开源的 YOLOv5 的下一个重大更新版本,按照官方描述,YOLOv8 是一个 SOTA 模型,它建立在以前 YOLO 版本的成功基础上,并引入了新的功能和改进,以进一步提升性能和灵活性。不过 ultralytics 并没有直接将开源库命名为 YOLOv8,而是直接使用 ultralytics 这个词,原因是 ultralytics 将这个库定位为算法框架,而非某一个特定算法,一个主要特点是可扩展性。其希望这个库不仅仅能够用于 YOLO 系列模型,而是能够支持非 YOLO 模型以及分类分割姿态估计等各类任务。因此,YOLO发展到如今的版本,已经不单单是目标检测的代名词,就像官方所解释的那样,YOLOv8 更应该更名为Ultralytics 。目前YOLO8算法框架(ultralytics库)全面支持图像分类、目标检测和实例分割、人体关键点检测等任务。在目标跟踪方面,YOLO8算法库内置了多目标跟踪领域的SOTA算法(Byte-tracker和Bot-tracker)。在实例分割方面,支持与SAM、Fast-SAM无缝集成.....未来,我们也期待着ultralytics库能够扩充更多的CV领域的SOTA算法。

与之前的YOLO版本相比,YOLOv8在以下几个方面有所不同:

  1. 骨干网络:YOLOv8采用了全新的骨干网络,以提高模型的性能和准确性。YOLOv8的骨干网络是Darknet-53。Darknet-53是一个深度卷积神经网络模型,它由53个卷积层和池化层组成,用于提取图像特征。其实Darknet-53在YOLOv3网络中就已经被广泛使用,并在YOLOv4和YOLOv5中也得到了应用。它具有较强的特征提取能力,能够在目标检测任务中提供较好的性能。

  2. 检测头:YOLOv8采用了Anchor-Free的检测头,这意味着它不再需要预先定义一组固定的先验框来检测目标,而是可以直接从原始图像中预测目标的边界框,这有助于提高模型的灵活性和准确性。

  3. 损失函数:YOLOv8采用了新的损失函数,以更好地优化模型的训练过程,进一步提高模型的性能。YOLOv8的损失函数由多个部分组成,包括分类损失(VFL Loss)、回归损失为CIOU Loss+DFL的形式。

限于文章的篇幅,详细分析YOLO8的网络结构并不是本篇文章的重点,我们单独在另外一篇文章中详细介绍。接下来,我们来介绍一下如何使用yolo8实现行人跟踪计数。

二、基于yolo8实现行人统计

统计行人必须先要检测到行人。这不得不提一下YOLO目标检测实现的基本原理:基于将输入图像分割成若干个网格,然后对每个网格进行目标检测。每个网格会预测出多个bounding box(包含物体的矩形区域)以及这些box中包含物体的概率和物体的类别信息。具体来说,YOLO首先将输入图像分成SxS个格子,如果某个物体的中心位置的坐标落入到某个格子,那么这个格子就负责检测出这个物体。每个网格会预测B个bounding box的信息和C个物体属于某种类别的概率信息。Bounding box信息包含5个数据值,分别是x,y,w,h,和confidence,其中x,y是指当前格子预测得到的物体的bounding box的中心位置的坐标,w,h是bounding box的宽度和高度,confidence代表该box中是否包含物体的置信度。

由于yolo官方已经在COCO数据集上训练过yolov8,分别有yolo8n、yolo8m、yolo8s、yolo8l、yolo8x五种不同尺寸的模型。因此,使用yolov8的这五种预训练模型,可以识别COCO数据集上已有的80种物体。接下来,我们使用yolo官方提供的预训练模型YOLO8n,识别并统计一张图片中有多少个人。首先看下面的代码:

from ultralytics import YOLOmodel=YOLO('./yolov8n.pt')#加载本地的yolo8n模型# results=model.predict('./people.jpeg')results=model('./people.jpeg')#推理本地图片print(type(results))print(type(results[0]))

上面的代码我们使用model('./people.jpeg')和model.predict('./people.jpeg)两种方式对图片进行推理预测

图片来源于网络

我们输出模型推理的结果,发现推理结果results是一个保存Results类的List数组,由于我们是一张一张图片推理的,因此List数组中仅有一个Results对象。

那么这个Results对象是干什么的呢?其实,这对象包含了YOLO8模型的所有预测信息,包括目标检测任务、图片分类任务、实例分割任务、人体关键点检测任务、多目标跟踪任务的所有预测信息都可以在这个对象中找到。因此,使用yolo8很简单,第一步配置好环境、第二步下载好模型、第三步写两行预测代码,后续的事情就是处理预测结果Results对象的事情了。下面我们来看一下Results对象中究竟都有什么属性。首先看一下YOLO官方对这个对象的注释:

"""
    A class for storing and manipulating inference results.

    Args:
        orig_img (numpy.ndarray): The original image as a numpy array.
        path (str): The path to the image file.
        names (dict): A dictionary of class names.
        boxes (torch.tensor, optional): A 2D tensor of bounding box coordinates for each detection.
        masks (torch.tensor, optional): A 3D tensor of detection masks, where each mask is a binary image.
        probs (torch.tensor, optional): A 1D tensor of probabilities of each class for classification task.
        keypoints (List[List[float]], optional): A list of detected keypoints for each object.

    Attributes:
        orig_img (numpy.ndarray): The original image as a numpy array.
        orig_shape (tuple): The original image shape in (height, width) format.
        boxes (Boxes, optional): A Boxes object containing the detection bounding boxes.
        masks (Masks, optional): A Masks object containing the detection masks.
        probs (Probs, optional): A Probs object containing probabilities of each class for classification task.
        keypoints (Keypoints, optional): A Keypoints object containing detected keypoints for each object.
        speed (dict): A dictionary of preprocess, inference, and postprocess speeds in milliseconds per image.
        names (dict): A dictionary of class names.
        path (str): The path to the image file.
        _keys (tuple): A tuple of attribute names for non-empty attributes.
    """

Results对象主要包含下列重要的属性:

boxes:该对象保存了目标检测的结果。

masks:该对象保存了实例分割的结果

probs:该对象保存了图像分类的结果

keypoints: 关键点检测的结果

names: 模型的类别

speed:  检测速度相关信息

orig_img:加载在内存中的原始图像

path:包含输入图像的路径

result对象默认是torch.Tensor对象,也可以转为其他对象

这里我们主要来看一下boxes对象的属性:

"""
    A class for storing and manipulating detection boxes.

    Args:
        boxes (torch.Tensor | numpy.ndarray): A tensor or numpy array containing the detection boxes,
            with shape (num_boxes, 6) or (num_boxes, 7). The last two columns contain confidence and class values.
            If present, the third last column contains track IDs.
        orig_shape (tuple): Original image size, in the format (height, width).

    Attributes:
        xyxy (torch.Tensor | numpy.ndarray): The boxes in xyxy format.
        conf (torch.Tensor | numpy.ndarray): The confidence values of the boxes.
        cls (torch.Tensor | numpy.ndarray): The class values of the boxes.
        id (torch.Tensor | numpy.ndarray): The track IDs of the boxes (if available).
        xywh (torch.Tensor | numpy.ndarray): The boxes in xywh format.
        xyxyn (torch.Tensor | numpy.ndarray): The boxes in xyxy format normalized by original image size.
        xywhn (torch.Tensor | numpy.ndarray): The boxes in xywh format normalized by original image size.
        data (torch.Tensor): The raw bboxes tensor (alias for `boxes`).

    Methods:
        cpu(): Move the object to CPU memory.
        numpy(): Convert the object to a numpy array.
        cuda(): Move the object to CUDA memory.
        to(*args, **kwargs): Move the object to the specified device.
    """

 因此我们要统计一张图像的行人数,就非常容易了,见如下代码:

上面的代码中我们先统计模型检测到的所有的物体的数量,然后进一步筛序出person的个数。就完成了一张图片下的行人统计。

那么如果不是一张图片而是一段视频呢?我们知道,视频本质上是由一张张图片按照时间序列组成的,如果把一段视频拆成一张张图片然后再按照上面的方法,能不能统计出一段视频有多少人呢?答案是不行的,比如一段10帧的视频,但是整个视频只有一个人,试想如果把这段视频分成10张图片然后单独统计,最后是不是把一个人算成了10个人?这里涉及到了目标跟踪,目标跟踪是指在给定第一帧图像中的目标位置后,根据跟踪算法预测出后续帧中目标的位置。其基本原理包括特征提取、运动模型、外观模型、在线更新机制等部分。其中,特征提取用于提取图像目标的特征,运动模型用于描述帧与帧之间的目标运动状态关系,预测下一帧中目标的可能位置。在目标跟踪中,会为同一个被跟踪的物体赋予一个ID,以区别其他物体。因此,要想统计一段视频中有多少行人,势必要求我们使用目标跟踪技术手段。限于文章的篇幅,在这里,我们就不详细介绍目标跟踪领域的知识了。下面直接介绍Byte-Tracker多目标追踪算法,这也是YOLO8内置的一种多目标追踪算法。

ByteTracker是一种用于多目标跟踪的算法,它是基于深度学习的目标检测算法和跟踪算法的结合。ByteTracker算法的核心思想是在目标检测的基础上,利用目标之间的相似性和连续性,通过对目标进行跟踪,实现多目标跟踪。

ByteTracker算法的流程如下:

  1. 目标检测:首先使用目标检测算法对视频序列中的每一帧进行目标检测,获取每个目标的位置和大小。

  2. 特征提取:对于每个检测到的目标,利用深度学习网络提取其特征,这些特征将被用于后续的跟踪过程。

  3. 目标跟踪:在连续帧之间,利用目标的特征相似性和运动连续性,建立目标之间的对应关系,实现目标的跟踪。

  4. 数据关联:将不同帧中的目标进行跟踪,需要解决数据关联问题,即确定哪些目标属于同一个轨迹。ByteTracker采用了一种基于匈牙利算法的数据关联方法。

  5. 轨迹管理:对于每个目标轨迹,需要对其进行起始、终止、更新等操作,以便实现多目标跟踪。

下面我们来看,如何在yolo8中使用这种多目标追踪算法,实现视频人流量追踪统计。

实现起来非常简单,也仅仅只需要一行代码。

model.track(source=source)即可调用yolo8内置的跟踪模式,但是默认使用的是BotTracker跟踪算法,这是yolo8内置的另外一种算法,在具有遮挡的情况下,效果非常好,比Byte-tracker、DeepSort、Sort等算法准确许多。但是速度却比这些算法慢,我们这里使用byte-tracker跟踪算法,需要在track()中指定tracker="bytetrack.yaml"即可。上图代码中,classes=[0]表示只检测行人,忽略其他物体。

还记得yolo8返回的Results对象的boxes属性吗,在使用track模式后,boxes对象的id就不再像是在目标检测任务那样为None,它现在有了唯一的值,只要跟踪算法没有丢失目标,这个id值就一直不会变,因此这个值就可以用来区分不同的物体。比如,同一个人一直都是一个id值,除非跟踪算法丢失了这个人。

我们可以一边遍历Results的结果一边把id值放在一个set()中,最后统计set()的长度,这样就实现了统计一个视频中的人数。

我们在视频中划定两个区域,如本篇文章的第一个视频所示,线的上方和下方其实各有一个不可见的区域。如果一个人的出现在上面的区域,之后又出现下面的区域,说明这个人是从视频的上方向下方行走,这样就可以知道一个人的轨迹方向了,就可以按照方向统计人流量了。比如本篇文章的第一个视频,人物从视频下方向上方走,视为‘出’,而从上方移动到下方,视为‘进’。

另外,限于本篇文章的篇幅,更细致的逻辑讲解、代码实现将在源码注释中体现,需要源码的小伙伴记得给文章点赞收藏哦。源码资源放在公众号中了,微信公众号搜索 ‘编程学习园地’,关注公众号,在聊天窗口回复关键字“yolo8实战”即可获得下载链接。

  • 15
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
智慧交通基于YOLOv8行人车辆检测计数系统源码(部署教程+训练好的模型+各项评估指标曲线).zip 平均准确率:0.91 类别:person、truck、car、bus、traffic light 【资源介绍】 1、ultralytics-main ultralytics-main为YOLOv8源代码,里面涵盖基于yolov8分类、目标检测额、姿态估计、图像分割四部分代码,我们使用的是detect部分,也就是目标检测代码 2、搭建环境 安装anaconda 和 pycharm windows系统、mac系统、Linux系统都适配 在anaconda中新建一个新的envs虚拟空间(可以参考博客来),命令窗口执行:conda create -n YOLOv8 python==3.8 创建完YOLOv8-GUI虚拟空间后,命令窗口执行:source activate YOLOv8 激活虚拟空间 然后就在YOLOv8虚拟空间内安装requirements.txt中的所有安装包,命令窗口执行:pip install -r requirements.txt 使用清华源安装更快 3、训练模型过程 进入到\ultralytics-main\ultralytics\yolo\v8\detect\文件夹下,datasets即为我们需要准备好的数据集,训练其他模型同理。 data文件夹下的bicycle.yaml文件为数据集配置文件,该文件为本人训练自行车检测模型时创建,训练其他模型,可自行创建。博文有介绍https://blog.csdn.net/DeepLearning_?spm=1011.2415.3001.5343 train.py中238行,修改为data = cfg.data or './bicycle.yaml' # or yolo.ClassificationDataset("mnist") 237行修改自己使用的预训练模型 若自己有显卡,修改239行,如我有四张显卡,即改成args = dict(model=model, data=data, device=”0,1,2,3“) 以上配置完成后运行train.py开始训练模型,训练完毕后会在runs/detect/文件夹下生成train*文件夹,里面包含模型和评估指标等 4、推理测试 训练好模型,打开predict.py,修改87行,model = cfg.model or 'yolov8n.pt',把yolov8n.pt换成我们刚才训练完生成的模型路径(在\ultralytics-main\ultralytics\yolo\v8\detect\runs\detect文件夹下),待测试的图片或者视频存放于ultralytics\ultralytics\assets文件夹, 运行predict.py即可,检测结果会在runs/detect/train文件夹下生成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

城南皮卡丘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值