玉米粒好坏检测数据集制作与YOLOV5训练全流程解析 简介本资源是面向计算机视觉初学者与农业智能化应用开发者的YOLOv5兼容目标检测数据集专用于玉米粒破损缺陷识别任务解决农产品质检中细粒度分类与密集小目标定位难题。数据集严格遵循YOLOv5目录结构组织含训练集1734张640×640 RGB图像对应txt标签与验证集171张图像标签共1906个标注文件、93张JPG图像及1个可视化绘图Python脚本总文件数2000个压缩包大小105.5MB。已有359人学习下载体现其在教学实践与轻量级部署场景中的实用价值。用户可直接加载训练无需格式转换附带的可视化脚本支持一键绘制边界框并保存结果图便于快速验证标注质量与模型预测效果所有样本均采集于单一背景目标密度高特别适合小目标检测算法调优与数据增强策略研究。 做玉米粒检测这份数据集的时候我踩了不少坑。从最初拿到一堆零散的玉米粒图片到最终整理成符合YOLOV5目录格式、可以直接开训的标准数据集中间经历了标注格式混乱、类别定义模糊、数据集划分不合理等一系列问题。这篇文章就把整套整理思路和实操过程完整记录下来包括YOLOV5目录格式的细节、标注规范、训练时的参数配置以及我在实际检测过程中遇到的几个典型问题。想自己动手做农产品检测数据集或者正准备用YOLOV5训练一个两类别目标检测模型的朋友这篇文章应该能帮你节省不少时间。1. 玉米粒好坏检测的数据集设计思路1.1 搞清楚检测目标和类别定义玉米粒好坏检测属于典型的小目标检测场景。和常见的行人检测、车辆检测不同玉米粒单颗体积小、排列密集、外观特征细微坏粒的霉变区域和好粒的自然色泽过渡有时候非常接近。所以数据集的质量直接决定了最终模型的上限。这个数据集定义为2类别从我实际整理的经验来看类别划分建议如下good好粒籽粒饱满、色泽均匀、无明显霉斑或破损。bad坏粒包含霉变、虫蛀、发芽、破损、变色等不满足食用或加工标准的籽粒。这里有个关键点坏粒的定义不要搞得太细。有人会想把“霉变粒”和“破损粒”分成两个类别但在实际场景中这两种状态经常同时出现在同一颗玉米粒上标注人员很难判断该归哪一类。做2类别而不是多类别能大幅降低标注歧义模型训练时的收敛速度也更快。如果你的业务确实需要区分霉变和破损建议先用2类别把检测做稳再考虑后续细分类。1.2 为什么选择YOLOV5目录格式目标检测数据集的格式五花八门有Pascal VOC的XML格式、COCO的JSON格式还有YOLO系列的TXT格式。选择YOLOV5目录格式主要基于三点考虑一是YOLOV5目前仍然是工业界应用最广泛的目标检测框架之一生态成熟、资料丰富二是YOLOV5的TXT标签格式非常简洁每个标注文件都是一行一个目标分别记录类别ID和归一化后的边界框坐标处理起来非常高效三是YOLOV5目录格式对训练集和验证集的划分有着明确约定只需要把图片和标签分别放到对应文件夹下再写一个简单的YAML配置文件就能开始训练几乎没有额外学习成本。从实际使用体验来说YOLOV5目录格式对初学者非常友好。你不需要懂复杂的JSON层级结构也不需要维护额外的映射关系文件一个data.yaml就搞定了所有配置。而且这个格式可以很方便地转换成其他框架需要的格式后续如果想迁移到YOLOV8或者MMDetection都有现成的转换脚本可以用。1.3 训练集与验证集划分的合理比例数据集的划分比例是个老生常谈但很关键的问题。yolov5超参数和数据集划分方式直接影响训练结果的可靠性。这个数据集包含训练集和验证集没有单独的测试集这在数据量有限的情况下是合理的做法。我实际用的划分比例是训练集验证集 91。没错验证集比例低于很多人习惯的82或73。原因在于玉米粒检测数据集中单张图片包含的目标数量很多一张图可能有三四十颗玉米粒所以即使验证集图片只占10%实际的验证目标数量也相当可观足够反映模型性能。反之如果验证集比例太高训练集的多样性会受影响尤其是坏粒样本在自然状态下占比本来就低训练数据不够会导致漏检率上升。注意划分时要保证训练集和验证集的图片来自不同批次的拍摄而不是随机打乱后再分。否则同一批玉米粒的图片会同时出现在训练集和验证集中导致验证结果虚高模型实际部署时的表现远不如验证指标。2. YOLOV5目录结构与标签格式全解析2.1 标准目录结构长什么样这是YOLOV5标准的数据集目录结构整个数据集打包后目录层级应该是这样的corn_detection/ ├── data.yaml ├── train/ │ ├── images/ │ │ ├── corn_001.jpg │ │ ├── corn_002.jpg │ │ └── ... │ └── labels/ │ ├── corn_001.txt │ ├── corn_002.txt │ └── ... └── val/ ├── images/ │ ├── corn_101.jpg │ ├── corn_102.jpg │ └── ... └── labels/ ├── corn_101.txt ├── corn_102.txt └── ...每个子集train和val下都必须严格区分images和labels两个文件夹图片和对应的标签文件必须同名后缀名不同没关系YOLOV5会自动匹配否则训练时会直接报错找不到标签文件。以上是YOLO系列的经典目录布局。在YOLOV5中data.yaml文件是训练时的重要配置它告诉程序类别数量和类别名称并指定训练集和验证集的图片路径。实际中还需要在data.yaml里写明标签文件的关联方式YOLOV5会根据图片路径自动推导对应标签路径不需要额外配置。2.2 data.yaml 配置文件详解data.yaml是训练过程中最重要的配置文件内容非常简单但一个字段都不能错。以下是我使用的配置# data.yaml train: ./corn_detection/train/images val: ./corn_detection/val/images nc: 2 names: [good, bad]train和val指定训练集和验证集图片所在路径路径可以是相对路径也可以是绝对路径。建议使用相对路径这样整个数据集文件夹即使迁移到其他环境也不需要修改配置。nc类别数量这里是2。names类别名称列表顺序必须和标签文件中的类别ID一一对应。这里good对应ID 0bad对应ID 1。千万不要小看这个yaml文件nc和names一旦写错模型训练结果会彻底错乱。我在实际项目里见过有人因为names顺序写反训练出来的模型把所有好粒都检测成坏粒而且因为检出框位置准确一时半会还发现不了问题。2.3 TXT标签文件的格式与归一化细节YOLOV5的标签文件是纯文本格式每一行代表一个目标格式为类别ID x_center y_center width height关键点在于所有坐标值都是归一化后的相对值不是像素坐标。x_center和y_center表示目标中心点相对图片宽高的比例width和height表示目标宽高相对图片宽高的比例取值范围在0到1之间。举个例子如果一张图片宽度为640px高度为480px其中一颗好玉米粒的边界框左上角像素坐标为(160, 120)右下角像素坐标为(320, 240)那么x_center (160 320) / 2 / 640 0.375y_center (120 240) / 2 / 480 0.375width (320 - 160) / 640 0.25height (240 - 120) / 480 0.25对应标签文件内容就是0 0.375 0.375 0.25 0.25这里有一个非常容易踩的坑有些标注工具比如LabelImg的YOLO模式下导出的内容已经是归一化好的但如果你用的是Pascal VOC格式标注转换时忘记除以图片宽高就会导致所有边界框坐标值大于1。YOLOV5训练时会直接忽略这些异常标注最终模型什么都学不到。2.4 训练集和验证集划分脚本为了保证每次划分结果一致而且验证集和训练集互不重叠我建议写一个简单的Python脚本自动划分而不是手动拖拽文件夹。以下是我使用的脚本按91比例划分数据集import os import random import shutil random.seed(42) source_images ./raw_images target_base ./corn_detection train_image_dir os.path.join(target_base, train, images) val_image_dir os.path.join(target_base, val, images) train_label_dir os.path.join(target_base, train, labels) val_label_dir os.path.join(target_base, val, labels) for d in [train_image_dir, val_image_dir, train_label_dir, val_label_dir]: os.makedirs(d, exist_okTrue) all_images [f for f in os.listdir(source_images) if f.endswith(.jpg)] random.shuffle(all_images) val_count max(1, int(len(all_images) * 0.1)) val_images all_images[:val_count] train_images all_images[val_count:] def move_files(image_list, src_img_dir, dst_img_dir, dst_label_dir): for img_name in image_list: shutil.copy(os.path.join(src_img_dir, img_name), os.path.join(dst_img_dir, img_name)) label_name img_name.replace(.jpg, .txt) label_path os.path.join(src_img_dir.replace(images, labels), label_name) if os.path.exists(label_path): shutil.copy(label_path, os.path.join(dst_label_dir, label_name)) # 需要保证 raw_images 同级目录下有 labels 文件夹存放对应标签 move_files(train_images, source_images, train_image_dir, train_label_dir) move_files(val_images, source_images, val_image_dir, val_label_dir) print(f训练集图片数: {len(train_images)}) print(f验证集图片数: {len(val_images)})这个脚本最大的好处是可以反复执行而不改变划分结果seed固定而且复制而非移动文件避免操作失误导致原始数据丢失。划分完成后还应该顺手统计一下训练集和验证集中每一类别的目标数量确保坏粒样本在两个集合中都有足够多的分布。3. 玉米粒图像采集与标注实操笔记3.1 采集设备和环境布置玉米粒检测数据集的图片质量决定了标注效率和模型上限。我实测下来手机摄像头1200万像素以上在光线充足的情况下完全够用但不建议在自然光下直接拍摄因为不同时间段色温差异很大会造成同一批玉米粒在不同图片中颜色明显不一致模型很容易把色偏当特征学进去。建议搭一个简单的拍摄箱用不透光的纸箱内部贴白色或浅灰色背景纸顶部开孔放置LED灯源色温固定在4000K到5000K之间保证光线均匀。拍摄时手机固定在三脚架上镜头垂直向下对准玉米粒摆放区域。每次拍摄时将玉米粒随机撒布不要刻意排列整齐控制在画面中占60%到80%面积留出适当边距。还有一个细节每拍完一批稍微搅动一下玉米粒再拍下一张保证数据多样性。同一批玉米粒如果不搅动只是换个角度拍摄模型学到的是背景和布局特征而不是玉米粒本身的特征泛化能力会大打折扣。3.2 标注工具选择与标注策略标注工具我推荐用LabelImg开源免费支持Pascal VOC和YOLO两种格式导出而且操作非常简单。直接用下面的命令安装pip install labelImg启动后在PascalVOC模式下标注完成一张图后保存为XML后续再用脚本统一转换成YOLO格式。为什么不直接在YOLO模式下标注因为YOLO模式的标签文件是TXT一旦标错了想修改没有很好的可视化检查工具。而VOC格式可以随时重新导入LabelImg中检查和修正。标注时有几个实操要点边界框尽量紧贴目标边缘不要留太多余白。玉米粒是小目标框稍微大一点IOU的计算就明显偏低影响模型收敛。遮挡严重的玉米粒不要标。如果一颗玉米粒被另一颗遮挡超过30%标注出来的边界框带有很强的不确定性反而会干扰训练。宁可少标一个目标也不要标一个不准确的框。坏粒的特征要多样化。霉变的程度有轻有重标注时要覆盖各种严重等级的坏粒而不是只标那些明显发黑腐烂的。否则模型只能学会识别严重霉变轻微霉变仍然会漏检。3.3 数据增强的必要性玉米粒检测的数据量通常不会特别大我整理完大概也就1000到2000张图片。如果不做数据增强模型很容易过拟合。YOLOV5内置了丰富的数据增强策略包括马赛克增强Mosaic、随机仿射变换、HSV色域变换等这些在训练时默认开启不需要额外处理。但从个人经验来看对于玉米粒这种小目标密集场景Mosaic增强帮助非常大。Mosaic把4张训练图片随机拼接成1张相当于变相增大了batch size而且由于拼接时图片尺寸缩小模型能接触到更多小尺寸目标。我实测过同样数据量下开启Mosaic训练的模型对小目标玉米粒的AP值比不开启高出5到8个百分点。不过Mosaic增强在训练后期也有副作用拼接后的图片里目标尺寸被压缩和真实场景分布不一致容易导致模型last epochs的验证精度波动。YOLOV5从v5.0版本开始支持关闭Mosaic的开关。我的做法是前150个epoch开启Mosaic最后30个epoch关闭让模型在接近真实分布的数据上做微调。4. 使用YOLOV5训练玉米粒检测模型完整流程4.1 环境安装与目录准备YOLOV5的安装非常简单。我推荐用conda创建一个干净的虚拟环境避免和已有项目依赖冲突conda create -n yolov5 python3.8 conda activate yolov5 git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt严格来说没有pytorch基础的话需要先安装对应CUDA版本的PyTorch。我建议按照PyTorch官网的命令来安装不要直接用requirements.txt里默认安装CPU版本。GPU训练和CPU训练的速度差距至少20倍1000张图片的训练量GPU十几分钟就完事CPU可能要跑一晚上。训练前把数据集放到yolov5项目目录下确保相对路径正确yolov5/ ├── corn_detection/ │ ├── data.yaml │ ├── train/ │ └── val/ ├── train.py ├── detect.py └── ...4.2 模型选型与训练参数配置YOLOV5提供了n、s、m、l、x五个不同规模的模型对于玉米粒检测这种2类别任务我强烈建议先用yolov5s.pt预训练权重性价比最高。yolov5n速度更快但精度稍微逊色m及以上的模型在小数据集上容易过拟合而且推理速度慢在嵌入式设备上部署时帧率跟不上。训练命令如下python train.py \ --data corn_detection/data.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 200 \ --workers 8 \ --device 0几个关键参数的说明--img 640输入图片分辨率。玉米粒是小目标分辨率低了特征会丢失640是兼顾速度和精度的选择。如果显存充足可以尝试768或896通常mAP会有所提升。--batch 16显存允许的情况下尽量调大。batch size太小会导致BN层统计量不稳定训练震荡。--epochs 200数据集规模小时训练轮次要适当增加。我建议使用YOLOV5自带的早停机制Early Stopping当验证集指标连续50个epoch没有提升时自动停止训练既能避免过拟合又能节省时间。训练过程中可以用tensorboard --logdir runs实时监控训练曲线。重点看train/box_loss、train/cls_loss和val/box_loss、val/cls_loss这几条曲线。如果训练损失持续下降但验证损失在某个点后开始反弹说明已经过拟合应该提前停止如果两者都迟迟不降八成是数据集标注有问题或者学习率设置不合理。4.3 验证与评估指标解读训练结束后YOLOV5会在runs/train/目录下保存训练结果和权重文件。其中weights/best.pt是验证集表现最好的模型weights/last.pt是最后一个epoch的模型实际部署推荐使用best.pt。使用val.py可以单独评估模型在验证集上的表现python val.py \ --data corn_detection/data.yaml \ --weights runs/train/exp/weights/best.pt \ --img 640 \ --task val评估输出包含每个类别的Precision精确率、Recall召回率和mAP0.5、mAP0.5:0.95。对于玉米粒好坏检测场景我建议重点关注Recall召回率。原因很现实坏粒漏检的代价远高于好粒误检。一颗坏粒混入好粒中可能导致整批粮食验收不合格而好粒被误判为坏粒最多只是人工复检一下。所以在训练时可以适当降低置信度阈值优先保证召回率把“疑似坏粒”都标出来交给人工确认。4.4 用训练好的模型跑玉米粒推理模型训练完成后可以用detect.py跑推理验证实际效果python detect.py \ --weights runs/train/exp/weights/best.pt \ --source test_images/ \ --img 640 \ --conf 0.25 \ --save-txt \ --save-conf其中--conf 0.25是置信度阈值低于这个值的目标会被过滤掉。对于玉米粒坏粒检测场景我建议把这个阈值调低到0.15甚至0.1宁可多检出一些候选框也不要漏掉真正的坏粒。输出结果会保存在runs/detect/目录下同时可以用--save-txt保存检测结果的TXT文件方便后续做批量统计。5. 常见问题与排错实录5.1 数据集加载时报错 images not found现象训练启动后报错提示找不到图片或者标签文件不匹配。排查思路这个问题的根源99%是路径配置错误。YOLOV5的train.py在读取data.yaml中的路径时使用的是相对路径相对于当前执行目录。如果你在某个子目录下执行训练命令路径就会失效。我的建议是data.yaml中统一使用绝对路径或者确保执行训练命令时当前目录就在yolov5项目根目录下。另外还要检查train和val指向的是images目录而不是labels目录这个非常容易写反。快速自查命令ls corn_detection/train/images | wc -l ls corn_detection/train/labels | wc -l如果图片数和标签数不一致说明有图片没有对应的标注文件需要补标或删除这些图片。5.2 训练Loss不降或降得很慢现象刚开始训练时Loss就不下降或者降到一个平台期后停滞不动。排查思路这个问题的原因是多方面的。先用小步快跑的方式排查把--epochs设为5--batch设为2在单张图片上跑通整个流程确认数据读取、标签加载、前向传播都没有问题。如果小规模能跑通再恢复完整配置慢慢调。如果训练Loss一直高居不下重点检查标签文件的类别ID是否超出了nc的范围。比如nc: 2但标签文件里出现了类别ID为2的标注合法ID只能是0和1。这种错误在数据量大的时候非常隐蔽模型训练时会忽略这些非法标注导致有效训练数据减少。可以用下面的Python脚本快速检查整个数据集的标签合法性import os label_dirs [./corn_detection/train/labels, ./corn_detection/val/labels] for label_dir in label_dirs: for label_file in os.listdir(label_dir): with open(os.path.join(label_dir, label_file), r) as f: lines f.readlines() for line in lines: parts line.strip().split() if len(parts) ! 5: print(f格式错误: {label_file}: {line}) class_id int(parts[0]) if not (0 class_id 2): print(f类别ID越界: {label_file}: {line})5.3 小目标漏检严重现象验证集mAP还算正常但实际应用时远处的玉米粒或者密集堆叠的玉米粒经常检测不到。排查思路玉米粒属于小目标漏检是常见问题可以从三个方向入手解决提高输入分辨率。--img从640提高到896或1024小目标在特征图中的像素占比会明显增大模型更容易捕捉到细节特征。代价是训练和推理时间变长、显存占用增加。使用更深的模型。从yolov5s升级到yolov5m或yolov5l模型容量增大后能学到更细粒度的特征。但如果数据集本身不大少于1000张升级模型反而容易过拟合需要配合更多的数据增强。增加小目标样本的采样权重。YOLOV5支持--multi-scale参数训练时随机缩放输入图片尺寸相当于变相对小目标样本做了过采样。实际上我在玉米粒检测项目中最有效的方案是提高输入分辨率到896配合降低置信度阈值后坏粒召回率从82%提升到了93%。如果还是达不到要求就考虑用SAHI这类切图推理工具把大图切成小块分别检测再合并结果对小目标场景的提升非常显著。5.4 训练集与验证集类别分布不均衡现象训练完成后模型对bad类别的检测效果差bad类别的Recall明显低于good类别。原因分析玉米粒自然状态下坏粒的比例远低于好粒。如果标注时没有刻意收集坏粒样本数据集中bad类别的目标数量可能只有good类别的十分之一。模型在训练过程中由于bad类别样本太少梯度更新对bad类别的权重调整不足最终导致坏粒检测率低。解决方案一是补充采集坏粒样本可以故意在玉米粒中混入不同霉变程度的坏粒再拍摄二是对已有坏粒样本做离线增强旋转、翻转、亮度调整等增加bad类别的样本数量三是使用YOLOV5的类别权重功能在损失函数中给样本少的类别更高的权重。具体做法是在data.yaml中添加weight: [0.3, 0.7]这个参数会在计算分类损失时对bad类别的错误给予更高的惩罚促使模型更加关注坏粒特征。6. 从数据集到实际部署的几个扩展方向6.1 模型压缩与嵌入式部署如果你打算把训练好的玉米粒检测模型部署到嵌入式设备或者移动端就需要考虑模型压缩。YOLOV5官方提供模型剪枝和量化工具其中最简单有效的做法是int8量化。在GPU上训练好的FP32模型通过TensorRT或OpenVINO转换成int8精度后模型体积可以缩小到原来的四分之一推理速度提升2到3倍精度损失通常控制在2%以内对于玉米粒这种非极端精度要求的场景完全够用。6.2 与硬件联动实现自动分选数据集和模型只是第一步实际生产环境中的玉米粒分选系统需要把检测结果和硬件执行机构联动起来。典型方案是工业相机拍照后推理程序在几十毫秒内完成目标检测然后把坏粒的坐标信息通过串口或以太网发送给PLCPLC控制高速气阀将坏粒吹出。这套系统中检测模型的推理延迟是核心指标所以模型选型和部署优化非常重要。YOLOV5s在Jetson Orin Nano等边缘设备上可以轻松跑到30FPS以上满足大多数分选场景的需求。6.3 持续迭代数据集的必要性我第一次做玉米粒数据集时模型在验证集上表现很好但部署到客户现场后发现漏检率明显上升。原因是因为现场玉米粒的品种、水分含量、霉变类型和训练数据存在差异。这说明做成标准格式的数据集也需要持续迭代把现场运行中漏检或者误检的图片定期收集回来重新标注后增量训练模型的效果才能稳步提升。目标检测模型的落地数据集的质量永远比模型结构更重要。在我整理玉米粒好坏检测数据集的过程中最重要的体会是不要把时间花在纠结模型选型上yolov5s足够应对大多数场景真正决定检测效果的是数据采集是否规范、标注是否准确、划分是否合理。只要把这几件事做扎实了哪怕只用一个中等规模的数据集也能训练出满足实际需求的检测模型。本文还有配套的精品资源点击获取

相关新闻

最新新闻

LM358DT原产地证书:判定逻辑、证书类型与报关优惠全解析

LM358DT原产地证书:判定逻辑、证书类型与报关优惠全解析

最近又被客户追着要LM358DT的原产地证书,说这批货在进口清关时被海关要求补充原产地证明,否则要按最高税率暂估。这种场景在电子元器件行业里太常见了,尤其是负责进口采购、报关或者供应链的朋友,几乎每个月都要跟这张纸打交道。L…

2026/8/30 5:13:00
Delphi 12.3下dOPC Client Toolkit源码实战:OPC DA客户端开发全解析

Delphi 12.3下dOPC Client Toolkit源码实战:OPC DA客户端开发全解析

简介:本资源是面向Delphi中高级开发者的专业级OPC客户端开发套件,专为在Delphi 12.3环境下构建工业自动化数据采集与监控系统而设计。它解决了OPC UA/DA协议接入复杂、接口封装冗余、调试门槛高等实际开发痛点,适用于SCADA系统集成、设备数据…

2026/8/30 5:13:00
Nucleo-WBA25CE1实战:BLE Direct Test Mode射频测试全流程指南

Nucleo-WBA25CE1实战:BLE Direct Test Mode射频测试全流程指南

做带蓝牙低功耗功能的产品,拿到Nucleo-WBA25CE1这块板子之后想确认射频性能,第一件正经事就是把Direct Test Mode跑通。这步不做,后面什么发射功率、接收灵敏度、频偏校准全是空谈。DTM说白了就是把协议栈绕过去,让射频前端直接按…

2026/8/30 5:13:00
【AI 业务流架构师】06-Agent记忆系统设计:四层记忆架构与长期上下文持久化

【AI 业务流架构师】06-Agent记忆系统设计:四层记忆架构与长期上下文持久化

Agent 记忆系统设计:四层记忆架构与长期上下文持久化 引言 让 Agent 跨会话"记住"用户,是几乎所有 AI 助理产品的核心诉求,也是最容易做糊的一环。很多产品的做法是把记忆塞进云端黑盒:用户既看不到 Agent 记了什么&…

2026/8/30 5:13:00
Babelbird 智能文件协作平台实战:版本管理与多维权限体系详解

Babelbird 智能文件协作平台实战:版本管理与多维权限体系详解

Babelbird 智能文件协作平台实战:版本管理与多维权限体系详解 工程团队日常最头疼的几件事:图纸改了七八版最后不知道哪版是终稿、跨部门文件传来传去权限混乱、离职员工带走关键资料。对于 50 人以上的研发或设计团队,文件管理的复杂度会指数…

2026/8/30 5:13:00
STM32复位释放瞬间IO电平异常:原因实测与避坑指南

STM32复位释放瞬间IO电平异常:原因实测与避坑指南

做STM32开发,最怕遇到这种场面:给板子一上电,继电器“啪”地吸合一下,电机“嗡”地转一瞬,LCD闪一下白屏,然后一切恢复正常。程序明明什么都没做,为什么硬件这么“自作主张”?其实问…

2026/8/30 5:07:59