水稻褐飞虱目标检测数据集与YOLOv8训练实战
2026/9/24 18:36:30 网站建设 项目流程

简介:面向农业AI、目标检测算法研发与植保应用,菲律宾水稻褐飞虱成虫目标检测数据集提供真实农田环境下的害虫现场图像与YOLO格式标注。数据采集自菲律宾水稻种植区,覆盖水稻生长周期不同阶段,包含自然光照变化、叶片遮挡等复杂田间情况,比合成数据更贴近实际部署环境。资源共2000个文件,以1458个txt标注文件和540张jpg现场图片为核心,另附1个yaml配置与1个docx说明文档,压缩包约56.36MB,可直接导入YOLO系列框架训练与验证。数据集包含训练、验证、测试划分,便于复现实验和评估模型泛化能力;已有196人学习,适合智能虫害监测系统开发、精准施药决策支持,以及农业院校与研究机构的算法教学。全部标注经农业专家校验,聚焦褐飞虱成虫这一关键水稻害虫,能帮助开发者减少数据清洗与格式转换成本,加快害虫识别模型从实验到落地的进程。

1. 菲律宾水稻褐飞虱成虫目标检测数据集:先弄懂它是什么,再决定怎么训

做过水稻虫情测报的人都有印象:一块田要蹲在田埂上,拿白瓷盘垫在稻株下面拍打,然后蹲在地上数落在盘里的褐飞虱成虫,数完一丛要几分钟,一片田数完人已经眼花。灯诱的虫瓶更夸张,一晚上能收上千头成虫,第二天早上对着放大镜一头头分雌雄、分长翅短翅,测报站的老技术员最怕的就是虫峰期。

这个标题里的“菲律宾水稻褐飞虱成虫目标检测数据集”,本质上就是把这类“田间数虫”的场景整理成了带标注框的图片集:图片拍的是菲律宾稻区田间与灯诱条件下的水稻褐飞虱成虫,标注框框住的是成虫个体,交付形态是压缩包,解压之后是图片、标注文件和划分好的数据集目录。它解决的问题很直接:让训练出来的目标检测模型替代人工数虫,或者至少把数虫从“肉眼逐头数”降级成“模型预筛、人工复核”。适合正在做植保智能测报、虫情监测设备识别算法、或者打算用 yolo 系模型训练自己的害虫数据集的人。

2. 数据集的构成与采集逻辑:理解菲律宾稻区,才能看懂这批图像

2.1 图像来源与拍摄姿态:灯诱、拍盘、原位三类场景差异很大

拿到数据集先别急着解压训练,第一步是认清图像来源。菲律宾稻区地处热带,褐飞虱周年繁殖、世代重叠,田间成虫和若虫同时存在,虫口密度远高于我国大部分稻区。这个数据集里的图像,按拍摄方式大致可以分成三类:

灯诱成像:俯拍灯诱盘或接虫盒,常见黑色或深色背景,成虫密度极高,个体之间有重叠,触角、翅脉纹理还比较清楚。这类图背景单一,检测难度相对低,但虫体密集造成的重叠会让小目标容易漏检。

拍盘成像:白瓷盘拍打稻株后直接俯拍,浅色背景,褐飞虱成虫的淡褐色虫体和白色背景对比度尚可,但瓷盘反光、水渍、稻株碎屑会带来噪声。背景单一、目标清晰,训练初期用它打底最舒服。

原位成像:稻丛基部直接拍摄,背景是茎秆、叶片、泥土和光影,虫体被遮挡、姿态杂乱。这是真正贴近测报场景的图,也是难度最高的图。最终部署时如果希望模型能直接处理田间原位图像,数据里缺了这类图,模型很可能在实测时翻车。

常见做法是把三类图都保留,而不是只挑某一类,这样训练出来的模型才不会被单一背景绑架。

2.2 类别设计:为什么只标“成虫”,不把若虫一起标进去

标题里特意写了“成虫”,这不是随口一说,而是有标注逻辑的。褐飞虱若虫无翅、体长只有 1~3 毫米,和稻飞虱科其他种类的若虫(白背飞虱、灰飞虱的若虫)肉眼几乎分不清,标框时误标率极高。如果数据集里把若虫也标进去,类别就变成了“褐飞虱若虫”和“褐飞虱成虫”,但实际标注时连专业测报员都可能把白背飞虱若虫标进褐飞虱框里,标签噪声一大,模型训练出来就变成“见虫就框”而不是“框褐飞虱成虫”。

所以只标成虫是更稳的选择:成虫有翅、体型 4~5 毫米、有相对稳定的体色和翅型,标注一致性容易保证,模型学到的特征也更集中。拿到的标注通常只有一个类别名,常见写法是 bph_adult 或 brown_planthopper_adult。标注文件里类别索引从 0 开始,比如 YOLO 格式的一条记录长这样:

0 0.4532 0.6121 0.0315 0.0420

含义是:类别 0、归一化后的中心点 x、中心点 y、框宽 w、框高 h。后面四个值都是 0~1 之间的小数。

2.3 压缩包目录组织:解压后先确认格式再动手训练

这类目标检测数据集的压缩包,常见目录组织是下面这样的:

路径内容说明
images/train训练集图片JPG 或 PNG,尺寸不完全统一
images/val验证集图片用来调参和选模型
images/test测试集图片最终评估用,别拿它调参
annotations/标注文件可能是 VOC 的 xml、COCO 的 json 或 YOLO 的 txt
labels/trainYOLO 格式标签如果直接提供,说明已经转好格式
classes.txt类别清单一行一个类名,顺序就是类别索引
README 或 data.yaml数据说明与训练配置里面写了类别数、路径和拍摄说明

划分比例常见是 8:1:1,或者 9:0.5:0.5。拿到手第一步不是打开图片看,而是看 annotations 目录下的文件后缀:是 .xml,走 VOC 转换流程;是 .json,先看是 COCO 格式还是自定义格式;已经是 .txt,直接检查坐标是否归一化。下面第三部分就按这三种情况分别处理。

提示:如果压缩包里图片尺寸差异很大,有大到 4000x3000 的田间原图,也有几百像素的灯诱裁剪图,保留原始尺寸即可,训练时用 imgsz 统一输入大小,不要提前缩放图片,否则小目标会被严重削弱。

3. 标注格式检查与转换:把压缩包变成能喂给 yolo 训练目录

3.1 先判断拿到的是哪种标注格式

用文本方式打开任意一个标注文件,看开头内容就能判断:

head -n 20 annotations/xxxx.xml

如果看到<annotation>包裹的<object>结构和<bndbox>坐标,这是 VOC 格式;如果看到{"images": [...]}"annotations"字段,这是 COCO 格式;如果是纯数字行如0 0.45 0.61 0.03 0.04,这是 YOLO 格式。这一步判断决定了后续走哪条转换路径,跳过去直接套脚本是新手最容易翻车的地方。

3.2 VOC 转 YOLO:一张 xml 对应一个 txt

VOC 的标注是左上角和右下角坐标(xmin, ymin, xmax, ymax),YOLO 需要的是归一化后的中心点加宽高。转换脚本我一般这样写:

import xml.etree.ElementTree as ET import os from pathlib import Path # 和训练的 data.yaml 里 names 的顺序保持一致 CLASSES = ["bph_adult"] def voc_to_yolo(xml_path, out_dir): tree = ET.parse(xml_path) root = tree.getroot() img_w = int(root.find("size/width").text) img_h = int(root.find("size/height").text) lines = [] for obj in root.iter("object"): name = obj.find("name").text.strip() if name not in CLASSES: continue box = obj.find("bndbox") x1 = float(box.find("xmin").text) y1 = float(box.find("ymin").text) x2 = float(box.find("xmax").text) y2 = float(box.find("ymax").text) x_c = ((x1 + x2) / 2) / img_w y_c = ((y1 + y2) / 2) / img_h w = (x2 - x1) / img_w h = (y2 - y1) / img_h # 边界裁剪,防止坐标越界 x_c = min(max(x_c, 0.0), 1.0) y_c = min(max(y_c, 0.0), 1.0) w = min(max(w, 0.0), 1.0) h = min(max(h, 0.0), 1.0) lines.append(f"{CLASSES.index(name)} {x_c:.6f} {y_c:.6f} {w:.6f} {h:.6f}") out_txt = Path(out_dir) / (Path(xml_path).stem + ".txt") out_txt.write_text("\n".join(lines), encoding="utf-8") xml_dir = "annotations" out_dir = "labels/train" os.makedirs(out_dir, exist_ok=True) for xml_file in Path(xml_dir).glob("*.xml"): voc_to_yolo(xml_file, out_dir)

逻辑不复杂,两个细节必须注意:一是类名列表的顺序,脚本里 CLASSES 的顺序必须和后面 data.yaml 的 names 顺序完全一致,顺序错一位,类别就全错;二是边界裁剪那四行,有些 VOC 标注的框会超出图像边界,不裁剪的话训练时可能会报坐标越界错误,裁剪后能挡掉这个隐患。

3.3 COCO 转 YOLO:用 pycocotools 读取再归一化

COCO 格式在目标检测数据集里也很常见,转 YOLO 的脚本核心部分如下:

from pycocotools.coco import COCO from pathlib import Path coco = COCO("annotations/instances_train.json") cat_map = {cat["id"]: i for i, cat in enumerate(coco.loadCats(coco.getCatIds()))} out_dir = Path("labels/train") out_dir.mkdir(parents=True, exist_ok=True) for img_id in coco.getImgIds(): info = coco.loadImgs(img_id)[0] img_w, img_h = info["width"], info["height"] lines = [] for ann in coco.loadAnns(coco.getAnnIds(imgIds=img_id)): x, y, w, h = ann["bbox"] # COCO bbox 是左上角坐标 + 宽高 cx = (x + w / 2) / img_w cy = (y + h / 2) / img_h fw = w / img_w fh = h / img_h lines.append(f"{cat_map[ann['category_id']]} {cx:.6f} {cy:.6f} {fw:.6f} {fh:.6f}") out_txt = out_dir / (Path(info["file_name"]).stem + ".txt") out_txt.write_text("\n".join(lines), encoding="utf-8")

注意 COCO 的 bbox 是[x, y, width, height],和 VOC 的[xmin, ymin, xmax, ymax]不一样,别拿 VOC 公式直接套。pycocotools 在 Windows 上的安装比较麻烦,常见做法是pip install pycocotools-windows,Linux 和 macOS 直接pip install pycocotools就行。跑完之后抽查几个 txt 文件,肉眼确认坐标值都在 0~1 范围内再进下一步。

3.4 补充标注与复核:用预标注加人工修正清理脏标签

如果解压后发现有些图没有标注文件,或者跑一轮快速训练后觉得漏检多,常见做法是先跑一轮预标注,再用标注工具人工修正。标注工具方面,labelImg 是老牌选择,支持 VOC 与 YOLO 格式导出;X-AnyLabeling 更现代,支持自动分割和半自动标注,对小目标的框选效率高一些。导出 YOLO 格式时,注意类别顺序要从 classes.txt 里读,别在工具里另建一套顺序,否则又会出现 3.2 节里说的错位问题。

这个“先粗标一轮、再人工复核”的思路,特别适合褐飞虱这种小目标密集的数据:先用预训练模型把所有疑似目标框出来,再人工删掉误检、补上漏检,比从头逐图手标快数倍。

4. 用 YOLOv8 训练褐飞虱成虫模型:从数据配置到小目标调优

4.1 编写 data.yaml:路径与类别顺序是唯一不能错的地方

训练前先准备数据集配置文件。拿到的压缩包里如果自带 data.yaml,检查一下路径是否还是打包者的本机绝对路径,是的话改成当前机器的路径。自己写的话,参考这个模板:

path: /home/user/bph_dataset train: images/train val: images/val test: images/test names: 0: bph_adult

path用绝对路径最省心,用相对路径也行但容易因为当前工作目录不同而找不到图片。names的 0 号索引必须和标签文件里的第一个数字对应,这是整个训练流程里最容易出错也最难排查的地方。写完跑一句验证:

python -c "from ultralytics import YOLO; m = YOLO('yolov8s.pt'); print(m.task)"

能正常打印detect说明环境没问题,接下来进入训练。

4.2 训练命令与核心参数:褐飞虱是典型小目标,参数不能照搬默认值

褐飞虱成虫在整张田间图里通常只有几十个像素,拿默认的 imgsz=640 直接训,小目标特征很容易在降采样过程中丢光。我一般这样起训:

yolo detect train \ model=yolov8s.pt \ data=bph.yaml \ imgsz=1280 \ epochs=150 \ batch=16 \ optimizer=AdamW \ lr0=0.0005 \ weight_decay=0.0005 \ mosaic=1.0 \ close_mosaic=10 \ copy_paste=0.3 \ patience=30 \ project=runs/bph

几个关键参数的选择逻辑如下:

参数取值选择理由
imgsz1280褐飞虱是小目标,输入尺寸越大保留的目标像素越多;显存不够时降到 960 或 1024,实在不够就用切片推理
batch16取决于显存,1280 输入下 16 是比较稳的起点值,OOM 就减半
optimizerAdamW小数据集上 AdamW 收敛比 SGD 稳,动量参数不用改默认值
lr00.0005迁移学习微调用,别用默认的 0.01,数据量小的时候容易把预训练权重冲坏
close_mosaic10最后 10 个 epoch 关闭 Mosaic,让模型在接近真实分布的图像上微调,避免小目标被切碎后学不到完整形态
copy_paste0.3褐飞虱常呈群体分布,复制粘贴增强能把单张图里的虫口密度放大,提高高密度场景下的召回率

训练中观察results.png里的曲线,重点关注验证集 mAP50-95 是否还在上升。单类目标 150 个 epoch 通常足够,mAP50-95 连续 20 个 epoch 不涨基本就到头了,patience=30会自己停掉,不用一直守着。

4.3 迁移学习与微调策略:避免目标检测模型微调崩掉

yolov8s.pt预训练权重开始是常见做法,COCO 上训过的权重对纹理、边缘、遮挡这些底层特征提取有很好的先验。数据量小、单类别场景下,我一般会先冻结 backbone 前 10 层,用较低学习率跑 30 个 epoch,让检测头先适应褐飞虱的框分布,再解冻全部层正常训练:

# 先用冻结训练找稳定的检测头 yolo detect train \ model=yolov8s.pt \ data=bph.yaml \ imgsz=1280 \ epochs=30 \ lr0=0.0002 \ freeze=10

如果这一步就开始崩,比如 loss 震荡、mAP 归零,多半是标签顺序错位或者标签坐标有越界,回第三部分重新检查数据,别硬调参数。数据有问题时调参纯属玄学,越调越乱。

4.4 小目标处理的推理端方案:切片推理比单纯改 imgsz 更可靠

训练完的模型投入实测时,灯诱图虫体密集、原位图目标太小,直接整图推理往往漏检严重。常见做法是引入 SAHI 切片推理:把图切成带重叠的若干小块,分别推理再合并结果,重叠区的目标用 NMS 去重。这样等效于把 imgsz 做大的同时不丢失大图的光照全局信息,对高密度小目标场景的召回率提升非常明显。实测中,同一张 4000x3000 的灯诱图,整图推理检到 80 头,切片推理能检到 200 头以上,差距就出在那些被降采样抹掉的微小个体上。

5. 褐飞虱数据集常见问题排查:五个让我熬夜调参的真实坑

5.1 训练到一半 Loss 变成 NaN,程序直接中断

现象:训练跑到第 20 到 40 个 epoch,loss 突然变成nan,日志里出现Gradidents溢出警告或直接报错。

原因:最常见的有两个。一是标签坐标中有大于 1 或小于 0 的值,或者框宽高为负数,这通常是 VOC/COCO 转换时没做边界裁剪;二是学习率设得过高,预训练权重在小数据集上被一步更新冲爆。

解决:先跑数据检查脚本,统计所有标签文件中坐标的最小值和最大值:

grep -oP '(?<=\s)\d+\.\d+' labels/train/*.txt | awk '{print $1}' | sort -g | head -n 1 grep -oP '(?<=\s)\d+\.\d+' labels/train/*.txt | awk '{print $1}' | sort -g | tail -n 1

最小值应该大于等于 0,最大值应该小于等于 1。发现越界就回第三部分在转换脚本里加裁剪逻辑重新转。坐标没问题就降学习率,lr0从 0.0005 降到 0.0001,再不行就排除混合精度影响,在训练命令里加amp=False试一次。

5.2 训练曲线正常,但验证集 mAP 一直为 0

现象:loss 正常下降,验证集的 Precision、Recall 也看着有模有样,但 mAP50 和 mAP50-95 死死钉在 0 上不动。

原因:类别索引错位,这是目标检测里最经典的“微调崩了”场景。标签文件里的第一个数字是 0,但 data.yaml 里names顺序或类别数配置不对;或者 VOC 转 YOLO 时 CLASSES 列表名写错,导致全部目标被过滤掉,标签文件是空的文本。

解决:检查空标签和属类映射,先看没有标签的图片有多少:

find labels/train -name "*.txt" -size 0 | wc -l

再看任意一张标注图,用 Python 加载标签并打印所有类别编号:

python -c "import numpy as np; data = np.loadtxt('labels/train/xxx.txt'); print(np.unique(data[:,0]))"

如果打印出来的类别编号不是 0,而是 1 或 2,说明转标签时 CLASSES 顺序和 yaml 的 names 不一致。统一按二进制之前确认:classes.txt第一行写什么名字,yaml 里 0 号位置就放什么名字。

5.3 高密度灯诱图中重叠成虫漏检严重

现象:单张图里虫口密度超过 100 头时,模型只框出不到一半,漏检密集地出现在虫体重叠区域。

原因:训练数据里高密度图太少,或者 Mosaic 增强把本来就小的高密度群切得更碎。模型没见过“很多虫挤在一起”的完整形态,推理时遇到重叠目标只会保留重叠率低的那一部分。

解决:三个方向同时做。一是把copy_paste从 0.3 提到 0.5,手工复制粘贴虫群区域增加高密度样本;二是在训练最后阶段设置close_mosaic=10,让模型在接近真实分布的图像上收敛;三是推理端用 SAHI 切片,把大图切成小块分别检测,重叠区域的目标就“散开”了。

5.4 田间原位图上,模型把白背飞虱、灰飞虱也都框了出来

现象:部署到田间原位图像后,模型输出里出现大量非褐飞虱的框,尤其是白背飞虱和灰飞虱成虫,它们体型、体色接近,肉眼都要细看才能分。

原因:数据集类别只有 bph_adult,但没有在标注层面做难负样本挖。“没标过”不等于“识别成不要的”,模型没见过同类近似物种,自然把它们当作目标的一部分。

解决:收集一批含白背飞虱、灰飞虱的图,作为负样本目录加入训练,标签留空。在 data.yaml 的 train 配置里,把负样本图片目录也加到train路径下,模型在训练中看到这些图,但没有任何框与之匹配,它才会学会抑制这些相似目标。这个做法的效果往往比加数据增强更直接。

5.5 导出 ONNX 或 TensorRT 后,精度明显下降

现象:PyTorch 推理时 mAP50 是 0.85,导出成 ONNX 后掉到 0.7,转成 TensorRT 的 FP16 又掉几个点。

原因:小目标对量化里精度损失极其敏感。FP16 保留的是浮点精度的低半精度,虫体只有几十像素时,特征值本身很小,量化截断就把关键梯度抹掉了。另外导出时如果用了过小的最小框阈值,会在 NMS 阶段丢掉小目标。

解决:导出 ONNX 时指定opset=12,关闭简化选项,转 TensorRT 时不要用 FP16,先跑 FP32 试一次。如果 FP32 有大幅提升,说明是量化问题,检查 TensorRT 版本和动态输入设置。褐飞虱这种小目标场景,把计算卡的 FP16 关掉换来的精度收益,往往比省下的那点延迟值钱。

6. 验证策略与数据增强技巧:怎么判断模型真的会数虫

6.1 验证集别按图像随机分,按田块分才有说服力

很多人在处理数据集时按图片随机划分训练验证集,这在褐飞虱场景里会虚高 mAP。同一块田不同时刻拍的图像,背景、稻株、光照高度相似,随机划分会把“同一个场景”的相似图像同时分进训练和验证,验证集的 mAP 自然漂亮,但模型换到另一块田就立刻露馅。常见做法是按拍摄田块或按时间批次分组,整组划分,确保验证集里的图像在采集条件上独立于训练集。这才是“遥感图像目标检测”里常说的跨场景泛化评估,对农业小目标模型同样适用。

6.2 用计数误差评估,而不是只看 mAP

目标检测的 mAP 衡量的是“框得准不准”,但植保测报关心的是“每百丛有多少头虫”。模型框偏了一点,mAP 掉一截,对虫量统计却完全没影响;反过来,漏检 10% 的虫,mAP 可能只掉 1 个点,对测报结论却是天壤之别。所以评估时除了 mAP,务必额外统计一个指标:计数相对误差 = 预测虫头数 / 人工数虫数 - 1。部署时设定可接受阈值,比如误差在正负 15% 以内算合格,比盯着 mAP 调参更符合业务落地的直观逻辑。

6.3 增强优先级:轻扰动、少翻转、高密度靠复制粘贴

褐飞虱成虫有轻微趋光性和方向性,但田间拍摄时虫子姿态基本随机,大幅旋转增强意义不大,反而会让模型学习到错误的朝向先验。我一般只保留 0~15 度的随机旋转,不做 180 度翻转,避免把“腹面朝上”这种不可能出现的姿态增强出来。HSV 扰动用轻微档,重点模拟不同时段拍摄的光照差异,比单纯调亮度更接近灯诱图与白天田间图的色温差。数据增强组合里,先保证偏差不漏,再考虑增加多样性。

最后说一个我自己的习惯:训练完后不急着部署,先拿几张灯诱、拍盘、原位的典型图各测一遍计数误差,误差超过 20% 就直接回数据集找原因,而不是继续加轮数。这套流程走顺之后,褐飞虱这类小目标场景的数据处理与模型调优速度会快很多,希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询