ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

黄瓜害虫目标检测数据集:YOLO格式农业视觉实战指南

黄瓜害虫目标检测数据集:YOLO格式农业视觉实战指南 简介黄瓜害虫目标检测数据集面向农业AI开发者与植保科研人员聚焦蚜虫、果蝇、南瓜甲虫、潜叶虫、粉虱五类高危害害虫所有图像均采集自真实农田环境覆盖不同生长阶段与光照条件。包内共1429个文件包含907张jpg图片、519个配套txt标注文件另附yaml配置说明与docx文档标注采用标准化YOLO格式兼容YOLOv5/v8等主流框架可直接用于模型训练与评估。资源包压缩后约158.58MB目录组织清晰便于按类别检索。目前已有193人学习适合用于智能农业监测系统开发、害虫自动识别、精准施药方案研究及农技培训教学。借助该数据集可快速搭建害虫检测基线模型扩展计数与密度分析等衍生任务为减少农药使用的可持续农业治理提供数据支撑。1. 黄瓜害虫目标检测数据集三千张真实农田图比公开通用集强在哪温室里翻起一片黄瓜叶背面密密一层蚜虫老把式扫一眼就能叫出名字但换成部署在大棚里的摄像头这事就没那么简单。黄瓜害虫目标检测数据集就是给这类农业视觉任务准备的三千多张真实农田场景拍摄的黄瓜植株图像覆盖蚜虫、果蝇、南瓜甲虫、潜叶虫、粉虱五类高危害害虫标注做成标准 YOLO 格式解压 zip 后就能被 YOLOv5/v8 这一套检测框架直接消费。它适合两类人一类是正在搭智慧农业监测系统的工程师另一类是拿农业数据练目标检测手感的初学者。接下来我按结构、目录、训练、避坑、部署这条线把它拆开讲。2. 数据集解剖五大类害虫的标注结构与 YOLO 文件格式的三层拆解2.1 五类害虫长什么样从蚜虫群聚到潜叶虫虫道拿到数据集先别急着解压先看类别定义。摘要里写得很清楚五类分别是 Aphids蚜虫、Fruitfly果蝇、Pumpkin-Beetle南瓜甲虫、Serpentine-leafminer潜叶虫、Whitefly粉虱。这五类在图像里的特征差异非常大蚜虫和粉虱都是小目标经常十几只或者几十只聚在叶片背面单只可能只有十几个像素果蝇体型中等复眼偏红褐色南瓜甲虫个头最大鞘翅上有明显光泽属于天然的大目标潜叶虫最特殊成体不明显但叶片上会有白色蜿蜒的取食虫道模型真正要学的是那种纹理异常区域。这五类放到同一个检测任务里天然构成了一个难易梯度大目标好检测但样本可能偏少小目标密集但容易漏检类别不均衡和尺度差异同时出现。如果你之前只在 COCO 或者行人数据集上练过手这个分布会给你完全不同的训练体验——小目标问题的权重被放大很多这正是农业数据集和通用数据集最明显的分水岭。整理成一张表会看得更清楚类别体型分布特点识别难点蚜虫 Aphids极小叶片背面群聚目标太小、密集遮挡果蝇 Fruitfly中等单只或几只复眼颜色易混淆南瓜甲虫 Pumpkin-Beetle大单只鞘翅反光过曝潜叶虫 Serpentine-leafminer中虫道细长形状像叶脉裂纹粉虱 Whitefly小群聚翻飞白色易被背景吞掉2.2 YOLO 标注的反推法每个 txt 都在描述一个归一化矩形这个包的标注是 YOLO 格式每张 jpg 旁边躺着一个同名 txt文件名只是扩展名不同。文本里每一行表示一个目标框五个数字依次是类别 ID、框中心 x、框中心 y、框宽 w、框高 h后四个值全部除以了原图宽高归一化到 0~1 之间。比如打开某个 txt可能长这样0 0.5231 0.4412 0.1230 0.0850 3 0.1127 0.8893 0.0350 0.0180第一行含义是类别 ID 为 0具体是哪个类以包里的 classes.txt 为准矩形中心位于图片宽度的 52.31% 处、高度的 44.12% 处框宽占整图 12.3%框高占 8.5%。第二行是一个尺寸很小的框多半就是粉虱或蚜虫这类小目标。字段含义拆开看更直观字段含义示例值取值区间第 1 列类别 ID0小于 nc第 2 列框中心 x0.52310~1第 3 列框中心 y0.44120~1第 4 列框宽 w0.12300~1第 5 列框高 h0.08500~1看文件名也能读出背景信息比如Copy-of-fruit-fly-2_jpg.rf.b140...jpg这种带_jpg.rf.标记的命名是 Roboflow 平台导出的典型风格意味着标注经历过统一的导出流程你在网上看到的很多同类目标检测数据集都是这套结构。数据和标签是一一对应的删错一张 jpg 会导致整个训练集配对失败所以验货的时候要成对检查而不是只数图片。2.3 解压后的验货流程分类、计数与 classes.txt 对齐拿到 zip 第一件事是解压然后按顺序做四步验货别直接拖进训练脚本。解压命令在 Linux 下就是一行unzip 黄瓜害虫目标检测数据集4.zip -d cucumber_pests cd cucumber_pests find . -maxdepth 2 -type d | sort文件名带中文或特殊字符时偶尔会报乱码加一个-O utf8或-O gbk按压缩包实际编码指定一下就行。find的作用是先把目录骨架摸清楚到底有没有 train/valid/test 划分还是所有图片平铺在一个目录里。这两种情况后面处理方式完全不同如果作者已经按 Roboflow 默认比例分好了通常训练集占七成、验证集和测试集各占一成半如果平铺就得自己按 8/1/1 重新切。接着统计图片和标签数量find . -name *.jpg | wc -l find . -name *.txt | wc -l cat classes.txt 2/dev/null || cat data.yaml 2/dev/null图片数和 txt 数必须一致差一个都别开工。classes.txt里的顺序就是训练时的类别 ID 顺序这个顺序一旦定了后面 data.yaml 里 names 列表就得跟它完全一致。很多翻车案例就发生在这作者给的顺序和训练者自己写的顺序错了一位训练全程不报错但推理时所有类别整体错位。验货完成后我习惯把五类害虫整理成表格贴在项目 README 里训练时反复对照省得后面睁眼瞎。提示如果解压后只看到一摞 jpg 而没有 txt先把整个压缩包翻一遍确认是不是有单独的 labels 分卷有些包把标注文件单独打包属于常见的资源分发习惯。3. 环境配置与目录重构把 Roboflow 导出包改成 YOLOv8 直接能训的 layout3.1 运行基线Python 版本、ultralytics 与 CUDA 的匹配训练 YOLO 系列环境这块其实没太多玄学只要版本匹配一次就能装干净。我常用的组合是 Python 3.10、PyTorch 2.x CUDA 11.8ultralytics 用 8.x 的稳定版。新建一个干净的 conda 环境最稳避免跟其他项目抢依赖conda create -n yolo python3.10 -y conda activate yolo pip install ultralytics安装完成后用一行命令验证是否真的能用 GPUpython -c import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))输出True加显卡型号才算通。如果输出False先检查 PyTorch 装的是不是 CUDA 版本pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118重装一次能解决大部分问题。CPU 也不是不能训三千张图用 CPU 一个 epoch 可能要跑十几分钟预算允许还是建议租一张显卡训练体验完全不同。遇到过有人装完 ultralytics 直接跑报torch.cuda.is_available() False翻半天日志发现是装了 CPU 版 torch属于这个环节最常见的翻车点。3.2 目录重组软链接优先于复制解压之后如果包内已经带有 train/valid/test 的标准分目录Roboflow 导出的常见形态那不需要重排图片直接建软链接把目录映射到统一工程目录下就行mkdir -p dataset ln -s $(pwd)/cucumber_pests/train/images dataset/train_images ln -s $(pwd)/cucumber_pests/train/labels dataset/train_labels ln -s $(pwd)/cucumber_pests/valid/images dataset/val_images ln -s $(pwd)/cucumber_pests/valid/labels dataset/val_labels软链接不复制文件省磁盘空间也避免复制中断产生半截文件。如果实际是平铺目录再用 Python 按 train/val/test 8/1/1 的比例做一次划分。划分时要防止同场景连拍图全挤进训练集——用文件名哈希取模比用 random 更稳因为结果可复现import hashlib, shutil from pathlib import Path src_img Path(cucumber_pests/jpg) src_txt Path(cucumber_pests/labels) out Path(dataset_split) for jpg in src_img.glob(*.jpg): txt src_txt / (jpg.stem .txt) if not txt.exists(): print(缺少标签:, jpg.name) continue bucket int(hashlib.md5(jpg.name.encode()).hexdigest(), 16) % 10 part train if bucket 8 else (val if bucket 9 else test) (out / part / images).mkdir(parentsTrue, exist_okTrue) (out / part / labels).mkdir(parentsTrue, exist_okTrue) shutil.copy2(jpg, out / part / images) shutil.copy2(txt, out / part / labels)这里的 8/1/1 比例是三千张这个体量下的保守选择图片越多验证集占比可以适当调低到 0.05。用文件名哈希做划分同一次运行结果固定哪个文件进了验证集是确定的不会因为重跑一次换一批验证图这对后面多轮对比实验特别重要。跑完检查三个目录里 jpg 和 txt 数量是否一致我每次都查从来没省过这一步。3.3 data.yaml 与类别顺序索引错一位全部白练目录就位后在工程根目录写一个 data.yaml。这个文件负责告诉 YOLO 去哪里找图、有几类、类别叫什么。一个最简配置path: ./dataset train: train/images val: val/images nc: 5 names: 0: Aphids 1: Fruitfly 2: Pumpkin-Beetle 3: Serpentine-leafminer 4: Whiteflytrain和val路径按第 3.2 节生成的目录写测试集目录可以不写推理时单独指定。names的顺序必须等于标签 txt 里第一列的数字也就是说 classes.txt 里排第几这里就得排第几。如果原包没给 classes.txt可以用这段脚本从所有 txt 里反推类别编号范围awk {print $1} labels/*.txt | sort -n | uniq -c输出第一列是类别 ID第二列是数量同时能看出类别总数和各类别样本量。如果发现 ID 最大是 4那 nc 就是 5如果最大是 6说明标签里混了没删干净的数据先清理再训。这一步花两分钟却能在训练前发现标注文件是否干净值得每次都做。4. 训练参数与调参路线从 v8s 到 v8m 的迁移选择4.1 第一轮训练命令epochs、batch、imgsz 怎么定环境就绪、数据就绪第一轮训练别急着炫技用保守参数拿一个 baseline。我通常用 v8s 起步预训练权重从 COCO 上继承特征比从零训练收敛快得多也稳得多yolo detect train \ modelyolov8s.pt \ datadata.yaml \ epochs100 \ batch16 \ imgsz640 \ patience20 \ cacheTrue \ device0几个关键参数按下面的表理解就够了。epochs100 是这个体量数据的中等水平配合 patience20 做早停loss 连续 20 轮不降就自动停省时间batch16 是 24GB 显存下的安全值显存小就降到 8imgsz640 是 YOLOv8 的默认输入尺寸第一轮先用它跑通后面针对小目标再往上提cacheTrue 把图片预加载进内存三千张图大概多占 2~3GB 内存换来每个 epoch 磁盘读取时间大幅缩短。参数起始值影响调整方向epochs100训练总轮数数据小可增到 150配合早停batch16每轮参与梯度更新的样本数显存不足降到 4/8imgsz640模型输入分辨率蚜虫漏检时提到 1280patience20早停耐心值追求精度放宽到 30device0指定 GPU 编号多卡写 0,1,2训练过程中终端会实时刷新 loss、mAP 这些指标第一轮我基本不看等跑完再统一分析。训练结束后runs/detect/train/目录下会出现weights/best.pt和weights/last.pt后面推理只用 best.pt也就是验证集表现最好的那一份权重。4.2 数据增强给三千张图加多少“魔法”合适官方默认增强参数是通用调参的结果放在真实农田数据上往往偏强或偏弱。我会在第二轮训练时手动指定增强参数重点控制颜色扰动。黄瓜叶子的绿色、虫害后的黄化这些特征在模型判断时权重很高颜色增强太猛叶子颜色被来回拉扯模型反而学不到“叶片状态”这个关键线索。yolo detect train \ modelyolov8s.pt \ datadata.yaml \ epochs120 \ batch12 imgsz640 \ hsv_h0.015 hsv_s0.7 hsv_v0.4 \ fliplr0.5 flipud0.1 \ scale0.5 \ mosaic1.0参数含义hsv_h 是色调扰动0.015 表示很小幅度的色相偏移防止叶片颜色被改成不自然的蓝绿hsv_s 是饱和度 0.7中等强度模拟不同光照下的颜色浓淡hsv_v 是亮度 0.4。fliplr 水平翻转 0.5 是默认值flipud 垂直翻转只给 0.1因为田间黄瓜藤蔓有固定的生长朝向垂直翻转太多会让模型学到错误的形态规律。scale0.5 允许缩放拉伸到原图的 50%~150%这一步对蚜虫这种密集小目标帮助很大等于让模型在不同尺度上多次见到同类目标。关于 mosaic前中期用 1.0 没有问题但最后一二十轮建议关掉或调低。mosaic 拼出的四宫格图片和真实场景差异很大模型后期需要回归真实分布最后一轮mosaic0.0是常见的收尾操作能让最终权重在小目标上的表现更稳定。4.3 训练完成后的三张图从 baseline 到 v8m 的迁移时机训练完别只盯着 mAP 一个数字我会惯例打开三张图。第一张是results.png看 train_loss 和 val_loss 两条曲线的尾部走势如果 val_loss 最后二十轮还在持续下降说明 epoch 不够把 best.pt 换回 last.pt 继续训如果 val_loss 已经走平甚至上翘说明过了拟合峰点best.pt 就是最终答案。第二张是混淆矩阵confusion_matrix.png重点看两类相邻害虫有没有互相串。比如果蝇和南瓜甲虫如果频繁误判说明样本里两者的拍摄角度太接近追加数据时要专门补侧视角图像。第三张是 PR 曲线看 recall 的尾部表现。农业检测里漏检比误检更致命漏掉一片蚜虫意味着虫害可能已经爆发所以我对 recall 的关注度高于 precision宁可多框几个噪声也不能放过真实虫害。v8s baseline 跑完后如果 mAP50 上了 0.8 但 mAP50-95 迟迟不动或者小目标类别的 AP 明显偏低我会换 v8m 再训一轮。v8m 参数量接近 v8s 的两倍batch 要相应减半其他参数不动。对比两轮结果如果 v8m 在 mAP50-95 上的涨幅超过两个点就保留大模型如果涨幅很小说明瓶颈不在模型容量而在数据分布v8s 反而更适合部署到田间的低算力设备上。这个对比决策比盲目换大模型靠谱得多。5. 避坑手册蚜虫漏检、类别错位与显存爆炸的六条实测记录5.1 现象mAP50 很高田间却一个蚜虫都认不出来训练跑完验证集 mAP50 有 0.85高高兴兴把 best.pt 丢进大棚实时流结果摄像头对着满是蚜虫的叶子输出空列表。原因很典型蚜虫体积太小640 分辨率下很多个体只有 8×8 像素验证集里能被识别是因为标注框恰好存在而新场景背景一复杂特征就被淹没了。解决方法是二选一把 imgsz 从 640 提到 1280 重新训练同时 batch 降到 8或者推理阶段对原图做切片推理把一张大图切成若干个 512×512 的 patch 独立检测再合并结果。后者不用重训见效更快适合先验证问题到底是不是尺度引起的。5.2 现象训练过程稳定但五类里南瓜甲虫 AP 明显塌方南瓜甲虫样本量如果远小于蚜虫模型会把学习资源全部倾斜到高频类别。看混淆矩阵能直观看到甲虫大量被预测成背景或者果蝇原因是类别不均衡。三千张图听着不少但均摊到五类低频类可能只有两三百个实例。我一般先按原样训一轮拿到 baseline再针对低频类单独处理把南瓜甲虫出现过的图全部挑出来用缩放和旋转做数据增强扩到一千张并回训练集重训。手动扩样比调 class weights 直观出问题好排查也不会引入额外的超参数。5.3 现象val_loss 低于 train_lossmAP 却低得离谱这不是过拟合而是数据划分不当。如果原包的 train/valid 划分是随机抽的而同场景连拍图既进了训练集又进了验证集验证集就会“假简单”——val_loss 很低但模型根本没泛化到新场景。解决方式是把划分逻辑从随机改为按拍摄批次分组也就是第 3.2 节里用文件名哈希划分的原因。拿到新数据集第一步永远先确认验证集的独立性这一步花十分钟能挡住后面最贵的返工。5.4 现象标签 txt 出现 12.34 这种大于 1 的坐标值少数 txt 里 cx、cy 或宽高没有归一化直接写了像素值。用 YOLO 训练时不报错但框位置完全错乱模型学的全是噪声。跑一段检查脚本把所有标签扫一遍问题马上现形import numpy as np from pathlib import Path bad [] for txt in Path(labels).glob(*.txt): with open(txt) as f: lines [l for l in f if l.strip()] arr np.array([list(map(float, l.split())) for l in lines]) if arr.shape[1] ! 5: bad.append((txt.name, 列数异常)) continue coords arr[:, 1:] if coords.min() 0 or coords.max() 1: bad.append((txt.name, 坐标越界)) print(异常标签数量:, len(bad)) for b in bad[:10]: print(b)脚本逻辑很简单每行必须有 5 列后四列必须在 0~1 区间内任何一个越界就记录。查出来的文件数量少就手工修数量多就按原图宽高做一次除法归一化然后覆盖写入。最坏的情况是全部标签都没归一化但训练时不报错等发现时已经烧掉几十个小时。5.5 现象改完 data.yaml 的 names 顺序模型把所有目标都认成果蝇这类问题几乎都是手滑改了类别顺序导致的。标签 txt 里的第一列是类别 ID训练时它对应的就是 data.yaml 里 names 的下标不是名字。你把 Fruitfly 从第 1 挪到第 0所有标签整体错位模型学到的映射和你以为的映射差了一位。解决建议标签文件这辈子不要改名改序新增类别往列表末尾追加旧索引永远保持固定。每次训练前从验证集抽一张图把预测框的类别名和肉眼对照一下这是排查这类问题最高效的方式。5.6 现象训练到一半 CUDA out of memoryimgsz1280配合 v8m 模型显存消耗会成倍上涨。解决路线是先降到 batch4 跑通再加回 8 或 16或者直接开ampTrue混合精度显存占用能省三成左右实测精度损失很小农业场景完全能接受。如果这两招都用了还爆检查后台是不是同时跑着其他占用显存的服务nvidia-smi看一眼就清楚。6. 推理验证与部署闭环从 best.pt 到虫情计数6.1 先跑一轮 val把 mAP50-95 读准训练完别急着上摄像头先跑一遍验证集yolo detect val modelruns/detect/train/weights/best.pt datadata.yaml imgsz640输出里 mAP50 反映框位置的粗粒度准确性mAP50-95 更严格考察多个交并比阈值下的综合表现。农业场景我一般盯着 mAP50 和 recall 看这两个指标更贴近“到底有没有漏害虫”的诉求。验证集如果本身划分合理这里的数字基本能代表田间表现的下限。6.2 虫情计数按类别统计框数量验证通过后一个很实用的小闭环是虫情计数。用 best.pt 跑一遍测试集或摄像头帧把每个框的类别聚合起来from collections import Counter from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) names model.names total Counter() for res in model.predict(sourcetest/images, conf0.25, imgsz1280): cls res.boxes.cls.cpu().numpy() total.update(names[int(i)] for i in cls) print(各类害虫检出数量:, dict(total))conf0.25是起始置信度阈值粉虱这类小目标置信度普遍偏低实际部署时多调低到 0.15 换 recall。imgsz1280是为了让小目标在推理阶段也能被看清。这个脚本输出的就是最简单的虫情密度表接进物联网平台以后每帧统计一次连续几帧都超过设定阈值就能触发预警。第一次把模型丢进大棚翻车之后我养成了个习惯不管哪个项目拿到数据包先强制走一遍结构核验——解压、数文件、比对 classes.txt 顺序、跑一遍标签合法性检查四步全过了才轮到训练。这套流程多花二十分钟挡住的是后面几十个小时的返工。希望帮到你。本文还有配套的精品资源点击获取
返回列表