植物萌芽检测实战:基于YOLOv12的数据集标注与训练全流程
发布时间:2026/10/1 2:45:18来源:尧图网络
简介植物萌芽检测数据集专注植物萌发阶段的视觉识别面向精准农业监测、智能温室管理、植物表型研究及农业科研教学等场景可支持构建萌芽期识别模型用于作物生长阶段自动化监测与生长周期预测。数据集共2000个文件涵盖1484个txt格式边界框标注、514张jpg原始图像、1个yaml配置与1个docx说明文档压缩包整体约133.71MBtxt标注遵循中心坐标加宽高的YOLO规范yaml可直接套用训练配置docx补充数据构建与使用建议。数据划分包含1177张训练图、302张验证图及5张测试图覆盖多种视角并包含旋转、裁剪、噪声处理等增强版本有助于提升模型鲁棒性。目前已有101人学习适合目标检测研究者与农业AI开发者快速开展萌芽期检测实验亦可作为农林院校算法教学实践数据集。1. 植物萌芽检测数据集从标准 YOLO 标注图到能落地的出芽识别模型温室育苗车间里一张苗盘几百个穴孔旺季时工人要逐个弓腰核对萌芽率一个班下来脖子和眼睛都僵得难受。植物萌芽检测数据集解决的正是这种重复枯燥的视觉劳动它把苗期图像整理成标准 YOLO 标注格式拿回来就能直接丢给 YOLOv12 这类目标检测模型训练模型输出每个芽的坐标框与置信度后面接统计报表还是补苗机械臂都顺理成章。适合三类人做农业自动化方案的工程团队、要在嵌入式设备上跑植物视觉识别的开发者以及研究工业农业医学领域目标检测数据集落地的从业者。省下的不只是标注时间还有从零梳理训练管线的过程。2. 先看懂数据集的目录与标注格式训练前的一小时自检2.1 目录结构长什么样这份资源解压之后内部目录是按目标检测训练的标准习惯组织的。我拿到任何一份数据集第一步不是急着训练而是先把目录树摸清楚确认 images 和 labels 是否一一对应。常见结构如下plant_sprout/ ├── images/ │ ├── train/ │ │ ├── sprout_0001.jpg │ │ ├── sprout_0002.jpg │ │ └── ... │ └── val/ │ ├── sprout_0351.jpg │ └── ... ├── labels/ │ ├── train/ │ │ ├── sprout_0001.txt │ │ ├── sprout_0002.txt │ │ └── ... │ └── val/ │ └── ... └── plant_sprout.yamltrain 与 val 的比例通常接近 8:2 或 9:1这个数据集按经验也是这种划分。图像多为俯拍或斜俯拍的苗盘/苗床照片分辨率跨度比较大有手机拍的也有工业相机拍的恰好能模拟现场设备参差不齐的真实状况。每个 jpg 对应一个同名 txttxt 里存的就是这张图上所有目标框的标注。yam 文件是给 Ultralytics 系列训练框架用的数据集描述文件里面写明了类别数量和类别名称训练时直接以dataplant_sprout.yaml的方式引用。在动手训练之前建议先做一件事用tree或find把文件数量统计出来确认两个目录的文件数一致避免后面训练时出现“部分图像没有标签”的隐蔽问题。find images/train -name *.jpg | wc -l find labels/train -name *.txt | wc -l如果两边数量对不上说明存在漏标注的图像后面训练出的模型在没标签的那些图上大概率会被当作负样本直接干扰损失函数。我的习惯是先把这一步走完再谈参数。2.2 YOLO 标注格式里的数字到底代表什么YOLO 格式的每一行是五个数字依次是类别编号、目标中心点的 x 坐标、y 坐标、目标宽度、目标高度。坐标全部做了归一化处理取值都在 0 到 1 之间分母是图像的宽和高不是像素绝对值。我拿一份典型的标注拆开说明1 0.513462 0.288741 0.034615 0.040727这一行表示这张图里有一个类别编号为 1 的目标它的中心点位于图像水平方向 51.35%、垂直方向 28.87% 的位置目标本身宽度约占整张图宽度的 3.46%高度约占整张图高度的 4.07%。换算成像素值只需要把前两个数乘以图像宽高、后两个数乘以图像宽高就能得到真实的像素框。萌芽期的小苗在整张图中往往只占很小一块面积所以 w、h 这类数字普遍落在 0.02 到 0.08 之间属于典型的小目标标注。做这类数据集训练最忌讳的就是把 w、h 的顺序记反还有把中心点坐标误当成左上角坐标。我见过不止一个同事用 LabelImg 导出时选了 PASCAL VOC 格式然后又手动转 YOLO转完忘了除宽度训练出来的框全部偏移到图像角落。这份数据集里常见类别有两种组织方式一类是只标“萌芽”一个类别适合单纯的出芽计数另一类会把“未出芽的空穴”和“已出芽”区分开甚至把子叶展开的苗单独列一类。后者在实际补苗场景中更有用因为自动补苗需要同时知道哪里空着、哪里已经长出来了。拿到数据集后先打开 yaml 文件确认 names 列表的内容不要按我的项目场景强行套你的业务逻辑。2.3 用一段脚本把数据集的健康状况查一遍训练之前我强烈建议把下面这段校验脚本跑一遍。它做的事很简单遍历每张训练图检查同名标签是否存在、每行是不是 5 个字段、坐标是否都落在 0 到 1 范围内。这段脚本几乎可以套用在任何 YOLO 格式数据集上不止这一份资源。from pathlib import Path root Path(plant_sprout) bad_count 0 for split in [train, val]: img_dir root / images / split lbl_dir root / labels / split for img_p in sorted(img_dir.glob(*.jpg)): lbl_p lbl_dir / (img_p.stem .txt) if not lbl_p.exists(): print(f[标签缺失] {img_p.name}) bad_count 1 continue for line in lbl_p.read_text().splitlines(): parts line.split() if len(parts) ! 5: print(f[格式错误] {img_p.name}: {line}) bad_count 1 continue cls parts[0] try: cx, cy, w, h map(float, parts[1:]) except ValueError: print(f[数值错误] {img_p.name}: {line}) bad_count 1 continue if not all(0 v 1 for v in (cx, cy, w, h)): print(f[坐标越界] {img_p.name}: {line}) bad_count 1 print(f检查完成异常数量: {bad_count})逻辑并不复杂先用glob拿到所有 jpg 文件名用stem属性去掉扩展名后拼出对应 txt 路径再逐行解析先查字段数量再查数值范围。坐标越界是最常见的问题之一比如手工标注时不小心把框拉出了画布边缘归一化后出现大于 1 的值。如果异常数量为 0说明这份数据集在结构层面是干净的可以进入训练环节。如果报出一堆标签缺失建议直接补一份空 txt 或者删除对应图像不要让模型把无标签区域当负样本学。这条规则对所有计算机视觉数据集都适用尤其是做行业数据集复用时前人的标注习惯未必严谨自检这一步不能省。3. 用 YOLOv12 把萌芽检测模型跑通环境、参数与验证3.1 训练环境与数据集划分YOLOv12 的训练流程和整个 YOLO 系列基本一致主流做法还是基于 Ultralytics 框架。先装好依赖pip install ultralytics albumentations如果你的 Ultralytics 版本还没有收录 YOLOv12 的预训练权重可以先换成 yolov11n 或 yolov8n 验证整套流程数据集本身不绑定特定模型版本标注格式是所有 YOLO 家族通用的。常见做法是先跑通小模型确认数据和标签没有问题再切换到大模型。数据集划分前要注意一个容易被忽略的点如果原始图像里存在同一苗盘的连拍序列直接随机打散划分 train/val 会造成图片泄漏验证指标虚高。按拍摄批次或时间先后切分例如前 80% 时间段的图像进 train、后 20% 进 val才是模拟真实新场景的做法。这一点在工业农业医学行业目标检测数据集里尤其重要因为现场采集往往是一次性拍几百张连图。我会在数据目录外新建一份数据集描述文件内容如下# plant_sprout.yaml path: ./plant_sprout train: images/train val: images/val nc: 2 names: [empty_hole, sprout]path写数据集根目录的相对路径train、val相对于path填写nc是类别总数names按类别顺序列出。如果你的数据集是单类别把nc改成 1names只保留一个即可。3.2 训练参数模板与说明下面是我平时训练萌芽检测时用的参数模板。YOLOv12 训练入口与 YOLOv8/YOLOv11 风格一致下面这段按 Ultralytics 通用接口写成from ultralytics import YOLO model YOLO(yolov12n.pt) model.train( dataplant_sprout.yaml, epochs120, imgsz640, batch16, lr00.01, lrf0.01, optimizerSGD, patience20, augmentFalse, seed42, )逐项解释我的选择理由epochs120是考虑到数据集规模不大给足迭代次数让小目标框的 anchor 充分调整imgsz640兼顾显存占用和大多数手机/工业相机图片的分辨率比例如果图像本身就是 1920×1080 的航拍图建议直接提到 960 再训练否则芽的像素面积会被压缩到十几像素batch16是 24GB 显存的典型配置显存小的机器降到 8lr00.01是 SGD 优化器的常用初值配合patience20早停在验证指标不再上升时自动保存最好权重augmentFalse是因为我习惯先跑一版不带增强的基线确认数据和标签正确再开增强。先解释imgsz对小目标的影响。imgsz640意味着输入图像会被缩放到 640×640原本 4000×3000 的大图里一个 40×40 像素的芽缩放后只剩约 6×6 像素几乎在主干网特征图上消失。第一版训练如果发现漏检严重优先把imgsz提到 960 或 1280。再解释augmentFalse的用意。Ultralytics 默认开启 Mosaic、HSV 扰动等增强数据集本身存在标注偏差时很难判断是增强过度还是模型欠拟合。先关闭增强跑一版干净的再增开是我处理所有行业数据集的一贯顺序。推理验证的代码也贴出来方便直接复现from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) results model.predict( sourcetest_images/, imgsz640, conf0.3, saveTrue, save_txtTrue, )conf0.3是出芽检测场景比较合理的下限。芽体小、边缘模糊置信度普遍比大目标低一截卡在 0.5 会漏掉大量真值save_txtTrue会把检测结果存成 YOLO 格式文本方便后续统计每张图的芽数。3.3 验证指标怎么读训练结束后Ultralytics 会输出一张 results.csv里面逐行记录了每个 epoch 的 mAP50、mAP50-95、precision、recall。萌芽检测这类小目标任务我更关注 recall 而不是 mAP。因为补苗场景里漏掉一个芽意味着空穴被当成有苗后期不会有人再补种损失更不可逆误报多一个芽顶多补苗时多放一粒种子成本低得多。如果 recall 低于 0.85建议按第 4 章的方法加大输入尺寸、调整增强策略。如果 precision 远低于 recall再去排查是不是标注框偏大导致模型把背景也包了进来。我通常会从 results.csv 里抽最后 10 行的数据做判断避免只看最佳权重那一个点。4. 数据增强与小目标优化让模型对现场光照更鲁棒4.1 针对萌芽图像的增强参数萌芽检测的图像大多在温室或苗床拍摄光照条件受天气、补光灯、遮阳网影响很大同一批苗在不同时段拍出来的色温、亮度完全不同。模型需要对这些变化不敏感才能在现场稳定工作。开启增强时我比较关注下面这几项model.train( dataplant_sprout.yaml, epochs120, imgsz960, batch8, hsv_h0.015, hsv_s0.6, hsv_v0.5, degrees15, translate0.1, scale0.4, fliplr0.5, flipud0.1, mosaic0.8, )hsv_v0.5允许亮度在正负一半的区间内随机扰动温室补光灯开启和关闭时的亮度差异基本能被覆盖hsv_h0.015只做轻微色相扰动避免把芽的绿色和土壤的黄色混到一起degrees15模拟相机安装角度偏移苗盘在视野里稍微歪一点也能被识别。flipud0.1只给 10% 概率因为俯拍角度下图像上下翻转虽然物理上合理但如果现场苗盘有方向性纹理翻转过多反而引入噪声。Mosaic 增强会把四张图拼成一张放大图像中的上下文信息。对小目标检测来说Mosaic 能显著提升模型对“芽周围土壤环境”的建模能力但也要注意如果标注框本身有偏差拼图后偏差会被放大。我习惯把mosaic从默认的 1.0 降到 0.8给正常图像留一些训练比例。4.2 输入尺寸、类别不平衡与困难样本挖掘萌芽数据集普遍存在一个反直觉的现象类别不平衡不在“萌芽 vs 背景”而在“容易检测的萌芽 vs 难检测的萌芽”。刚破土而出的芽只有两片子叶甚至只有一条缝面积小、对比度低和土壤颜色接近模型倾向于只学那些已经展开子叶、边界清晰的大芽。针对这种困难样本有两个常见做法我经常组合使用。第一把输入尺寸从 640 提到 960。萌芽框宽度占整图的比例通常在 0.03 到 0.05 之间640 输入下对应 19 到 32 像素属于小目标但还不算极小960 输入下能到 29 到 48 像素特征图上的响应明显增强。显存不够时用batch8或者开启梯度累积也要上大图尺寸这一步对小目标检测的收益往往比调任何超参数都明显。第二对低置信度样本做二次标注加入训练集。训练完第一版模型后把验证集里 recall 为 0 的图像抽出来人工检查是没标还是标错。常见情况是原数据集漏标了那些特别小的芽模型学到了正确特征但 label 里没有对应框损失函数把正确的预测也当负样本惩罚。把这些漏标补上再训练一轮recall 通常能提升三到五个百分点。类别不均衡的处理则要看 yaml 里的 names 定义。如果你的数据集区分了empty_hole和sprout两个类别且空穴数量远多于芽数可以在采样时对sprout类别的图像做上采样复制让每个 epoch 里两类目标出现的频率接近。Ultralytics 没有直接提供 per-class 采样参数常见做法是提前在数据层面复制少数类图像或者直接用外部脚本做重采样。5. 避坑五个翻车现场与排查记录5.1 损失正常下降验证 mAP 却一直是 0现象训练日志里 box loss 从 0.08 慢慢降到 0.03看起来很健康但每个 epoch 结束后的 mAP50 和 recall 都停在 0 附近整张验证集一个框都预测不出来。原因标签文件路径写错了。plant_sprout.yaml里train和val写的是images/train和images/val但 Ultralytics 会默认去labels/train找同名 txt。如果 labels 目录名大小写不一致或者 txt 文件压根没放进去训练时所有图像都成了“无标签”状态模型学不到任何监督信号损失下降只是背景知识的正常收敛。解决回到 2.3 的校验脚本先统计 labels/train 下的 txt 数量确认和 images 数量一致。如果 txt 文件存在但训练仍显示 0 标签打开其中一份看内容是否为空文件。空文件比缺失文件更隐蔽因为文件名对得上但没有任何标注行模型依然拿不到监督信号。5.2 预测框整体偏到芽旁边的土壤上现象置信度挺高框也方方正正但框的中心点不在芽体上而是落在芽基部旁边的土块或基质上尤其是小芽特别明显。原因标注框不够紧。很多标注工具导出的框是矩形外接框如果标的时候图省事把边框划大了几像素芽体本身又小于 10 像素框中心点就会偏离目标区域。模型训练过程中会学着预测这个“偏了的中心”最后输出的预测自然也是偏的。解决我一般会抽查 50 张训练图把标注框画回原图看贴合度。如果固定偏移方向比如都是偏右下说明标注时统一出现了系统性偏差用脚本把所有标注按像素偏移修正再训练。如果是随机偏移就把这类边界模糊的样本找出来重新标注重点修那些面积小于 20×20 像素的框。5.3 刚破土的芽频繁漏检已展开子叶的芽都能检出现象分类别统计时sprout类的 recall 明明有 0.92但实际看可视化推理结果漏掉的全是最小的那批芽很多只有三五个像素宽。原因这是典型的小目标在多尺度特征图中响应不足。YOLO 系列的主干网络下采样倍数决定了最小检测尺寸输入 640 时P3 特征图的 stride 是 8对应感受野大约 8 像素小于 8 像素的目标基本只能靠上下文推测难以形成稳定的特征响应。解决两个手段组合一是按 4.2 把imgsz提到 960 或 1280让目标在输入图像里的像素面积变大二是用切图推理。我常用的工具是 SAHISlicing Aided Hyper Inference把大图切成 640×640 的重叠切片分别推理再合并结果能在不改训练配置的情况下把 recall 拉高五到十个点。对萌芽检测这种目标小、分布密的任务切图推理几乎是现场落地的保底方案。5.4 显存不够batch 调小后损失曲线剧烈震荡现象24GB 显卡跑batch16没问题换到 8GB 显卡只能batch4训练损失从 0.05 到 0.11 来回跳验证指标也不稳定早停机制频繁误判。原因batch 太小的情况下BNBatch Normalization层的统计量计算不稳定每批数据的均值和方差波动大梯度方向的噪声也随之放大。这在目标检测的早期训练阶段尤其明显因为前期 anchor 分配还在剧烈变化。解决优先做梯度累积单卡上模拟出更大的 batch。Ultralytics 支持在训练参数里通过batch和accumulate配合或者手动在优化器层面累积梯度。其次把优化器从 SGD 换成 AdamW它对小 batch 的适应性更好一些。如果两者都不方便就强制冻结 backbone 前 10 层训练只更新检测头能显著降低显存占用和梯度波动。5.5 验证指标很好一到现场新场景就翻车现象训练集和验证集都是从同一次拍摄里随机划分的mAP50 到了 0.95结果到现场换了一批苗盘拍摄检测率直接掉到 0.6 以下。原因随机划分造成数据泄漏。同一苗盘、同一时段拍摄的图像之间高度相似模型记忆了这些图像的纹理特征而不是“芽”本身的通用特征验证集和训练集太像导致评估结果虚高。解决所有行业数据集都应该按时间或场景做分组划分而不是随机打散。具体到这个数据集我会把所有图像先按拍摄日期排序取前 80% 的图像做训练后 20% 做验证。如果资源里没带时间信息就按文件名序号的大段切分保证同一个批次的连拍不会同时出现在训练和验证里。这个改动看起来小但对现场泛化能力的影响是决定性的。6. 训练完成后我建议你在交付前强制走一遍的验证流程模型训练完不代表能用每年因为这个翻车的人不少。我自己的习惯是留出一个叫final_check的小目录里面放 20 到 30 张与训练集完全不同场景的图片比如不同育苗盘的、不同光照下的甚至手机拍摄角度与工业相机不同的。每次训练完不管验证集指标多好看都要把这个目录跑一遍推理肉眼检查输出结果。检查时重点看两类错误一类是漏检模型对某个明显的芽没输出任何框另一类是错检把土壤里的石子、基质颗粒或刻度线误判成芽。前者说明泛化不足后者说明特征学习有偏差。漏检多的回到第 4 章调输入尺寸和增强错检多的往往是标注时把背景物体框了进去需要回查训练集里有没有类似的脏标签。我还习惯把每张测试图的置信度分布打印出来统计conf 0.3的检测框数量占比。如果一张 640×640 的图上模型输出了上百个低置信度框说明模型对背景产生了过度敏感需要在后处理里把conf阈值往上提到 0.35 或 0.4同时检查是不是训练集里空穴类别样本太少。最后分享一个我自己的血泪教训有一次做实时的苗盘巡检设备训练阶段只跑通了 YOLOv8 的默认配置没有做小目标优化结果拿到现场后漏检率高出预期好几倍。从那以后我每次训练前都强制走一遍数据校验、按场景划分训练集、开大输入尺寸这三个步骤虽然多花一两个小时但再也没有出现过交付现场翻车的情况。这份植物萌芽检测数据集本身标注得算规范但任何数据集到了自己手里都值得按这个流程过一次手希望我的经验能帮你少走一段弯路。本文还有配套的精品资源点击获取
网站建设高端定制企业官网