首页 / 资讯中心 / 文章详情

基于YOLOv11的花生种子霉变检测系统设计与实现

基于YOLOv11的花生种子霉变检测系统设计与实现 ★ FEATURED ARTICLE
其实我很早就想做一套能真正落地的深度学习质检系统了。目标检测的教程一搜一大把但大多数都停在“训练完看个mAP”就结束了。真正放到实际场景里用户要的不是一个权重文件而是一个能登录、能选图、能出结果、能保存记录的完整工具。这个花生种子霉变检测系统就是这么来的基于YOLOv11做目标检测配合自建的花生种子数据集外层用Python把模型推理、UI界面、登录注册全部串起来最终交付的是一个开箱即用的桌面应用。这套东西适合谁一是做农业生产智能化或食品质量检测相关课题的朋友需要一个完整的项目范式做参考二是刚学完YOLO系列、想知道怎么把模型封装成产品的新手三是需要快速搭建“深度学习界面”演示系统的开发者。整个项目从数据准备、模型训练再到界面封装链路完整踩坑不少这篇就把每一环的细节和教训都写出来。1. 项目整体思路与选型分析1.1 先理清需求检测系统到底要做什么很多人一上来就急着跑模型其实第一步应该是把需求拆明白。这个系统的核心任务是给定一张包含花生种子的图像模型能自动找到每一颗花生籽粒的位置并判断它是否发生霉变。注意这里不是做图像分类——不是整张图给一个“好”或“坏”的结论而是要定位出图像中每一个目标标出类别和位置。这就决定了技术路线必须走目标检测不能简单套分类模型。再往下拆系统需要有三个层次的功能底层是训练好的检测模型中间层是调用模型做推理的后端逻辑最外层是用户能直接操作的可视化界面。再加上登录注册整个系统就是一个mini版的SaaS形态——先管住用户身份再提供服务。这个拆解过程很重要。如果你在做一个项目或者毕设先把你做的东西的功能边界画清楚哪些是必要的、哪些是凑数的想明白这个后边的开发就是按图索骥。1.2 为什么最终选了YOLOv11选检测框架的时候我认真对比过几代模型。老牌的Faster R-CNN精度是有保障的但推理速度慢而且部署复杂尤其是往UI里集成的时候检测一张图要一两秒体验非常糟糕。SSD倒是快但小目标检测能力偏弱花生霉变通常表现为斑点状的局部色泽变化很多时候目标面积并不大SSD在这种场景下容易漏检。YOLO系列是速度与精度的平衡点。从v5到v8到v11迭代这么多版本生态已经非常成熟了。到了v11这一代C3k2模块替代了早期的C3结构注意力机制也做了升级整体在保持高帧率的同时小目标检测能力有明显提升。对花生种子这种形态规则但细节差异很大的目标来说YOLOv11的特征提取能力够用而且它的训练工具链非常完善从标注数据到训练再到导出的全流程都有成熟配套。还有一个很现实的因素社区资料丰富。遇到问题上网查基本都能找到参考这一点对于做项目的人来说太重要了。很多冷门框架精度再好出了问题查一整天都找不到解决方案分分钟劝退。1.3 整体技术架构设计系统整体分为三大块模型端、服务端、客户端。模型端就是YOLOv11的权重文件这是整个系统的核心资产。训练好之后导出为适合推理的格式保证加载速度快、内存占用可控。服务端指的是推理逻辑也就是把图像传给模型、执行推理、解析输出结果、做后处理的这一段代码。客户端就是UI层接受用户的操作指令调用服务端逻辑把结果展示出来。登录注册模块独立出来用本地文件存用户信息不走网络数据库。好处是部署零依赖坏处是只能本机使用、无法做真正的账号体系但对于演示和课题来说完全够用而且实现起来干净利落。2. 数据集构建与标注规范2.1 数据采集比想象中费劲得多做花生种子霉变检测第一个卡住我的竟然不是模型而是数据。网上公开的花生霉变检测数据集几乎没有食品安全类的公开数据集本身就不多更别说细到“花生种子的霉变目标检测”这种程度。所以整个数据集必须自己动手建。采集过程分两路走。第一路是拍真实样品去农贸市场买不同批次的带壳花生和花生米在自然光和台灯下、白底和黑底背景下用手机加微距镜头拍摄。霉变的花生有些是表面长绿毛或白毛的有些是颜色变深发黄的有些是局部有霉斑的这些都要尽量覆盖。第二路是网络抓图补充从公开图片平台搜花生、发霉花生、坏花生籽粒等关键词人工筛选可用的图片。最终我整理出原始图片大概1800多张。注意这个数量不算多但对于单类或双类检测来说已经能起步了。如果你要做更稳定的工业级模型建议至少攒到5000张以上。2.2 标注细节类别的定义直接影响模型上限标注工具我用的是LabelImg输出PASCAL VOC格式的XML再转成YOLO需要的txt格式。流程是先用LabelImg打开图片框选目标选择类别保存。这里有个很重要的经验类别怎么定义直接决定了模型的学习目标。我一开始图省事只标了霉变花生moldy这一个类正常花生不标想着只检测异常目标就行了。结果训练出来的模型表现很飘因为模型没有“正常”的概念阈值稍低就把正常花生也框出来当成霉变阈值一高又漏检。后来我改成标注两个类正常花生normal和霉变花生moldy。这样模型在训练时能明确区分两类特征的边界推理时也可以同时输出两类目标。从实际效果看mAP50从单类时的0.71涨到了双类时的0.89提升非常明显。2.3 数据增强与划分策略YOLOv11训练框架里内置了丰富的数据增强方式比如HSV色彩空间扰动、随机翻转、缩放、平移等。理论上开箱即用但实际要把增强参数调对。我的配置经验是mosaic增强在训练前期打开能大幅提升模型对多目标和小目标的适应能力但训练最后几十个epoch建议关掉因为mosaic生成的合成图跟真实分布有差异一直开着会导致最终收敛不够精准。HSV增强适度即可饱和度偏移不要超过0.5否则花生的颜色会被拉得完全不自然反而损害检测精度。数据集划分上我按8:1:1的比例拆成训练集、验证集、测试集。注意一定要打乱顺序确保同一场景拍摄的相似图片不会集中出现在某一个集合里否则验证集失真训练出来的指标好看但实际泛化很差。3. YOLOv11模型训练全流程3.1 环境适配版本匹配是第一个坑YOLOv11对Python版本和依赖有明确要求。我的环境是Python 3.10CUDA 11.8PyTorch 2.0.1以上版本都兼容。这里提醒一句如果你用的是Windows系统安装PyTorch的时候一定要选对应CUDA版本的wheel包用默认的CPU版本训起来会让人怀疑人生。YOLOv11的源码在GitHub上直接克隆下来安装依赖时用requirements.txt一步到位。除此之外还需要单独安装ultralytics这个核心库它统一了数据加载、模型构建、训练流程这些逻辑。我训练用的是单张显卡显存8Gbatch size设为16输入尺寸640x640。如果你是用的云端GPU训练配置还可以往上推。先把预训练权重YOLOv11n.pt和yolov11s.pt下载好训练时会自动加载通用特征大幅减少收敛时间。3.2 训练参数的认识与调优逻辑很多人习惯直接跑默认参数但我建议至少把这些关键参数搞清楚。以下几个参数基本决定了模型最终质量epochs、batch、imgsz、lr0、patience。我的训练设置是epochs200batch16imgsz640。学习率初始值lr00.01配合默认的余弦退火策略。patience设为30意思是连续30个epoch验证集指标不提升就早停防过拟合、省时间。训练过程中每10个epoch会在验证集上跑一次mAP评估指标变化一目了然。在调参的过程中我试过把imgsz提到960检测精度有小幅提升但推理速度明显下降帧率低了近一半。对于花生种子检测这种场景640足够用了。结论是不要盲目追求高分辨率要和你的实际使用环境匹配。3.3 训练过程状态解读训练日志里最有价值的三个指标box_loss、cls_loss、mAP50。box_loss是边界框回归损失代表预测框和真实框的差距cls_loss是分类损失代表类别预测的准确程度。正常情况下这两者应该持续下降并趋于平稳。mAP50是IoU阈值取0.5时的平均精度均值是衡量检测模型最直观的指标。我吃了一次亏第一次训练到第20轮的时候box_loss不降反升mAP一直趴着不动。排查了半天发现是数据集在标注的时候很多霉变花生框得太紧边界压住了霉变斑纹的边缘导致完好的籽粒和霉变起始特征产生了重叠。后来重新过了一遍标注把框往外扩了两三个像素问题就解了。所以当你看到loss异常的时候优先检查数据不要急着调参数。4. 检测效果评估与模型优化4.1 精度判定的标准训练完成后评估模型光看loss曲线不够要看验证集上的具体指标。我最终拿到的结果是mAP500.89mAP50-950.63precision0.91recall0.85。这个水平在当下的机器学习任务里属于中上考虑到数据量和类别复杂度已经能满足检测需求。mAP50容易理解就是所有类别的平均精度。mAP50-95是IoU从0.5变化到0.95取多个阈值后计算的平均值这个指标更严苛也能更真实反映模型定位的精细程度。一般来说mAP50和mAP50-95的差距如果超过0.3说明定位还不够准可以尝试增大输入分辨率或优化边框回归损失。分类别看一眼normal类的AP是0.93moldy类的AP是0.85。霉变类AP偏低的原因是霉变花生形态多样有些早期霉变颜色变化不明显跟正常花生差异很小误判率偏高。这也是当前整个检测系统的瓶颈。4.2 优化方向与实践验证针对霉变类AP偏低的问题我尝试了几种优化方案。第一调整类别权重。给moldy类加更高的loss权重相当于强行让模型对霉变类样本更敏感。做法是在数据配置文件中给class_weights参数赋值例如normal0.6、moldy1.2。这样在分类损失中霉变类贡献的梯度更大模型会偏向提高对霉变特征的学习。第二增加带标签的难例数据。霉变早期阶段的样本单独标注了一批补充进训练集。增加难例是最直接也最有效的方式新数据训练后霉变类AP从0.85提到了0.88。第三使用训练时的TTA策略。推理时开启测试时增强把原图、翻转图、缩放图分别推理再综合结果。TTA能稳定提升几个点的精度但推理时间会成倍增加所以我的建议是作为离线评估时的参考线上实时检测还是关掉。4.3 推理速度与模型体积速度方面用YOLOv11s作为主体模型时GPU模式下推理一张640x640的图大约耗时12毫秒CPU模式下大约150到250毫秒。放到桌面应用里用户点选图片到出结果基本一秒内能完成体验是可以接受的。模型体积方面YOLOv11s的权重文件约19MB压缩后14MB左右不管是打包还是分发都非常方便。如果你的硬件环境更差可以用YOLOv11n体积只有5MB左右精度下降约3到4个点但推理速度提升接近一倍。我甚至试过用v11n跑树莓派级别的设备也能流畅运行。5. UI界面与登录注册模块设计5.1 UI框架选型与整体布局UI层选型上tkinter是Python自带库语法简单、上手快做小型工具类界面绰绰有余而且打包体积小、跨平台。PyQt5功能更强、控件丰富、视觉效果更好但引入的依赖体积大打包后动辄一两百MB。考虑到这个系统的定位是检测演示与课题交付最终选了PyQt5因为用户对界面观感的要求往往比我们想象的高。整体布局分三个区域。顶部是功能栏包含打开图片、开始检测、保存结果等操作按钮。中间是主显示区左边显示原始图片右边显示检测结果图两边的尺寸在窗口拉伸时能联动缩放。底部是信息栏显示当前检测到的各类数量、单次推理耗时、以及模型加载状态。5.2 登录注册界面的实现逻辑登录注册模块看起来简单但要做到账户安全性、代码结构清晰、扩展性好还是需要仔细设计的。用户信息存储我用了JSON文件。密码用hashlib库的sha256加盐处理不存明文。注册时先判断用户名是否存在——存在则提示换一个不存在则把用户名、加盐后的哈希值、注册时间写入用户文件。登录时读取用户传入的密码做同样的哈希处理和存储的哈希值比对一致则登录成功进入主界面。这里有两个细节值得说。第一是加盐必须做恶意手段很擅长对常见密码做彩虹表碰撞不处理哈希等于裸奔。第二是登录界面关闭时要确保弹窗绑定的事件循环不会卡住主进程。用PyQt5的QDialog来做登录窗体setWindowModality设为Qt.ApplicationModal能确保登录窗口弹出时主界面不可操作逻辑更严谨。5.3 主界面核心检测功能实现检测功能是主界面的核心。用户点击“打开图片”按钮通过QFileDialog弹出文件选择器支持常见的jpg、png、bmp格式。选中之后用QPixmap将图片加载到左侧的QLabel中原始图像不做任何压缩方便后续在保存结果时保留原始分辨率。点击“开始检测”后程序先调用加载好的模型对图片做推理。这里需要注意PyQt5的UI线程不能跑耗时的推理任务否则界面会直接卡死、白屏用户会以为程序崩了。解决办法是用QThread创建子线程把推理逻辑放到worker线程里跑推理结束后通过信号槽机制把结果传回主线程更新界面。检测结果的绘制方面模型输出的目标框坐标、类别和置信度都是归一化格式要先乘回原图宽高。画框时normal类用绿色框显示moldy类用红色框线宽根据原图的尺寸自动缩放避免大图上线条太细看不见。界面右侧还会显示两类目标的统计数字比如“正常花生35颗霉变花生8颗霉变率18.6%”。这个额外功能虽然做起来不难但对实际使用者的决策帮助很大也对整个系统的实用程度有了直观提升。6. 系统集成部署与避坑经验总结6.1 模型加载与推理封装系统实际交付时模型加载的稳定性非常重要。我比较推荐把推理逻辑封装成一个独立的检测器类启动界面时先实例化避免每次检测都重新加载权重。加载时用ultralytics库的YOLO类直接读取权重路径。推理时传入图片路径或ndarray数组通过predict方法设置conf参数控制置信度阈值这个阈值直接影响误报和漏报的平衡。从我的实践来看阈值调到0.35到0.4之间比较合适既能过滤掉大部分低置信度的误检框又不会放过霉变特征不明显的早期样本。推理完成后要从results对象中提取boxes数据和names映射。这个时候要小心不同版本的ultralytics库返回的数据接口可能有差异。因此封装时一定要统一提取逻辑保证后续界面层只依赖固定接口。6.2 打包分发时的注意事项Python项目交付最绕不开的坑就是打包。用PyInstaller打出来的包如果直接打包往往缺少一些依赖文件比如PyQt5的插件、ultralytics的运行配置文件、还有一些模型转换工具的动态库。我的打包方案是用PyInstaller加spec文件的方法重点在hidden imports里把torch、torchvision、ultralytics、cv2等动态导入的模块全部显式列上。还要把项目依赖的资源文件和权重文件一并加入datas保证收到包的机器上不用手动去配模型路径。打包产物是一个exe文件、权重文件、配置文件再加上一个说明文档。第一次打包出来的exe我测试时发现新机器上打开就闪退一查日志是缺少Visual C Redistributable运行库。后来打包时加了--add-data把对应运行库一并打进去这个问题才算彻底解决。6.3 实操中踩过的坑与排查技巧这里把我在这个项目里踩过的几个坑集中整理一下都是翻文档翻到头秃才找到的原因。第一个坑是训练时显存溢出报错。解决方法是降低batch size但减小batch会影响BatchNorm统计效果所以更优的解法是开启gradient accumulation模型优化器每积累多个batch的梯度再做一次更新效果和用大batch几乎一致。第二个坑是推理时中文标签乱码。这是因为Ultralytics库在画框时默认字体不支持中文。解决办法是手动指定中文字体路径在画框前重置预测结果的names和字体设置。不要图省事全程用英文标签代替做交付时用户看到中文界面更舒服。第三个坑是打包后模型加载路径错乱。PyInstaller打包的路径跟源码运行路径不一样直接用相对路径读权重很容易找不到文件。解决方法是运行时统一用sys._MEIPASS或者os.path.dirname(file)动态拼接路径然后把权重文件放到约定目录程序启动时主动检查文件是否存在并给出明确提示。第四个坑是霉变类别在验证集上AP偏低但训练集很高典型的过拟合信号。当时我数据量小、增强又保守模型把训练集的细节当成通用特征硬记下来了。后来加大数据增强力度同时补充了一些真实新样本过拟合情况明显改善。6.4 系统扩展方向建议做完这一套花生种子霉变检测系统之后我发现这个架构完全可以推广到其他农产品质检场景。比如大米发黄检测、玉米霉变检测、水果表面缺陷检测只需要替换数据集和重新训练模型UI层和登录注册模块几乎不用动。还可以扩展的方向包括把检测结果自动写入Excel报表并导出做到检测记录的数字化管理把模型部署到服务端通过一个轻量级的接口让多个客户端同时检测或者引入硬件接入USB摄像头做实时流式检测这个功能离工厂产线的需求更近一步。我在实际使用中发现如果拿这套系统给一个小型收购站用一个工作日要检测两千多张花生图片同时还需要把每天霉变率数据留存下来。后续版本可以把统计模块做厚一点把每日、每周的霉变率趋势以图表的形式画出来。这样的系统就从一个检测工具升级成了质检记录分析平台实用性会再上一个台阶。
阅读完成 · 觉得有帮助?
咨询建站