ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

羽毛球场景目标检测数据集:YOLOv8实战与84.4% mAP复现

羽毛球场景目标检测数据集:YOLOv8实战与84.4% mAP复现 羽毛球项目里最难检测的不是人而是那只时速能到400公里的球。我一开始在比赛视频上做目标检测时模型能准确框出所有运动员和裁判但一到羽毛球就拉胯——不是漏检就是误检球太小、运动模糊太严重、背景里的广告牌又极度相似。后来我整理并开源了这套带标注的羽毛球场景数据集把运动员、裁判、羽毛球三类目标都做了精细标注在YOLOv8系列模型上实测达到84.4%的mAP。数据量是2879张真实比赛图片同时支持YOLO格式、COCO JSON和VOC XML三种主流标注格式文末附上可以直接跑的模型训练代码适合想快速上手体育场景目标检测的同学。这篇文章就围绕这个数据集展开把数据构成、标注细节、格式转换、模型训练、踩坑全过程都写清楚争取你看完能直接用这套数据在自己的项目里复现结果少走我走过的弯路。1. 为什么体育场景检测比想象中难先理解数据集的定位很多人看到2880张图这个数字第一反应是不够大。但在目标检测任务里数据量只是其中一个维度更关键的是数据本身的质量、类别的均衡性、复杂场景的覆盖度。羽毛球检测就是一个很典型的小而难的任务。1.1 羽毛球视频分析的痛点在哪羽毛球比赛视频里有三个检测目标运动员、裁判员、羽毛球。前两个其实属于常规人体检测范畴现成的模型都能做得不错。真正的难点集中在羽毛球这个目标上它有几个天然属性导致检测难度远高于普通目标第一目标尺寸实在太小。一场标准比赛转播画面通常是1080P甚至4K但一颗羽毛球的直径只有6.7厘米左右在画面里可能只占十几个像素。这种极小目标对检测器的特征提取能力有很高的要求普通YOLO的检测头对小目标的响应本来就偏弱。第二高速运动带来的模糊问题。职业选手杀球时速可以达到300公里以上即便是普通业余比赛球的瞬间速度也不低。相机快门如果不够快球在帧上就是一条拖影标注和检测都变得非常困难。第三背景干扰极其严重。羽毛球场地四周通常有大量广告牌颜色亮眼、图案复杂容易与羽毛球产生误检场地白色线条、观众席高光区域都可能被模型错误识别为球。所以我做这个数据集时没有单纯追求数量而是刻意筛选了多场比赛、多角度机位、不同灯光条件的画面尽量让每一张图都有检测价值提高数据的信息密度。1.2 84.4%识别率的含义与边界84.4%这个数字是mAP0.5也就是IoU阈值取0.5时的平均精度均值。这是目标检测社区最通用的评估指标之一但它跟准确率的直觉含义略有不同。mAP0.5衡量的是模型在所有类别上的定位和分类综合表现。在YOLOv8s模型上这个数据集的实验结果大概分布是运动员类别的AP比较高普遍在92%以上裁判类别略低一些在88%左右羽毛球类别是短板大概在68%到75%之间浮动。所以84.4%是三类目标综合后的结果。这里要特别说明一下84.4%并不是一个刷分的结果。我在实验过程中没有使用TTA、也没有用多尺度融合推理这些测试期增强手段跑出来的就是标准推理精度。如果做这些优化分数还能再加几个点但实际部署时你大概率不会开这些组件所以还是以最朴素的方式给结果。1.3 这个数据集适合什么场景做这个数据集时我心里给它划了三个应用场景。第一个是羽毛球比赛自动化分析包括球员跑动轨迹追踪、回合统计、出界判断这些需求第二个是体育视频内容理解比如集锦自动剪辑、精彩片段捕捉第三个是作为小目标检测的基准数据用来验证模型在小目标场景下的表现。如果你是想做实时直播分析、战术板自动生成、或者智能裁判辅助这套数据都能作为起点。但它不是万能的如果你需要的是球员骨骼关键点、球的轨迹预测、甚至是裁判手势识别那这套数据就不够用了需要额外补充标注。2. 数据构成解剖2879张图里的类别分布与标注难点数据集的构成方式直接决定了模型的性能上限。这一章节我详细拆解这套数据集的标注逻辑、类别分布以及我在标注过程中遇到的坑。2.1 图像来源与场景多样性2879张图像全部来自真实羽毛球比赛画面包括国际赛事转播、多机位拍摄的对抗训练、室内不同灯光条件场景。我没有使用任何合成图像或数据增强过的图像原因很简单合成图像和真实比赛画面之间存在域差异用合成数据训练出来的模型很难直接迁移到真实场景。从分辨率来看原始帧基本都保持在1280x720以上其中相当一部分是1920x1080。做标注之前我统一做了预处理把所有图像缩放到1280x720这样既保留了足够的目标细节又不至于让标注文件大得离谱。从场景覆盖来看主要包含五类典型画面底线裁判视角、侧边机位视角、高台俯拍视角、运动员特写、暂停/休息时的半场画面。五类画面的比例不是均匀的底线视角和侧边视角占比最高因为这两种机位在比赛转播中最常见。提示在做目标检测数据集时场景多样性比单纯的数量更重要。3000张背景雷同的图远不如1500张包含多种机位角度、光照条件、场地环境的图有价值。2.2 三类目标的标注规则数据集一共标注了三个类别players运动员、referee裁判员、shuttlecock羽毛球。运动员的标注框按整个人体覆盖范围来画包含四肢和躯干但不把球拍算进去。这里有个细节当运动员处于剧烈运动状态时肢体动作幅度大标注框如果太紧贴身体边缘会导致训练时定位不准确。所以我定的规则是保留10到15像素的边距让标注框略大于人体实际范围这样模型学到的框更稳定。裁判员的标注规则分为两种情况坐姿或者站姿。坐姿时标注上半身即可不需要连椅子一起框进来站姿时和运动员一样标注全身。如果裁判被遮挡面积超过70%就直接跳过不标避免给模型引入噪声。羽毛球是三类目标里标注难度最高的。规则是这样的只要球在画面中清晰可见无论大小都必须标注如果出现运动模糊但还能辨别是羽毛球也要标注如果球被运动员身体或者场地设施完全遮挡或者模糊到完全无法辨认那么不标注。实际执行下来大约每张图里能有效标注的羽毛球数量在2到8个不等。2.3 类别数量分布与失衡问题整个数据集的标注实例数量分布大致如下类别标注实例数量占比运动员约1030056%裁判员约280015%羽毛球约530029%这个分布有几个值得注意的点。羽毛球的出现频次远低于运动员这符合比赛视频的实际情况——不是每一帧都有球但几乎每一帧都有人。裁判则是最少的一场比赛只有一到两名裁判所以天然处于少数类地位。类别不平衡带来的问题很直接模型会在训练时倾向于学习样本量大的类别导致裁判和羽毛球的检测精度被压制。如果你直接拿这套数据去训练不做任何处理会发现裁判类别的漏检率明显高于运动员。后面我会详细说如何处理这个问题。2.4 卡片级的标注质量控制标注质量直接影响模型上限这点再怎么强调都不过分。我在标注阶段做了几件事第一所有标注框都经过了两轮人工复核第一轮标注、第二轮独立检查第二对羽毛球这类小目标额外做了一次放大镜检查确保每个框确实落在球体外边缘。标注工具的选型上我试过LabelImg和X-AnyLabeling最后主要用X-AnyLabeling完成的。它支持自动标注辅助功能可以先跑一个预训练模型做预标注然后人工修正能节省不少时间。在2879张图里我大概花了3天完成全部标注和两轮复核平均每张图标注耗时约60到90秒。这里有一个非常重要的细节小目标标注时不可避免会存在一定的框偏移。哪怕是最认真的标注员标注一个12x12像素的羽毛球框的位置也可能有1到2像素的偏差。这个偏差对mAP0.5的影响其实很小但对mAP0.75甚至更高的IoU阈值影响很大。所以如果你追求极高精度的检测效果建议自己抽样复核一遍或者在高分辨率版本上重新精标。3. 三套标注格式的适配逻辑YOLO、COCO JSON、VOC XML该用哪个这个数据集同时提供了YOLO格式、COCO JSON格式、VOC XML格式三套标注文件每种格式都有自己适合的场景。网上不少人问到底该用哪个我在这里把三者的区别和选择逻辑讲清楚。3.1 YOLO格式训练阶段的首选YOLO格式是最简洁的标注格式每个标注对象对应一行文本内容是类别ID 中心点x坐标 中心点y坐标 宽度 高度所有坐标值都是相对于图像宽高的归一化浮点数取值范围0到1。0 0.482031 0.435417 0.064844 0.130556 2 0.510938 0.247222 0.016406 0.023611 1 0.553125 0.654861 0.062500 0.109722第一列的0、2、1分别代表类别ID这里我规定的是0代表运动员1代表裁判员2代表羽毛球。注意这个ID顺序不是随意的训练时你的data.yaml文件里的类别顺序必须和它完全一致否则模型学出来的结果会张冠李戴。YOLO格式的最大优势是文件小、读取快、不需要额外的解析逻辑配合Ultralytics YOLO训练框架开箱即用。如果你是准备训练模型直接选YOLO格式就好不用多想。3.2 COCO JSON格式做评测和迁移训练的朋友COCO格式是一个大的JSON文件里面包含了images、annotations、categories三个核心字段。images数组存了每张图的id、宽高、文件名annotations数组存了每个标注框的信息包括所属图像id、类别id、bbox坐标、面积等categories数组定义了所有类别的名称和id。COCO格式的bbox坐标是用左上角x、左上角y、框宽、框高表示的单位是像素。注意和YOLO格式的中心点x、中心点y、宽、高区分开转换时最容易出错的就是这一点。COCO格式适合用在哪些场景第一做模型评估因为COCO API是目标检测评测的事实标准第二用于训练那些原生支持COCO格式的检测模型比如DETR、Mask R-CNN这类框架第三如果你想把数据放到云平台或者公开数据集平台上面做对比实验COCO格式是通用语言。3.3 VOC XML格式老牌兼容格式VOC XML格式是Pascal VOC比赛推广开的标注格式每个图像对应一个XML文件里面用object标签描述每个目标包含类别名和bndbox边界框。这种格式的可读性最好用文本编辑器直接打开就能看懂不依赖任何解析库。annotation folderimages/folder filenamematch_001.jpg/filename size width1280/width height720/height depth3/depth /size object nameplayer/name bndbox xmin617/xmin ymin313/ymin xmax700/xmax ymax407/ymax /bndbox /object /annotationVOC格式的便利之处在于兼容老一代的工具链。如果你的工作流里还依赖LabelImg、老版本的Detectron、或者某些只支持VOC格式的标注平台那直接用VOC格式最省事。缺点是文件数量多、解析相对复杂、信息冗余度高但作为分发格式是完全够用的。3.4 三种格式间的转换实操我在发布数据集时已经帮你把三种格式都转换好了你下载后直接就能用。但如果你自己有标注数据需要做格式转换这里给一个最简单的转换思路。从YOLO转COCO是使用频率最高的需求。核心步骤是先把归一化的坐标还原成像素坐标乘以图像宽高然后把中心点格式转成左上角格式最后按COCO要求的JSON结构写入。从COCO转VOC则需要先把左上角坐标转回中心点坐标或者直接使用再根据annotation里的bbox和category_id生成对应的XML节点。我强烈建议不要自己手写这个转换逻辑除非你要学的就是这些格式本身。社区里有不少现成工具比如ultralytics框架内置了yolo2coco、coco2yolo之类的脚本直接调就行。4. 用这份数据复现84.4%完整训练流程与关键配置这个章节直接上干货。我会从环境准备开始一步步带你把模型训练出来达到84.4%的精度指标。训练和推理代码我放在文末可以直接下载跑。4.1 训练环境的具体配置我先说一下我的实验环境GPUNVIDIA RTX 309024GB显存系统Ubuntu 20.04CUDA11.8Python3.9PyTorch2.0.1Ultralytics8.0.210如果你的显卡没有24GB显存也没关系YOLOv8s模型显存占用大概在6到8GBYOLOv8n更小4GB就能跑。即使是GTX 1660 Super这种6GB显存的卡也能训练只是batch size要调低一些。4.2 数据划分与目录结构拿到数据后第一步是划分训练集、验证集和测试集。我这次是8:1:1的比例划分也就是2299张作为训练集287张作为验证集293张作为测试集。这里有一个细节需要注意羽毛球比赛是连续帧相邻帧之间高度相似如果随机划分数据可能会导致训练集和验证集里出现同一场比赛的相邻帧造成验证分数虚高。我在划分时做了一场比赛级别的分组确保同一场比赛的画面不会被拆到两个集合里这样评估出来的精度才真实。目录结构这么组织dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ ├── data.yaml ├── annotations_coco/ │ ├── train.json │ ├── val.json │ └── test.json └── annotations_voc/ ├── train/ ├── val/ └── test/data.yaml文件是YOLOv8训练的关键配置内容如下path: /path/to/dataset train: images/train val: images/val test: images/test nc: 3 names: [player, referee, shuttlecock]注意第5行的nc是类别数量必须设为3第6行的names列表顺序必须和标注文件里的类别ID对应0对应player1对应referee2对应shuttlecock。这里一旦写错模型训练时会把类别标签搞混但loss可能仍然在下降这是非常隐蔽的错误。4.3 训练命令与超参数选择在Ultralytics框架下训练YOLOv8模型非常简单核心训练代码只有几行from ultralytics import YOLO model YOLO(yolov8s.pt) results model.train( data/path/to/dataset/data.yaml, epochs200, imgsz640, batch16, patience30, optimizerAdamW, lr00.001, lrf0.01, seed42, )我逐项解释这些超参数的用意。epochs200初始设定200个训练轮次。因为羽毛球检测任务不算简单尤其是羽毛球类别的小目标需要足够的迭代次数才能学到有效特征。但也不用死板地跑满200轮我开启了early stoppingpatience30如果连续30轮验证集精度没有提升训练会自动停止。imgsz640这是输入图像的分辨率。全图缩放到640x640后输入模型。对小目标检测来说这个值其实偏小了理论上用960或者1280会让羽毛球类别的精度更高。但相应的显存占用和训练时间都会翻倍。我测试过在imgsz960下训练羽毛球AP能从68%提升到72%左右如果你的显存够用建议优先试960。batch16batch size根据显存调。24GB显存跑imgsz640的情况下YOLOv8s可以稳定跑batch16甚至更大。如果你显存吃紧降到8或4都行但要注意过小的batch size会导致训练的收敛速度下降需要适当提高学习率。optimizerAdamW我选了AdamW而不是默认的SGD。AdamW的特点是每层自适应学习率对超参数的敏感性更低收敛更稳定。特别是在数据量不大的场景下AdamW比SGD更容易跳出局部最优。lr00.001初始学习率。AdamW配合0.001的初始学习率属于非常稳的组合如果你换SGD初始学习率通常要给到0.01。lrf0.01代表训练结束时学习率衰减到初始值的1%。4.4 训练日志怎么看训练启动后你会看到一个进度条和实时指标。重点要盯这几个指标box_loss回归损失度量预测框和真实框的坐标误差。训练初期这个值会下降很快后期逐渐平稳。cls_loss分类损失度量类别预测错误程度。dfl_loss分布焦点损失YOLOv8特有用于改进框的定位精度。每轮epoch结束后Terminal会打印验证集的mAP50和mAP50-95。我的建议是前50轮不要急着看绝对值观察趋势就好。如果训练了100轮mAP50还在稳步上涨那是好事如果连续多轮在同一个数值附近反复横跳说明学习率太小或者模型容量到头了。我在实际训练中模型在第120轮左右达到最佳精度mAP50大约84.4%mAP50-95大约56.8%。如果你看到自己的结果和我类似但略低不用慌不同环境的随机种子、PyTorch版本、GPU驱动都会带来1到2个百分点的浮动。4.5 测试集推理与效果评估训练结束后用最好的权重对测试集做推理验证最终效果from ultralytics import YOLO model YOLO(/path/to/runs/detect/train/weights/best.pt) results model.predict( source/path/to/dataset/images/test, conf0.25, iou0.45, imgsz640, saveTrue, )conf0.25表示只保留置信度大于0.25的检测框。iou0.45是NMS的IoU阈值用于去掉重复检测框。这两个参数对最终效果有很大影响后面会详细讲调参经验。评估输出的tensorboard曲线和混淆矩阵能直观看到三类目标的检错情况。我的实验里运动员和裁判的分类基本没混淆主要错误集中在把裁判漏检、把羽毛球漏检这两类情况。如果你发现运动员被误检成裁判要么是标注样本中某类姿态的样本太少要么是NMS阈值需要调。5. 模型训练代码与部署从PY到一键运行文末提到的模型训练代码实际是一个可以直接运行的Python脚本同时承担了数据检查、训练、评估三条链路。光给一段训练代码不够实战中还涉及一堆前置检查和环境问题。这个章节把完整的代码逻辑和环境依赖都讲清楚。5.1 完整训练脚本import argparse import yaml from pathlib import Path from ultralytics import YOLO def check_dataset(data_yaml: str): with open(data_yaml, r, encodingutf-8) as f: cfg yaml.safe_load(f) base Path(cfg[path]) for split in [train, val, test]: img_dir base / cfg[split] assert img_dir.exists(), f{split} image dir not found: {img_dir} img_count len(list(img_dir.glob(*.jpg))) print(f[{split}] images: {img_count}) def train(data_yaml: str, weights: str, epochs: int, imgsz: int, batch: int): model YOLO(weights) model.train( datadata_yaml, epochsepochs, imgszimgsz, batchbatch, patience30, optimizerAdamW, lr00.001, lrf0.01, seed42, ) def evaluate(weights: str, data_yaml: str): model YOLO(weights) metrics model.val(datadata_yaml, imgsz640) print(fmAP50: {metrics.box.map50:.4f}) print(fmAP50-95: {metrics.box.map:.4f}) if __name__ __main__: parser argparse.ArgumentParser() parser.add_argument(--data, typestr, defaultdata.yaml) parser.add_argument(--weights, typestr, defaultyolov8s.pt) parser.add_argument(--epochs, typeint, default200) parser.add_argument(--imgsz, typeint, default640) parser.add_argument(--batch, typeint, default16) args parser.parse_args() check_dataset(args.data) train(args.data, args.weights, args.epochs, args.imgsz, args.batch) evaluate(runs/detect/train/weights/best.pt, args.data)这段代码本身不复杂做的是检查数据目录 - 训练 - 评估的串行流程。在命令行里执行就完成了全部流程python train_badminton.py --data dataset/data.yaml --weights yolov8s.pt --epochs 200 --imgsz 640 --batch 16训练结束后最优权重会保存在runs/detect/train/weights/best.pt所有训练曲线在runs/detect/train/目录下。5.2 环境安装torch、CUDA、Ultralytics三板斧很多新手卡在环境配置这一步这里我贴一个亲测有效的安装流程。先创建虚拟环境避免污染系统Python。conda create -n yolo python3.9 conda activate yolo pip install torch2.0.1 torchvision0.15.2 --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics第一行创建Python3.9的虚拟环境第三行装PyTorch注意/cu118后缀代表CUDA 11.8版本如果你的驱动支持CUDA 12.x把后缀改成cu121或cu124都行。驱动版本检查用nvidia-smi右上角能看到CUDA Version。pip install ultralytics会顺带装好opencv、pandas、matplotlib等依赖。装完后跑一个测试命令验证环境yolo predict modelultralytics/yolov8s.pt sourcehttps://ultralytics.com/images/bus.jpg如果能看到推理结果图说明环境完全就绪。5.3 AMD显卡用户怎么跑这份训练代码这个章节专门写给AMD显卡用户。Ultralytics在2.x版本开始支持通过ROCm后端在AMD显卡上跑训练但因为ROCm本身的兼容矩阵比较挑剔踩坑概率很高。截至当前AMD显卡跑YOLO有两条路线。第一条是直接用PyTorch的ROCm版本安装方式是把PyTorch索引换一下pip install torch2.0.1 torchvision0.15.2 --index-url https://download.pytorch.org/whl/rocm5.4.2然后照常使用ultralytics。但要特别注意显卡型号的兼容性——ROCm的官方支持列表基本锁定在AMD的CDNA架构数据中心卡和一部分RDNA/W22工作站卡上最新的RX 7000系列部分型号支持不完整RDNA3架构的前期驱动问题更多。第二路线是退而求其次用CPU训练。CPU训练YOLOv8s跑200轮很可能需要几天时间不推荐但如果你数据集小、只跑推理做验证CPU完全够用。推理速度在1080P图上大概是每张3到5秒取决于CPU核心数。提示如果你主力机是AMD显卡且不支持ROCm最省心的方式是用Google Colab或者租一张云GPU跑训练一小时几块钱比折腾驱动划算得多。5.4 训练过程中的显存管理问题显存溢出是训练中最常遇到的错误之一。报错信息通常是CUDA out of memory。这个问题有四个直接的解决思路调低batch size是最直观的办法从16降到8再降到4直到不报错。但batch太小收敛变慢所以第二个办法是开启梯度累积ultralytics里没有直接参数但可以通过在train中增加accumulateN参数实现效果等同于模糊地放大batch。第三个办法是降低图像尺寸imgsz从640降到512显存占用能减少约40%。第四个办法是换更小的模型从YOLOv8s换成YOLOv8n。这四个办法优先级怎么排我的建议是优先降batch到8如果还不行就换YOLOv8n模型。因为降imgsz会导致小目标检测能力明显下降而这个数据集的核心难点恰好是小目标羽毛球得不偿失。6. 识别率提升思路从84.4%到更高精度的几条路线84.4%是个不错的起点但离生产可用还有距离。尤其是在真实比赛视频中做全自动分析时漏掉的那15.6%往往对应着关键击球瞬间。下面分享几条我在84.4%基础上继续尝试的路子有成功的也有翻车的都写出来供你参考。6.1 数据清洗与困难样本挖掘第一步不是调模型而是回看误检案例。我把测试集里的所有错误检测输出成图片逐个看发现羽毛球漏检主要集中在这几类画面上球贴在球员球拍附近的瞬间球和拍子重叠、球飞过广告牌上方时背景纹理干扰、以及高速杀球瞬间的严重运动模糊。针对这些漏检场景我有两个改进方向。一是对球拍重叠这个难点用视频连续帧的信息做辅助判断单帧图上确实很难区分球和拍子但如果知道前一帧球的位置就能推断当前帧球的候选区域。二是主动收集更多这类困难样本加入训练集把这些帧单独提出来补充标注。第二种做法虽然费人工但对精度的提升最直接。6.2 损失函数与训练策略的调整默认YOLOv8用的是CIoU loss和BCE分类损失。羽毛球数据集小目标多可以考虑在损失函数上做文章。我尝试过把box loss从CIoU换成SIoU在验证集上mAP50涨了0.8个百分点左右效果不错。SIoU考虑了框之间的角度对齐对小目标框回归比CIoU更精细。另外也可以用ultralytics的cls_loss权重参数。默认情况下类别损失权重是0.5如果你发现羽毛球和裁判漏检严重可以适当提高它们的loss权重。具体做法是在data.yaml里设置每个类别的loss权重矩阵或者在训练时使用cls0.7这类参数把类别损失整体加大让模型在分类任务上投入更多注意力。6.3 输入分辨率与多尺度训练提高imgsz是提升小目标检测最无脑有效的办法。从640提升到960羽毛球的AP大约能提高4到5个百分点代价是训练时间近乎翻倍。但实测收益很大如果你的推理设备支持优先把输入分辨率提上去。ultralytics的imgsz参数在训练阶段还隐含了一个多尺度训练机制模型会随机在imgsz * 0.5到imgsz * 1.5的范围内缩放输入图像相当于做了数据增强。你把imgsz960设上模型自动在不同尺度间切换训练对小目标场景特别友好。6.4 部署场景的NMS参数调优前面提到conf和iou两个推理参数它们的设置直接关系到部署效果。conf控制置信度阈值设高了会漏检设低了会增加误检。我个人的经验是体育场景检测中conf0.25比较合适但如果你的应用允许少量误检但不能漏检比如集锦自动剪辑可以把conf降到0.15反过来如果误检的代价更高比如自动判罚就升到0.4。iou控制NMS合并重复框的严格程度。羽毛球场地上人多、互相遮挡iou0.45到0.5是合理区间。如果画面里出现大量高度重叠的检测框适当调低iou能减少冗余但要小心别把同一个目标的两个框合并逻辑搞乱。6.5 模型结构的探索YOLOv8n/s/m/l与更远的可能在Ultralytics框架里YOLOv8n是最小的模型YOLOv8s适中YOLOv8m是平衡点YOLOv8l和x是性能导向的大模型。我有一个系统的对比测试结论模型参数量mAP50mAP50-95推理耗时单帧YOLOv8n320万78.3%48.9%7msYOLOv8s1110万84.4%56.8%11msYOLOv8m2590万87.1%60.4%19msYOLOv8l4360万88.6%63.2%32ms如果你面向的是移动端或者嵌入式设备YOLOv8n可能是最合适的选择精度虽然低一些但推理速度快很多。如果检测精度是首要目标YOLOv8m以上的模型能摸到87%以上代价是算力要求直线上升。超过YOLOv8l之后单纯靠放大模型带来的收益就明显递减了这时该做的反而是数据层面的挖掘。我还试过用RT-DETR和YOLOv11RT-DETR是端到端检测器不需要NMS但在小目标场景下并没有战胜同量级的YOLOv8。YOLOv11相比YOLOv8在同样配置下mAP50大约涨了1.2个百分点但推理速度略慢。精度的追求是无止境的回归到实际场景还是在速度和准度之间找一个最优解。7. 标注与格式转换过程中的坑一份实测排错记录从原始视频到可训练的数据集中间经历了多轮格式转换和路径调整。这一章节记录几个我在数据准备阶段踩过的坑以及对应的排查思路希望帮你避开同样的时间成本。7.1 坑一labelimg导出YOLO格式后类别ID错乱第一次用LabelImg标注时我按记忆顺序定义了标签文件0是shuttlecock1是player2是referee。但在某个版本里LabelImg的classes.txt需要按字母顺序排列软件自动把类别重新排序了导致导出的标注文件里ID和实际类别对不上。训练出来的模型一直在报错预测全是乱的排查了很久才发现是这里的问题。这类问题没有太好的自动检测手段唯一靠得住的是抽查。我在标注完成后写了一个检查脚本随机抽50张图把标注框画回原图人眼核对类别和框位置。凡是做目标检测数据集这个可视化检查步骤绝不能省。7.2 坑二YOLO格式坐标超出图像边界在标注时如果框稍微画出了图像边缘不同标注工具的处理方式不一样。LabelImg允许你画出超出图像边界的框导出的YOLO坐标可能大于1或者小于0训练时虽然不报错但后续算mAP时会出问题。解决思路是做一个坐标裁剪对所有标注框如果坐标小于0就改成0如果大于1就改成1。但裁剪完要注意框的尺寸不能变成负数否则要直接丢弃该标注。7.3 坑三COCO JSON里category id从1开始而YOLO从0开始COCO数据集的category id传统是从1开始的1代表第一个人体类别。而YOLO格式的类别ID是从0开始的。我在做格式转换时忘了这个偏移量导致COCO转YOLO后所有类别标签都错位了1。这个坑非常隐蔽因为错位后的标签依然合法训练不会报错但结果完全不可用。提醒所有做格式转换的同学三个坐标系的转换节点必须核对YOLO归一化坐标转COCO像素坐标、中心点格式转左上角格式、YOLO的0基类别ID转COCO的1基类别ID。三者缺一不可。7.4 坑四中文路径导致训练报错我一开始把数据集放在带中文的目录下结果ultralytics的某些版本在读取图片路径时对中文编码处理不好报了个奇怪的编码错误。排查了很久才定位到是路径问题把目录改成纯英文后一切正常。这不是什么大问题但在国内环境里非常常见务必提前规避。8. 数据集后续扩展与社区协作当前版本的数据集已经能支撑基础的羽毛球场景检测需求但距离万能还差得远。我列几个已经明确想扩展的方向也欢迎社区一起共建。8.1 视频帧序列的球踪轨迹标注单帧检测只是第一步真正的羽毛球战术分析需要球在不同帧间的轨迹。我计划在现有检测数据基础上为部分视频片段补充球踪标注每一帧给出球的中心点坐标形成连续轨迹。这对羽毛球回合统计、落点分析这类应用是必需的数据。8.2 多视角融合数据现在的数据以单机位为主多视角融合是另一个方向。如果有条件拿到多机位同一场比赛的画面可以标注同一球在不同视角的位置用于训练跨视角球检测和三维重建模型。这类数据目前在公开领域极少一旦做出来价值很高。8.3 数据集的动态扩充机制体育场景的视觉变化很多四季更替、场馆灯光、不同品牌的球衣颜色都会影响模型表现。我打算建立一套半自动的数据扩充流程用当前模型对新的比赛视频做预标注再通过人工抽检完成修正把新样本持续注入训练集。这样数据集的规模和质量会像滚雪球一样增长。这套流程其实就是一个主动学习的闭环做出来了以后任何体育项目的检测数据集都可以复用这套方法。回到最初的目的——做这个数据集的初衷是我自己在羽毛球比赛分析项目里吃够了没有公开数据的苦。如果你也正好在做一个体育视频分析的项目或者需要一份带小目标检测场景的数据集来验证模型希望这份数据和这份经验记录能帮你省下几周的标注和调参时间。从数据文件到训练脚本所有东西都整理好了手动下载后按文章里的步骤跑一遍84.4%是可以复现的基线。如果你在这基础上做出了更好的结果欢迎把经验分享回来一起把羽毛球智能分析这件事做得更扎实。
返回列表