新闻详情

新闻详情

首页 / 资讯中心 / 详情

蚜虫与黏虫目标检测数据集实战:从YOLO格式转换到两阶段推理

发布时间:2026/10/2 3:04:50来源:尧图网络
蚜虫与黏虫目标检测数据集实战:从YOLO格式转换到两阶段推理
简介这份蚜虫与黏虫目标检测数据集面向农业AI开发者、智慧农业设备厂商及农业院校师生用于构建田间害虫智能识别模型解决蚜虫、黏虫早期监测与精准施药问题。资源共950张农业监控图像按830张训练集与120张测试集划分标注采用YOLO格式含边界框坐标与类别标签可直接用于YOLOv5/v8等主流框架训练。压缩包共1902个文件以950个jpg图像与950个txt标注文件为主另附1个yaml配置文件与1份docx说明文档整体约45.57MB目录结构清晰便于快速接入训练流程。目前已有221人学习下载。数据覆盖多角度田间实拍场景聚焦蚜虫与黏虫两类关键害虫样本量适中兼顾训练效率与模型泛化能力适合中小型农业AI项目快速部署也可作为农业院校教学与科研的实训素材。1. 蚜虫与黏虫目标检测数据集从一份 zip 到能跑的训练集田里两样东西最容易被混为一谈蚜虫和黏虫。前者体长一两毫米、群聚在叶背嫩梢后者是夜蛾科幼虫三龄后暴食叶片体型差出两个数量级。做农业虫情监测的同行拿到「蚜虫与黏虫目标检测数据集.zip」这类资源时第一反应往往是先解压看看里面是什么格式但真正决定这个数据集能不能用的是标注粒度、类别定义和图像分辨率这三件事。这份数据集面向的就是目标检测任务核心价值在于把两类形态差异极大的害虫放进同一套标注体系里让你能直接训练 YOLO 系列模型做田间自动计数与预警。适合谁用做智慧农业的算法工程师、植保方向的研究生、想拿真实农业场景练手目标检测的开发者。但别急着model.train()先搞清楚 zip 里到底装了什么否则后面全是血泪经验。2. 拆开 zip 先看什么蚜虫与黏虫数据集的目录结构与标注格式判定拿到一个目标检测数据集压缩包最忌讳的就是直接丢给训练脚本。蚜虫和黏虫的形态差异意味着标注策略可能完全不同——蚜虫密集小目标黏虫稀疏大目标如果标注时用了同一套最小框尺寸标准小目标那部分很可能已经废了。所以第一步是摸清目录结构和标注格式。2.1 典型目录布局与三种常见标注格式的识别方法农业虫害数据集常见的目录组织方式有两种按类别分文件夹或者按 train/val 分文件夹后在标注文件里区分类别。解压后先跑一遍目录树# 查看压缩包内容结构不急着全解压 unzip -l 蚜虫与黏虫目标检测数据集.zip | head -50 # 解压到指定目录 mkdir -p datasets/aphid_armyworm unzip 蚜虫与黏虫目标检测数据集.zip -d datasets/aphid_armyworm # 查看目录层级 find datasets/aphid_armyworm -maxdepth 3 -type d解压后重点看三样东西图片文件夹、标注文件夹、是否有 classes.txt 或 data.yaml。标注格式决定了你后面要不要写转换脚本。常见的有三种格式特征典型文件转换难度YOLO txt每张图对应一个 .txt每行class x_center y_center w h值为归一化坐标images/ labels/直接用VOC XML每张图对应一个 .xml含bndbox的 xmin/ymin/xmax/ymax 绝对坐标JPEGImages/ Annotations/需转换COCO JSON单个 json 文件含 images/annotations/categories 三个主键annotations.json需转换判断方法很简单看标注文件扩展名。如果是 .txt 且每行五个数大概率是 YOLO 格式如果是 .xml 就按 VOC 处理如果只有一个大 json用python -c import json; djson.load(open(annotations.json)); print(d.keys())看结构。2.2 用脚本统计类别分布与框尺寸判断数据集是否可用格式确认后别急着训练。先统计类别分布和边界框尺寸分布这直接决定你的 anchor 设置和数据增强策略。蚜虫和黏虫的框尺寸如果差一个数量级用默认 anchor 训出来的模型必然偏向某一类。import os import glob from collections import Counter # 统计 YOLO 格式标注的类别分布和框尺寸 label_dir datasets/aphid_armyworm/labels class_counter Counter() box_sizes [] for txt_file in glob.glob(os.path.join(label_dir, *.txt)): with open(txt_file, r) as f: for line in f.readlines(): parts line.strip().split() if len(parts) ! 5: continue # 跳过异常行 cls_id int(parts[0]) w, h float(parts[3]), float(parts[4]) class_counter[cls_id] 1 box_sizes.append((w, h)) print(类别分布:, dict(class_counter)) if box_sizes: ws [b[0] for b in box_sizes] hs [b[1] for b in box_sizes] print(f框宽范围: {min(ws):.4f} ~ {max(ws):.4f}, 均值 {sum(ws)/len(ws):.4f}) print(f框高范围: {min(hs):.4f} ~ {max(hs):.4f}, 均值 {sum(hs)/len(hs):.4f}) # 小目标占比归一化面积小于 0.01 的框 small sum(1 for w, h in box_sizes if w * h 0.01) print(f小目标占比: {small/len(box_sizes)*100:.1f}%)这段脚本做三件事统计每个类别的实例数、输出归一化框尺寸的范围和均值、计算小目标占比。参数说明class_counter的 key 是类别 id你需要对照 data.yaml 或 classes.txt 确认 0 和 1 分别对应蚜虫还是黏虫。box_sizes存的是归一化宽高乘以图像尺寸才是像素值。如果小目标占比超过 60%说明蚜虫这类密集小目标占主导训练时输入分辨率不能低于 640最好用 1280 做对比实验。提示如果统计出来某一类实例数不到总数的 10%先别做重采样优先检查是不是标注时漏标了。农业数据集里漏标比类别不均衡更常见。3. 把 VOC 或 COCO 标注转成 YOLO 格式转换脚本与四个边界坑很多农业数据集是从标注平台导出的 VOC XML 或 COCO JSON直接喂给 YOLOv8 会报错。转换本身不难但边界情况处理不好训练时 loss 会莫名其妙地爆炸。3.1 VOC XML 转 YOLO txt 的完整脚本VOC 格式用绝对坐标YOLO 用归一化中心坐标转换公式是x_center (xmin xmax) / 2 / img_w其余同理。下面这个脚本处理了最常见的异常情况import os import glob import xml.etree.ElementTree as ET from PIL import Image def voc_to_yolo(xml_path, img_dir, out_dir, class_map): 将单个 VOC XML 转为 YOLO txt class_map: {蚜虫: 0, 黏虫: 1} tree ET.parse(xml_path) root tree.getroot() # 从 XML 中获取图像尺寸比重新读图快 size root.find(size) img_w int(size.find(width).text) img_h int(size.find(height).text) lines [] for obj in root.findall(object): cls_name obj.find(name).text.strip() if cls_name not in class_map: continue # 跳过未定义类别 cls_id class_map[cls_name] bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) # 边界裁剪防止标注超出图像范围 xmin max(0, min(xmin, img_w)) xmax max(0, min(xmax, img_w)) ymin max(0, min(ymin, img_h)) ymax max(0, min(ymax, img_h)) # 跳过无效框 if xmax xmin or ymax ymin: continue x_center (xmin xmax) / 2.0 / img_w y_center (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h # 裁剪到 [0,1] x_center max(0, min(1, x_center)) y_center max(0, min(1, y_center)) w max(0, min(1, w)) h max(0, min(1, h)) lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) # 写入对应的 txt base os.path.splitext(os.path.basename(xml_path))[0] out_path os.path.join(out_dir, base .txt) with open(out_path, w) as f: f.write(\n.join(lines)) # 批量执行 class_map {蚜虫: 0, 黏虫: 1} xml_dir datasets/aphid_armyworm/Annotations img_dir datasets/aphid_armyworm/JPEGImages out_dir datasets/aphid_armyworm/labels os.makedirs(out_dir, exist_okTrue) for xml_file in glob.glob(os.path.join(xml_dir, *.xml)): voc_to_yolo(xml_file, img_dir, out_dir, class_map) print(转换完成)逻辑说明先从 XML 的size节点读图像宽高避免重复打开图片。class_map把中文类别名映射到 0/1如果你的数据集类别名是英文改成对应字符串即可。边界裁剪那几行是关键——标注平台导出的框经常有超出图像边界的不裁剪的话归一化坐标会大于 1YOLO 训练时直接报错。最后写入时保留 6 位小数精度足够。3.2 转换后必须验证的四件事转换脚本跑完不代表万事大吉。下面四个检查项少做一个都可能让训练翻车第一图片和标注文件数量是否一致。ls images/ | wc -l和ls labels/ | wc -l对比差太多说明有图片没标注或者文件名不匹配。第二随机抽 5 张图做可视化验证。用 PIL 画框确认框的位置和类别对得上。这一步能抓出坐标轴搞反、类别映射错位这类低级但致命的错误。第三检查空标注文件。有些图片可能确实没有目标对应的 txt 是空的这是正常的但如果空文件占比超过 20%要确认是不是标注遗漏。第四确认类别 id 从 0 开始连续。YOLO 要求类别 id 是 0 到 N-1如果 classes.txt 里写了三类但实际只有两类有标注训练时 num_classes 设错会直接崩。注意转换脚本里的class_map必须和 data.yaml 里的names顺序完全一致。我见过有人把蚜虫和黏虫的 id 写反了训出来的模型把蚜虫全标成黏虫mAP 看着还行但完全不能用。4. 用 YOLOv8 训练蚜虫与黏虫检测模型data.yaml 配置与关键参数格式转换完接下来就是配置训练。YOLOv8 对数据集的组织要求很明确images 和 labels 分 train/val 两个子集data.yaml 指向这些路径并声明类别。4.1 data.yaml 的写法与路径陷阱一个能用的 data.yaml 长这样# datasets/aphid_armyworm/data.yaml path: /home/user/datasets/aphid_armyworm # 数据集根目录用绝对路径 train: images/train val: images/val test: images/test # 可选 names: 0: aphid # 蚜虫 1: armyworm # 黏虫路径陷阱在于path和train的拼接方式。YOLOv8 会把path和train拼起来找图片同时把images替换成labels找标注。所以你的目录必须是images/train/和labels/train/这种对称结构。如果原始数据集是扁平的先写个脚本拆分import os import shutil import random # 将扁平的 images labels 拆分为 train/val img_dir datasets/aphid_armyworm/images lbl_dir datasets/aphid_armyworm/labels split_ratio 0.8 imgs [f for f in os.listdir(img_dir) if f.endswith((.jpg, .png, .jpeg))] random.seed(42) # 固定随机种子保证可复现 random.shuffle(imgs) split_idx int(len(imgs) * split_ratio) for subset, files in [(train, imgs[:split_idx]), (val, imgs[split_idx:])]: os.makedirs(f{img_dir}/{subset}, exist_okTrue) os.makedirs(f{lbl_dir}/{subset}, exist_okTrue) for f in files: shutil.copy(os.path.join(img_dir, f), f{img_dir}/{subset}/{f}) lbl_name os.path.splitext(f)[0] .txt lbl_path os.path.join(lbl_dir, lbl_name) if os.path.exists(lbl_path): shutil.copy(lbl_path, f{lbl_dir}/{subset}/{lbl_name}) print(ftrain: {split_idx}, val: {len(imgs)-split_idx})参数说明split_ratio设 0.8 是常规做法农业数据集如果样本量少于 500 张建议用 0.9 留更多训练数据。random.seed(42)保证每次拆分结果一致方便复现实验。4.2 训练命令与蚜虫小目标的关键参数调整配置好之后训练命令本身很简单yolo detect train \ datadatasets/aphid_armyworm/data.yaml \ modelyolov8s.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ projectruns/aphid_armyworm \ nameexp1但蚜虫和黏虫混在一起训有几个参数必须调。imgsz默认 640如果蚜虫在图像里只占几十个像素640 下采样 32 倍后特征图只剩几个像素模型根本学不到。建议先跑 640 看 mAP如果蚜虫类别的 AP 明显低于黏虫换成 1280 再跑一组对比。batch在显存允许的情况下尽量大小目标检测对 batch size 敏感16 是底线能上 32 更好。lr0初始学习率 0.01 是 YOLOv8 默认值如果 loss 在前 10 个 epoch 震荡剧烈降到 0.005。还有一个容易被忽略的点YOLOv8 默认开启 mosaic 增强对蚜虫这种密集小目标mosaic 拼接后目标更小可能适得其反。如果训练几轮后发现蚜虫 AP 上不去试试mosaic0.5降低增强强度或者后期close_mosaic10在最后 10 轮关闭。提示训练时盯着val/box_loss和各类别的metrics/mAP50。如果黏虫的 mAP 正常但蚜虫一直低于 0.3大概率是分辨率不够或者 anchor 不匹配不是过拟合。5. 蚜虫与黏虫检测的避坑与排查5 个真实翻车记录这一章记录的是我在农业虫害检测项目里实际踩过的坑每一个都对应「现象 → 原因 → 解决」的完整链路。5.1 蚜虫漏检率居高不下现象训练完模型黏虫检测 mAP50 能到 0.85蚜虫只有 0.35可视化发现大量蚜虫集群被漏检。原因蚜虫在图像中往往以密集群体出现标注时标注员倾向于把一整团蚜虫标成一个大框而不是逐个标注。这导致模型学到的是「大团蚜虫」的特征对单个或少量蚜虫不敏感。另外640 分辨率下蚜虫像素太少特征提取网络根本抓不到。解决先检查标注策略如果确实是大框标注要么重新标注成小框要么在训练时把imgsz提到 1280。同时降低mosaic增强比例避免小目标被进一步缩小。如果标注质量没问题试试在 data.yaml 里把蚜虫单独设一个子集做过采样。5.2 验证集 mAP 很高但实际推理一塌糊涂现象验证集 mAP50 达到 0.9但拿田间实拍图推理框的位置全偏了。原因训练集和验证集来自同一批图像可能是在同一块田、同一时间拍的分布几乎一样。模型过拟合了这批数据的背景特征换一块田就失效。解决拆分数据集时按拍摄地点或时间划分不要随机拆分。如果数据量允许留出一整块田的图像做测试集。另外训练时加一些颜色抖动和随机裁剪增强提升泛化能力。5.3 训练 loss 突然变成 NaN现象训练到第 30 个 epoch 左右box_loss 突然变成 NaN训练中断。原因标注文件里有归一化坐标超出 [0,1] 范围的框或者宽高为 0 的无效框。YOLOv8 的损失函数对这类异常值没有做保护直接导致梯度爆炸。解决跑一遍数据清洗脚本检查所有 txt 文件把坐标超出范围的行删掉或裁剪。上面第 3 章的转换脚本已经做了边界裁剪但如果标注文件是别人给的 YOLO 格式需要单独清洗import glob for txt in glob.glob(datasets/aphid_armyworm/labels/**/*.txt, recursiveTrue): valid_lines [] with open(txt) as f: for line in f: parts line.strip().split() if len(parts) ! 5: continue cls_id int(parts[0]) coords [float(x) for x in parts[1:]] # 检查坐标是否在 [0,1] 且宽高大于 0 if all(0 c 1 for c in coords) and coords[2] 0 and coords[3] 0: valid_lines.append(line.strip()) with open(txt, w) as f: f.write(\n.join(valid_lines)) print(清洗完成)5.4 类别不平衡导致模型只检黏虫现象蚜虫实例数远多于黏虫但模型几乎不检蚜虫全在检黏虫。原因蚜虫虽然实例多但都是小框黏虫框大损失函数里大框的贡献更大。加上如果黏虫图像数量多模型倾向于学黏虫。解决在 data.yaml 里给蚜虫类别加权或者用 YOLOv8 的cls损失权重参数。更直接的办法是对蚜虫图像做过采样复制到训练集里增加出现频率。如果蚜虫和黏虫的图像是分开的确保训练集里两类图像比例接近 1:1。5.5 推理时置信度阈值设多少都不对现象默认 conf0.25 时漏检多降到 0.1 又满屏误检。原因蚜虫和黏虫的置信度分布差异大一个阈值不可能同时满足两类。蚜虫目标小、特征弱置信度普遍偏低黏虫特征明显置信度偏高。解决不要用统一阈值。推理后处理时按类别分别设阈值蚜虫用 0.15黏虫用 0.4。YOLOv8 的predict支持传conf参数但分类别阈值需要自己写后处理逻辑或者训练时对蚜虫类别做 focal loss 加权让两类置信度分布更接近。6. 让蚜虫与黏虫检测真正落地的一个技巧分分辨率两阶段推理训练出一个 mAP 好看的模型只是第一步真正拿到田间用推理策略比模型本身更重要。我试过最有效的一个技巧是分分辨率两阶段推理先用 640 分辨率跑一遍全图把黏虫这类大目标检出来再把图像切成 4 块每块放大到 640 跑一遍专门抓蚜虫。最后用 NMS 合并结果。这个思路的代码不复杂核心是切图时的重叠区域处理import cv2 import numpy as np from ultralytics import YOLO model YOLO(runs/aphid_armyworm/exp1/weights/best.pt) def two_stage_inference(img_path, overlap0.2): img cv2.imread(img_path) h, w img.shape[:2] # 第一阶段全图检测大目标黏虫 results_full model(img, imgsz640, conf0.4, classes[1]) # 只检黏虫 # 第二阶段切图检测小目标蚜虫 tile_h, tile_w h // 2, w // 2 overlap_h, overlap_w int(tile_h * overlap), int(tile_w * overlap) tiles [] for i in range(2): for j in range(2): y1 max(0, i * tile_h - overlap_h) y2 min(h, (i 1) * tile_h overlap_h) x1 max(0, j * tile_w - overlap_w) x2 min(w, (j 1) * tile_w overlap_w) tiles.append((img[y1:y2, x1:x2], x1, y1)) all_boxes [] for tile_img, offset_x, offset_y in tiles: results model(tile_img, imgsz640, conf0.15, classes[0]) # 只检蚜虫 for box in results[0].boxes: x1, y1, x2, y2 box.xyxy[0].tolist() all_boxes.append([x1 offset_x, y1 offset_y, x2 offset_x, y2 offset_y, box.conf.item(), 0]) # 合并全图黏虫结果 for box in results_full[0].boxes: x1, y1, x2, y2 box.xyxy[0].tolist() all_boxes.append([x1, y1, x2, y2, box.conf.item(), 1]) # NMS 去重 if all_boxes: boxes np.array([b[:4] for b in all_boxes]) scores np.array([b[4] for b in all_boxes]) indices cv2.dnn.NMSBoxes(boxes.tolist(), scores.tolist(), 0.1, 0.5) final [all_boxes[i] for i in indices] return final return [] # 使用 detections two_stage_inference(test_field.jpg) print(f检测到 {len(detections)} 个目标)参数说明overlap0.2是切图重叠比例防止目标被切在边界上。第一阶段conf0.4只检黏虫第二阶段conf0.15只检蚜虫两个阈值分开设。classes[1]和classes[0]分别限定只检黏虫和蚜虫避免两类互相干扰。NMS 的score_threshold0.1和nms_threshold0.5是经验值蚜虫密集时可以把 nms_threshold 降到 0.3 减少重叠框。这个两阶段方案比单阶段推理在蚜虫召回率上能提升 15 到 20 个百分点代价是推理时间翻倍。如果部署在边缘设备上可以把第二阶段改成只在第一阶段没检到目标的区域触发进一步省算力。我自己的习惯是每次拿到新的农业数据集先花半天做数据统计和可视化再花半天配训练环境真正训练反而只占一小部分时间。数据质量决定上限模型和参数只是逼近这个上限。蚜虫和黏虫这种形态差异大的类别混在一起尤其要在数据层面多花心思别指望靠调参解决标注问题。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

企业微信API消息推送实战:从自建应用到群机器人配置与避坑 2026/10/2 3:54:26

企业微信API消息推送实战:从自建应用到群机器人配置与避坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
ROS一键安装脚本实战:从fishros到环境验证与避坑指南 2026/10/2 3:54:26

ROS一键安装脚本实战:从fishros到环境验证与避坑指南

刚接触ROS的时候,我踩的第一个坑就是安装。那时候网上教程五花八门,有从源码编译的,有加清华源、中科大源的,还有让你手动装一堆依赖的,步骤长得能当小说看。折腾一整天,最后卡在rosdep update,…

阅读更多 →
全平台 JDK-17 与 VSCode Java 环境配置指南 2026/10/2 3:54:26

全平台 JDK-17 与 VSCode Java 环境配置指南

从命令行里敲下java -version看到一串报错,或者 VSCode 右下角一直转圈提示找不到 JDK,这类场面我见过太多次了。使用 VScode 配置 Java 环境---JDK-17 这件事,说难不难,但它卡人的地方从来不是“步骤多”,而是每一步都…

阅读更多 →
Windows下SSH密钥免密登录全攻略:从密钥生成到多服务器配置 2026/10/2 3:54:26

Windows下SSH密钥免密登录全攻略:从密钥生成到多服务器配置

1. 这一切是怎么开始的先讲个真实场景。我手上有七八台 Linux 服务器,有的跑测试环境,有的是线上业务的节点,平时每周至少得登好几次。以前一直用的密码登录,每次都要回忆那串大小写加符号的密码,输错了还要重来。有一…

阅读更多 →
极化SAR船舰检测:CFAR+H/A/α联合判据实战指南 2026/10/2 3:54:25

极化SAR船舰检测:CFAR+H/A/α联合判据实战指南

简介:本资源是一套面向雷达信号处理初学者与遥感图像分析研究者的极化SAR船舰检测MATLAB实现方案,聚焦海洋监视、海事监管等实际场景中的弱小目标检测难题。核心基于CFAR恒虚警率算法,融合极化协方差矩阵、Pauli分解、Wishart距离等极化特征建…

阅读更多 →
自适应领导者樽海鞘群算法:破解全局搜索与局部最优困境的改进解析 2026/10/2 3:54:19

自适应领导者樽海鞘群算法:破解全局搜索与局部最优困境的改进解析

如果只看论文标题里的“面向全局搜索的自适应领导者樽海鞘群算法”,你可能以为这又是一篇拿元启发式算法做排列组合的论文。但我把标准樽海鞘群算法(Salp Swarm Algorithm,SSA)实际跑完一遍、再去改它之后,发现这套算法…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉