尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

玉米好坏检测数据集实战:COCO标注与YOLOv8训练调优

玉米好坏检测数据集实战:COCO标注与YOLOv8训练调优 简介这份玉米好坏检测数据集面向从事农产品品质分拣、粮食加工质检及计算机视觉算法实践的开发者与研究人员用于训练和验证玉米粒好坏二分类或目标检测模型解决实际场景中人工分拣效率低、标准不统一的问题。资源包共2000个文件以1995张jpg图像为主体另含3个json标注文件与2个txt说明文件压缩包约122.84MB图像均按COCO格式完成人工标注可直接接入主流检测框架进行训练与评估。数据集覆盖多种拍摄角度与光照条件下的玉米粒样本标注信息包含类别与边界框便于开展数据增强、模型微调与精度对比实验官方给出的平均准确率在89.5%以上可作为基线参考。目前已有393人学习下载适合需要快速获取高质量标注数据、验证检测方案或搭建农产品质检原型的读者使用。1. 玉米好坏检测数据集2357 张图、COCO 标注、89.5% 准确率意味着什么你拿到一个玉米好坏检测数据集2357 张玉米图片全部按 COCO 格式人工标注官方给的指标是平均准确率 89.5% 以上。先别急着高兴也别急着怀疑——这个数字放在农业视觉检测里属于「能用但要盯紧」的区间。它意味着模型在大多数正常光照、单穗、背景干净的图上能稳定分出好穗和霉变、虫蛀、破损穗但一旦遇到穗子堆叠、阴影遮挡、输送带反光掉点会很明显。这个数据集真正适合的人是做粮食分选设备、粮库质检、玉米收购定级这类场景的算法和工程同学。它解决的不是「从零训一个农业大模型」而是让你在几天内跑通一条从 COCO 标注到可部署检测器的链路先验证业务闭环再决定要不要自己扩标。2357 张不算大但人工标注的 COCO 框质量通常比爬虫自动标的高这是它比很多「数据集下载」站里随手打包的货更值钱的地方。我一般会把它当成一个 baseline 起点先用 YOLOv8 或 MMDetection 跑通看混淆矩阵里「好穗被判坏」和「坏穗被判好」哪个多再决定阈值往哪偏。下面按「先看懂标注 → 再跑通训练 → 再排坑 → 再谈进阶」的顺序讲。2. 拆开 COCO 标注2357 张玉米图里到底存了什么2.1 COCO 的 JSON 结构在玉米检测里长什么样COCO 格式不是「一个文件夹一堆图」那么简单它的信息全压在一个 JSON 里。玉米好坏检测通常只有两类或三类good好穗、bad坏穗有的还会细分 mold霉变、insect虫蛀。你要做的第一件事不是写训练脚本而是把 JSON 读出来确认类别数、框数、每类分布。import json from collections import Counter with open(annotations/instances_train.json, r, encodingutf-8) as f: coco json.load(f) # 类别映射category_id - name cats {c[id]: c[name] for c in coco[categories]} print(类别:, cats) # 每类框数量 cnt Counter() for ann in coco[annotations]: cnt[cats[ann[category_id]]] 1 print(每类框数:, cnt) # 每张图的框数分布判断是否密集 img_box Counter() for ann in coco[annotations]: img_box[ann[image_id]] 1 print(单图最多框数:, max(img_box.values())) print(有框图片数:, len(img_box), 总图片数:, len(coco[images]))这段代码做三件事把 category_id 翻译成人类能读的类别名统计每类框数判断有没有严重类别不平衡统计单图框数判断玉米是「一图一穗」还是「一图多穗堆叠」。如果单图最多框数超过 15说明有密集堆叠场景后面 NMS 的 IoU 阈值就不能照搬默认 0.7。参数上重点看两个categories的 id 是否从 1 开始连续COCO 惯例是 1 起但有人从 0 起直接喂给 YOLO 会错位annotations里iscrowd是否为 0。玉米穗如果被标成 iscrowd1训练时会被当忽略区域你以为是坏穗的样本其实没参与 loss。2.2 把 COCO 转成 YOLO 格式转换脚本与四个边界坑YOLOv8 吃的是 txt 格式每行class x_center y_center w h全部归一化到 0~1。转换本身不难坑在边界。import json, os from PIL import Image def coco2yolo(json_path, img_dir, out_dir): with open(json_path, r, encodingutf-8) as f: coco json.load(f) cats {c[id]: i for i, c in enumerate(coco[categories])} # 重映射到 0 起 img_info {im[id]: im for im in coco[images]} os.makedirs(out_dir, exist_okTrue) for ann in coco[annotations]: im img_info[ann[image_id]] W, H im[width], im[height] x, y, w, h ann[bbox] # COCO 是左上角 x,y 宽高 # 边界裁剪防止越界导致归一化后为负或 1 x1 max(0, x); y1 max(0, y) x2 min(W, x w); y2 min(H, y h) if x2 x1 or y2 y1: continue # 退化框直接丢 cx (x1 x2) / 2 / W cy (y1 y2) / 2 / H bw (x2 - x1) / W bh (y2 - y1) / H line f{cats[ann[category_id]]} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}\n name os.path.splitext(im[file_name])[0] .txt with open(os.path.join(out_dir, name), a, encodingutf-8) as fo: fo.write(line) coco2yolo(annotations/instances_train.json, images/train, labels/train)逻辑说明COCO 的 bbox 是[x, y, width, height]YOLO 要的是中心点加宽高且归一化。四个边界坑分别是一框超出图像边界不裁剪会得到负数或大于 1 的值训练直接报 nan二退化框宽或高为 0要丢弃否则除零三category_id 必须重映射到 0 起连续否则 YOLO 的 nc 对不上四同一张图多个框要用追加模式写同一个 txt别每框覆盖一次。提示转换完随手抽 5 张图用labelImg或cv2画框回看确认框和玉米穗对齐。人工标注也会有手抖89.5% 的准确率里有一部分就是标注噪声吃掉的。3. 用 YOLOv8 在本地跑通玉米好坏检测的最小命令3.1 环境与数据目录一次配置到位先明确目录结构YOLOv8 对路径敏感配错了报错信息很难读。# 目录结构 corn_dataset/ ├── images/ │ ├── train/ # 约 1885 张 │ └── val/ # 约 472 张 ├── labels/ │ ├── train/ │ └── val/ └── corn.yamlcorn.yaml内容path: /abs/path/corn_dataset train: images/train val: images/val nc: 2 names: [good, bad]path一定写绝对路径相对路径在不同工作目录下会翻车。nc是类别数玉米好坏二分类就写 2如果细分霉变虫蛀就改成对应数量names顺序必须和转换脚本里cats的枚举顺序一致。pip install ultralytics yolo detect train datacorn.yaml modelyolov8n.pt epochs100 imgsz640 batch16这是最小可跑命令。yolov8n.pt是最小的 nano 模型2357 张图用它先验证链路别一上来就上 x 或 l显存和时间都吃不消。imgsz640是默认玉米穗在图中占比如果很小可以提到 960但显存翻倍。3.2 三个必调参数imgsz、batch、学习率跑通之后决定 89.5% 能不能复现甚至超过的主要是这三个。imgsz玉米穗如果整图只占 1/5 面积640 下穗子只有一百多像素霉变斑点和阴影分不开。我一般先跑 640 看 mAP再跑 960 对比如果 960 涨了 3 个点以上说明小目标吃亏最终部署也得按 960 走。batch显存够就 16 或 32太小比如 4会让 BN 统计不稳loss 抖。显存不够用batch8加accumulate2模拟大 batch。学习率YOLOv8 默认lr00.01对 2357 张的小数据集偏大容易前期震荡。我一般降到lr00.005配合cos_lrTrue余弦退火。命令yolo detect train datacorn.yaml modelyolov8n.pt epochs150 imgsz960 batch8 lr00.005 cos_lrTrue patience30patience30是 30 轮没提升就早停小数据集过拟合快别硬跑 300 轮。3.3 看结果混淆矩阵比 mAP 更能说明玉米好坏训练完别只看 mAP50。打开runs/detect/train/confusion_matrix.png重点看两个格子好穗被判成坏穗假阳、坏穗被判成好穗假阴。粮食收购场景里坏穗漏检判成好比好穗误判判成坏代价高得多因为霉变粒混进去整仓降级。如果假阴多把坏穗类的置信度阈值调低或者训练时给坏穗类加权。YOLOv8 不直接支持类权重常见做法是过采样坏穗图片或者用copy_paste增强把坏穗复制到更多背景上。from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) metrics model.val(datacorn.yaml, conf0.25, iou0.6) print(metrics.box.maps) # 每类 mAPconf0.25是验证时的置信度阈值iou0.6是 NMS 的 IoU。玉米堆叠场景把 iou 提到 0.7否则相邻穗子会被互相抑制掉。4. 玉米检测的避坑与排查89.5% 掉到 70% 的五个原因4.1 现象验证集 mAP 正常实拍图全乱原因训练集和验证集来自同一批拍摄条件背景、光照、相机一致模型学到了「背景捷径」而不是玉米本身。实拍换了输送带颜色或灯光直接崩。解决从 2357 张里按拍摄批次划分 train/val别随机分。如果元数据里没有批次信息看文件名前缀或 EXIF 时间。再不行手动挑 200 张明显不同光照的做 val。4.2 现象坏穗召回率极低几乎全判成好穗原因类别不平衡。好穗可能 1800 框坏穗只有 500 框模型倾向多数类。解决过采样坏穗图或在 dataloader 里对坏穗类做copy_paste。另一个办法是二阶段先检测所有穗再裁出来做好坏分类分类阶段可以单独平衡。4.3 现象训练 loss 正常下降但 mAP 卡在 0.6 不动原因标注框普遍偏大或偏小。人工标玉米穗时有人框到穗尖有人只框穗身IoU 分布散模型学不准。解决抽 30 张图统计框面积分布如果方差极大考虑统一标注规范重标或者用mosaic增强让模型对框尺度不敏感。YOLOv8 默认开 mosaic确认没被关掉。4.4 现象推理时同一穗出多个框原因NMS 的 IoU 阈值默认 0.7玉米穗细长两个预测框 IoU 可能只有 0.5 就被保留。解决推理时把iou降到 0.5或者用agnostic_nmsTrue让不同类之间也互相抑制。命令里加iou0.5 agnostic_nmsTrue。4.5 现象换 960 分辨率后显存爆了原因imgsz 翻倍特征图面积翻四倍显存涨得比想象多。解决batch 减半或者用yolov8s代替yolov8n但保持 640。也可以开ampTrue混合精度YOLOv8 默认开确认没被手动关。5. 把 89.5% 用起来阈值调优与部署前验证5.1 按业务代价调置信度阈值89.5% 是默认 conf0.25 下的平均准确率但你的场景未必用 0.25。写个小脚本扫一遍阈值看坏穗召回和好穗误判的权衡。from ultralytics import YOLO import numpy as np model YOLO(runs/detect/train/weights/best.pt) for conf in np.arange(0.1, 0.6, 0.05): m model.val(datacorn.yaml, conffloat(conf), iou0.6, verboseFalse) # 假设类别 0 是好穗1 是坏穗 print(fconf{conf:.2f} good_mAP{m.box.maps[0]:.3f} bad_mAP{m.box.maps[1]:.3f})如果坏穗 mAP 在 conf0.15 时最高而好穗在 0.3 时最高说明两类的最优阈值不同。部署时可以按类设阈值坏穗用低阈值保召回好穗用高阈值保精度。5.2 部署前必须做的三张图验证别信验证集数字部署前一定做三件事。第一拿 20 张完全没参与训练的实拍图跑一遍人工数漏检和误检。第二拿一张密集堆叠图看 NMS 后还剩几个框和人工数对比。第三拿一张极端光照图过曝或欠曝看模型是否直接输出空。这三张图过了89.5% 才算落地。5.3 一个具体技巧用 SAHI 切图提升小穗检出如果玉米穗在整图里占比小于 5%640 或 960 都吃力。用 SAHISlicing Aided Hyper Inference把大图切成重叠小图分别推理再合并小目标召回能涨 5 到 10 个点。from sahi import AutoDetectionModel from sahi.predict import get_sliced_prediction det AutoDetectionModel.from_pretrained( model_typeyolov8, model_pathruns/detect/train/weights/best.pt, confidence_threshold0.25, devicecuda:0 ) result get_sliced_prediction( test_dense.jpg, det, slice_height640, slice_width640, overlap_height_ratio0.2, overlap_width_ratio0.2 ) result.export_visuals(export_dirsahi_out/)slice_height/width按训练 imgsz 设overlap0.2 是经验值太小会切断穗子太大推理变慢。切图后同一穗可能被多个切片检出SAHI 内部会做 NMS 合并但合并阈值要自己调默认有时会留重复框。我自己的习惯是任何农业检测数据集先跑通最小链路再用混淆矩阵定阈值最后一定拿实拍图打脸一次。2357 张、COCO 人工标注、89.5% 这个起点不算差但别把它当终点把它当尺子——量出你的真实场景还差多少再决定补标还是换模型。希望帮到你。本文还有配套的精品资源点击获取
返回列表