使用Yolov8 + BotSORT 跟踪在自定义数据集上进行球员和球检测

 
 

点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

目标:本博客旨在了解YOLO体系结构,并在自定义数据集上对其进行训练,然后微调模型以获得更好的结果,并进行推理以了解最佳工作方式。

YOLO代表什么?

YOLO(You Only Look Once)是一种先进的目标检测算法,由于其革命性的单次检测技术而声名鹊起,该技术提高了其速度和准确性,超越了同类产品。

YOLOv1最初是在2015年提出的,将目标检测视为回归问题,使用边界框计算类别概率。它经过多次改进,目前由Ultralytics维护,后者发布了最新版本Yolov8。

简要了解YOLO算法的工作原理

顾名思义,YOLO算法在图像上进行单次预测,这比传统方法更好,传统方法使用滑动窗口在整个图像上进行卷积,或者使用多个位置的区域提案来定位对象。

YOLO通过将图像划分为S x S网格(如下所示)来实现这一点,其中每个网格单元负责生成边界框和置信度得分输出。

2b233d65c97e5726f0ae726de9f4737d.png

对于图像中的每个网格单元,我们计算以下内容:

2588cbf67151478895c7474fd248f830.png

目标变量的格式,每个网格单元的第一个单元是置信度值,这只是一个标签,决定网格单元内是否存在任何对象(0或1)。如果答案是肯定的,那么我们继续预测xywh格式的边界框的值,其中x和y是边界框中心的坐标,w和h是边界框的宽度和高度。最后,我们有我们的类概率分布向量,其中包含每个对象标签的预测分数,范围在0到1之间。

e3b4b7a0d98cfa4994af030802e71049.png

使用上述图像的网格单元的示例输出

如果我们看一下上面的图像,我们可以清楚地看到蓝色的边界框定义了狗对象的真实边界。当我们查看绿色网格单元的输出向量时,我们试图预测蓝色边界框的中心,这是我们的真实标签。

首先,我们确定该网格单元中是否存在对象,由于答案是肯定的,我们可以继续分配xywh值,您可能已经注意到宽度和高度值超出了0和1的范围。这是因为整个边界框的真实标签跨越了绿色网格单元并且在高度和宽度上需要多于3个网格单元。最后,关于我们的类概率分数,绿色网格单元只包含doog对象,因此我们可以轻松地为狗对象分配分数1,而对于车对象则为0。

另外,如果我们看一下黄色网格单元,我们知道它不包含任何对象,因此我们可以简单地为其输出向量分配置信度值0。这里的“x”表示不关心的项,这意味着我们可以安全地忽略输出向量中的所有其他值。

e9e57c388c89c572af720a87adae1522.jpeg

训练Yolov8模型使用自定义数据集

现在,让我们继续使用来自Roboflow的Player and Ball Detection数据集,并使用Yolov8进行训练:

数据集链接:https://universe.roboflow.com/nikhil-chapre-xgndf/detect-players-dgxz0

首先,我们需要安装Ultralytics,它维护了所有Yolo模型:

pip install ultralytics

接下来,我们需要设置一个YAML文件以配置一些训练参数:

path: absolute path to dataset (/path/to/dataset)
train: relative path from dataset (/train)
test: relative path from dataset (/test)
val: relative path from dataset (/val)


# Define Classes and their Labels


names:
  0: Ball
  1: Player
  2: Referee

接下来,我们需要选择一个Yolov8模型权重来开始我们的训练:

0bf98189aeaad6c4094d4686664cbbe0.jpeg

在我们的用例中,我们将使用Yolov8n(Nano),它是最轻量级和最快速的模型,虽然根据mAP分数来说它并不是最准确的模型,但经过足够的训练,它可以在视频跟踪时产生更好的fps并得到良好的结果。

from ultralytics import YOLO
import torch
import os


# Load the YOLOv8 model
model = YOLO('yolov8n.pt')


# TRAINING
if __name__ == '__main__':      
    results = model.train(data="config.yaml", epochs=50, patience=5)

如上所示,我们可以简单地从之前设置的config.yaml文件中加载数据。我们将开始进行100个时期的训练,并设置一个持续10个时期的耐心参数,这意味着如果在连续的10个时期内没有改进,则模型将提前停止训练。

为获得更好的结果而提高网络维度

在训练过程中我面临的最大挑战是“球”类别的低mAP分数,花了一些时间我才意识到出了什么问题。Yolov8通常期望输入图像为正方形格式,在非正方形图像的情况下,默认将所有图像调整为宽度为640px的图像,保持纵横比以维持高度。除非另有规定,如下所示。

9dd56e7cd125acadf3ec12143d968af8.jpeg

原始图像,尺寸为1920x1080

5988b3e1f9d2a9448278cfd422a279d7.jpeg

Yolov8调整大小的图像,尺寸为384x640以保持纵横比

使用GIMP比较“球”类的大小

b5e81f2e175a071152791ad0edead8b1.png7a46aae2a77ab150860bf12247b6ecf6.png

d7ed2c4583f51fc0e84d9e3fd0bdb2c8.png

原始图像中“球”类的像素大小

803720214b0e8e11ce9d4a275970461a.png

压缩图像中“球”类的像素大小

在两张图像中,对象图像的质量和大小的减小都很明显,因此导致模型的检测效果差。在训练时增加图像大小可以获得更好的mAP分数,不仅对于“球”类别,对于所有其他类别也是如此。

但是,这意味着我们应该始终使用最高分辨率的图像进行训练和推理以获得最佳结果,对吗?这个答案取决于情况,因为增加模型的网络维度将导致模型使用更多的训练资源并使其变慢。因此,我们需要找到一个平衡速度和模型准确性的最佳点。

4a8f1fdea87ba50a8076b82857e97682.png

此外,请记住,根据YOLO文档,网络维度只能是32的倍数。因此,经过一些思考,我决定使用1088作为图像大小,考虑到最小对象的最小图像大小应大于15x15像素。

模型性能

37494dc911adfe02c6c78ae862243737.png

一旦我们完成训练,我们可以使用上面显示的指标查看训练/验证结果,Yolov8为每个详细指标准备了一个充满图表和可视化的目录,以及模型权重,上面只是一个简要摘要。

现在,我们可以使用这个训练结果目录,将权重上传回Roboflow以部署为模型,这可以用于辅助图像标注,或者可以简单地在线部署供公众使用。

ea752fb9a6c1348f615fabcc9b8f0e95.png

在Roboflow上查看指标

使用我们的模型权重进行推理

现在,我们可以加载我们刚刚训练的最佳权重,然后使用Ultralytics提供的BoTSORT跟踪器对视频剪辑进行跟踪,而不是使用默认权重。

import cv2
from ultralytics import YOLO


# Load the YOLOv8 model
# model = YOLO('yolov8n.pt')          ### Pre-trained weights


model = YOLO('runs/detect/train2/weights/best.pt')          ### weights from trained model


# Open the video file
video_path = r"path/to/video"
cap = cv2.VideoCapture(video_path)


# Loop through the video frames
while cap.isOpened():
    # Read a frame from the video
    success, frame = cap.read()


    if success:
        # Run YOLOv8 tracking on the frame, persisting tracks between frames
        results = model.track(frame, persist=True, show=True, tracker="botsort.yaml")


        # Visualize the results on the frame
        annotated_frame = results[0].plot()


        # Display the annotated frame
        cv2.imshow("YOLOv8 Tracking", annotated_frame)


        # Break the loop if 'q' is pressed
        if cv2.waitKey(1) & 0xFF == ord("q"):
            break
    else:
        # Break the loop if the end of the video is reached
        break


# Release the video capture object and close the display window
cap.release()
cv2.destroyAllWindows()

向我们的检测模型添加跟踪有助于在视频剪辑的连续帧之间跟踪物体,它通过为每个检测到的对象分配一个唯一的ID来实现这一目标。因此,它还可以帮助绘制对象(如足球)随时间变化的轨迹,并基于其在帧之间的运动绘制路径。

最终结果

2929dda7abaa1ca94e4efc1058d0c3ce.png

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程,即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。


下载2:Python视觉实战项目52讲
在「小白学视觉」公众号后台回复:Python视觉实战项目,即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。


下载3:OpenCV实战项目20讲
在「小白学视觉」公众号后台回复:OpenCV实战项目20讲,即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。


交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~
BoT-SORT是发表于2022年的先进的多目标跟踪算法,它结合了运动外观信息、相机运动补偿更准确的卡尔曼滤波状态向量,并把这些改进集成到ByteTrack,从而在MOTA、IDF1HOTA性能指标上超过了ByteTrack,增强了目标跟踪的鲁棒性,比较适用于存在相机运动的场景。YOLOv8代码中已集成了BoT-SORT。本课程使用YOLOv8BoT-SORT对视频中的行人、车辆做多目标跟踪计数与越界识别,开展YOLOv8目标检测BoT-SORT多目标跟踪强强联手的应用。课程分别在WindowsUbuntu系统上做项目演示,并对BoT-SORT原理代码做详细解读(使用PyCharm单步调试讲解)。课程包括:基础篇、实践篇、原理篇代码解析篇。Ÿ  基础篇包括多目标跟踪任务介绍、常用数据集评估指标;Ÿ  实践篇包括Win10Ubuntu系统上的YOLOv8+BoT-SORT的多目标跟踪计数与越界识别具体的实践操作步骤演示;Ÿ  原理篇中讲解了马氏距离、匈牙利算法、卡尔曼滤波器、SORT、DeepSORTBoT-SORT多目标跟踪算法的原理,并解读了BoT-SORT论文;Ÿ  代码解析篇中使用PyCharm单步调试对BoT-SORT的代码逐个文件进行讲解。课程提供代码解析文档。相关课程:《YOLOv8+ByteTrack多目标跟踪(行人车辆计数与越界识别)》https://edu.youkuaiyun.com/course/detail/38901《YOLOv8+DeepSORT多目标跟踪(行人车辆计数与越界识别)》 https://edu.youkuaiyun.com/course/detail/38870《YOLOv5+DeepSORT多目标跟踪与计数精讲》https://edu.youkuaiyun.com/course/detail/32669 
E:\anaconda\envs\cycy\python.exe C:\Users\14480\Desktop\毕设\ultralytics\ultralytics-main\train.py New https://pypi.org/project/ultralytics/8.3.90 available 😃 Update with 'pip install -U ultralytics' Ultralytics YOLOv8.2.50 🚀 Python-3.10.16 torch-2.6.0+cu118 CUDA:0 (GeForce GTX 1650 Ti, 4096MiB) Traceback (most recent call last): File "C:\Users\14480\Desktop\毕设\ultralytics\ultralytics-main\ultralytics\engine\trainer.py", line 551, in get_dataset data = check_det_dataset(self.args.data) File "C:\Users\14480\Desktop\毕设\ultralytics\ultralytics-main\ultralytics\data\utils.py", line 269, in check_det_dataset file = check_file(dataset) File "C:\Users\14480\Desktop\毕设\ultralytics\ultralytics-main\ultralytics\utils\checks.py", line 509, in check_file raise FileNotFoundError(f"'{file}' does not exist") FileNotFoundError: 'C://Users//14480//Desktop//毕设//ultralytics//ultralytics - main//dataset//data.yaml' does not exist The above exception was the direct cause of the following exception: Traceback (most recent call last): File "C:\Users\14480\Desktop\毕设\ultralytics\ultralytics-main\train.py", line 12, in <module> model.train(data="C://Users//14480//Desktop//毕设//ultralytics//ultralytics - main//dataset//data.yaml", File "C:\Users\14480\Desktop\毕设\ultralytics\ultralytics-main\ultralytics\engine\model.py", line 644, in train self.trainer = (trainer or self._smart_load("trainer"))(overrides=args, _callbacks=self.callbacks) File "C:\Users\14480\Desktop\毕设\ultralytics\ultralytics-main\ultralytics\engine\trainer.py", line 133, in __init__ self.trainset, self.testset = self.get_dataset() File "C:\Users\14480\Desktop\毕设\ultralytics\ultralytics-main\ultralytics\engine\trainer.py", line 555, in get_dataset raise RuntimeError(emojis(f"Dataset '{clean_url(self.args.data)}' error ❌ {e}")) from e RuntimeError: Dataset 'C://Users/14480/Desktop//ultralytics/ultralytics - main/dataset/data.yaml' error 'C://Users//14480//Desktop////ultralytics//ultralytics - main//dataset//data.yaml' does not exist engine\trainer: task=detect, mode=train, model=ultralytics/cfg/models/v8/yolov8n.yaml, data=C://Users//14480//Desktop//毕设//ultralytics//ultralytics - main//dataset//data.yaml, epochs=300, time=None, patience=100, batch=32, imgsz=640, save=True, save_period=-1, cache=False, device=None, workers=8, project=runs/train, name=exp6, exist_ok=False, pretrained=True, optimizer=SGD, verbose=True, seed=0, deterministic=True, single_cls=False, rect=False, cos_lr=False, close_mosaic=0, resume=False, amp=True, fraction=1.0, profile=False, freeze=None, multi_scale=False, overlap_mask=True, mask_ratio=4, dropout=0.0, val=True, split=val, save_json=False, save_hybrid=False, conf=None, iou=0.7, max_det=300, half=False, dnn=False, plots=True, source=None, vid_stride=1, stream_buffer=False, visualize=False, augment=False, agnostic_nms=False, classes=None, retina_masks=False, embed=None, show=False, save_frames=False, save_txt=False, save_conf=False, save_crop=False, show_labels=True, show_conf=True, show_boxes=True, line_width=None, format=torchscript, keras=False, optimize=False, int8=False, dynamic=False, simplify=False, opset=None, workspace=4, nms=False, lr0=0.01, lrf=0.01, momentum=0.937, weight_decay=0.0005, warmup_epochs=3.0, warmup_momentum=0.8, warmup_bias_lr=0.1, box=7.5, cls=0.5, dfl=1.5, pose=12.0, kobj=1.0, label_smoothing=0.0, nbs=64, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, degrees=0.0, translate=0.1, scale=0.5, shear=0.0, perspective=0.0, flipud=0.0, fliplr=0.5, bgr=0.0, mosaic=1.0, mixup=0.0, copy_paste=0.0, auto_augment=randaugment, erasing=0.4, crop_fraction=1.0, cfg=None, tracker=botsort.yaml, save_dir=runs\train\exp6 进程已结束,退出代码为 1
03-15
从错误信息来看,您正在尝试运行 Ultralytics 的 YOLO 模型训练脚本 `train.py`。然而程序遇到了一个问题导致崩溃,以下是具体的分析及解决方案: --- ### 错误原因分析: 1. **数据配置文件缺失** 根据报错内容: ``` FileNotFoundError: 'C://Users//14480//Desktop//毕设//ultralytics//ultralytics - main//dataset//data.yaml' does not exist ``` 表明您的代码无法找到指定路径下的 `data.yaml` 文件。该文件通常用于定义数据集的结构(例如图片目录、标签目录等),而缺少此文件将导致模型无法加载正确的数据。 2. **路径问题** 路径中的双斜杠 `\` 正斜杠 `/` 可能会引发兼容性问题,尤其是当系统环境切换到 Windows 或 Linux 之间时。需要确认路径是否正确无误,并避免混合使用不同操作系统的分隔符。 3. **其他潜在问题** 如果路径文件都检查没问题,则可能是 YAML 配置本身有问题或不完整。 --- ### 解决方案步骤: #### 步骤一:确认 `data.yaml` 文件是否存在 首先,请手动打开以下路径并验证文件存在与否: ``` E:\Anaconda\envs\cycy\Python.exe 所在机器上, C:/Users/14480/Desktop/毕设/ultralytics/ultralytics-main/dataset/ ``` 如果确实不存在该文件,请按照官方文档生成一个新的 `data.yaml` 示例文件。 示例 `data.yaml` 内容如下(假设为检测任务): ```yaml # 数据集根目录 path: dataset/ # 训练集、验证集测试集划分 train: images/train val: images/valid test: images/test # 类别数及相关名称映射 nc: 2 # 类别数量 names: ['class_1', 'class_2'] # 各类别名列表 ``` #### 步骤二:修改路径设置 确保传递给 `model.train()` 函数的数据路径准确且规范。推荐直接提供相对路径而非绝对路径。如: ```python model.train(data="dataset/data.yaml", ...) ``` 同时注意替换所有反斜杠`\`为正斜杠`/`以保证跨平台兼容性。 #### 步骤三:检查依赖版本 根据日志开头提示更新最新版超体框架可以修复某些未预见的问题: ``` pip install -U ultralytics ``` 此外还应关注PyTorch与CUDA驱动匹配状况,当前显示torch-2.6.0+cu118表示采用的是支持CuDNN v11.8版本GPU加速库。 --- ### 总结建议 经过以上排查后再次启动训练命令行即可恢复正常工作流程;若仍存在问题则需逐级调试每一步输入输出直至定位根本症结所在点为止!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小白学视觉

您的赞赏是我们坚持下去的动力~

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

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

打赏作者

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

抵扣说明:

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

余额充值