ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

YOLOv11草莓成熟度检测:从数据集构建到边缘部署全流程

YOLOv11草莓成熟度检测:从数据集构建到边缘部署全流程 1. 草莓成熟度检测到底在解决什么问题草莓这种水果有个特点就是同一株上的果实成熟时间不一致有的已经红透可以采摘有的还是青白色需要再等几天。传统做法是靠人工一颗一颗看判断颜色、大小、光泽度然后决定采不采。问题是人工判断标准不统一今天光线好可能觉得这颗熟了明天阴天可能同样的果子就被判定为没熟。而且草莓皮薄反复翻看容易造成机械损伤损耗率上去了果农的收益就下来了。我最早接触这个方向是因为一个做设施农业的朋友找我聊他想在大棚里装一套自动巡检设备让摄像头沿着轨道走一圈自动识别哪些草莓可以摘了。他当时的需求很朴素别跟我讲什么高深算法就告诉我能不能用现成的模型拿我棚里的照片训一下然后跑在边缘设备上实时框出成熟果实就行。这个需求听起来简单但真正落地的时候从数据集构建到模型选型再到部署优化每一步都有坑。YOLOv11 草莓成熟度检测系统本质上就是一套基于目标检测算法的视觉识别方案。它的核心任务是把草莓图像中的果实框出来并且判断它处于哪个成熟阶段——通常分为未熟、半熟、成熟三个等级。这套系统能做什么简单说给一张草莓大棚的图片或者一段视频流它能告诉你画面里有多少颗草莓、每颗在哪里、分别是什么成熟度。适合谁来参考做智慧农业的开发者、农业院校做课题的学生、想用视觉方案替代人工分拣的种植户以及任何对 YOLOv11 实战落地感兴趣的技术人员。这里要特别说明一点成熟度检测和普通的草莓检测是两回事。普通检测只要框出草莓就行成熟度检测要求模型能区分颜色渐变过程中的细微差异。青白色、浅粉色、鲜红色、暗红色这些颜色在 RGB 空间里差距不大但在 HSV 空间里色调值差异明显。所以数据集标注的时候分类标准必须提前定死不能今天按这个标准标明天换个人又按另一个标准标否则模型学出来的边界是模糊的。注意成熟度等级划分没有绝对统一的标准不同品种、不同用途鲜食、加工、运输对成熟度的要求不一样。建议在项目开始前就和最终用户确认好分级规则最好用色卡或者标准比色板作为参照。2. 数据集构建从拍照到标注的完整流程2.1 数据采集的场地与光照策略数据集的质量直接决定模型的上限这句话在农业视觉项目里尤其成立。草莓大棚的光照条件非常复杂晴天中午棚内光照强度可能超过 80000 lux阴天或者傍晚可能只有 2000 lux 左右。如果采集数据时只在一个时间段拍模型到了实际部署时遇到其他光照条件就会崩。我的做法是分三个时段采集上午 9 点到 11 点、下午 1 点到 3 点、傍晚 5 点到 6 点半。每个时段至少采集 200 张原始图像覆盖顺光、逆光、侧光三种角度。设备用普通手机或者工业相机都行但要注意关闭自动白平衡和自动曝光因为自动模式会让同一颗草莓在不同照片里呈现不同的颜色这对成熟度分类是致命的干扰。采集时还要注意遮挡问题。草莓叶片会遮挡果实有时候只露出一个角。这种样本必须保留因为实际部署时摄像头不可能每次都拍到完整果实。我见过有人为了标注方便专门把叶片拨开再拍结果模型在真实场景里遇到遮挡就完全失效。2.2 标注规范与分类边界定义标注工具用 LabelImg 或者 CVAT 都可以格式统一用 YOLO 格式的 txt 文件。关键不在于工具而在于分类边界的定义。我建议用 HSV 色彩空间来辅助判断而不是单纯靠肉眼。具体操作是用 OpenCV 把图像转到 HSV 空间然后取果实表面三个不同位置的点读取 H 通道的值。H 值在 0 到 10 之间通常对应红色成熟10 到 25 对应橙红半熟25 到 40 对应青白未熟。当然这只是一个参考范围实际品种不同会有偏移。用这个方法先做一轮预分类然后再人工复核能大幅提高标注一致性。标注的时候有个细节容易被忽略边界框要尽量贴合果实轮廓但不要切掉果尖和果蒂。果蒂部分的颜色有时候和果实主体不一致如果框得太紧模型学到的特征会不完整。我一般建议边界框比果实实际轮廓外扩 3 到 5 个像素。2.3 数据增强与类别平衡草莓成熟度数据集天然存在类别不平衡问题。大棚里同一时间成熟果实通常只占 20% 到 30%大部分是未熟或者半熟。如果直接拿这种数据去训练模型会倾向于把什么都预测成未熟因为这样准确率看起来最高。解决办法有两个层面。第一个是在采集阶段就有意识地多拍成熟果实比如专门找已经红透的果子拍特写。第二个是在训练阶段用数据增强来平衡但要注意增强方式的选择。对于成熟度分类任务颜色抖动Color Jitter要慎用因为颜色是判断成熟度的核心特征你把红色抖成橙色标签就错了。可以用的增强包括随机水平翻转、随机裁剪、轻微旋转正负 15 度以内、马赛克增强。亮度调整可以小幅度做但对比度调整要谨慎。我自己的做法是对成熟类别做 2 倍过采样对半熟类别做 1.5 倍过采样未熟类别保持原样。然后在训练时用类别权重来进一步平衡损失函数。3. YOLOv11 模型选型与训练策略3.1 为什么选 YOLOv11 而不是其他版本YOLO 系列到 v11 这个版本在精度和速度的平衡上已经做得相当成熟了。相比 v8v11 在骨干网络里引入了更高效的注意力机制对小目标的检测能力有提升。草莓在图像里通常只占几十个像素属于典型小目标这一点很关键。另一个考虑是部署生态。YOLOv11 支持导出 ONNX、TensorRT、OpenVINO 等多种格式在 Jetson 系列边缘设备上的部署方案很成熟。我试过在 Jetson Nano 上跑 YOLOv11n输入 640x640FP16 量化后推理速度能到 15 到 20 FPS对于大棚巡检这种不需要极高帧率的场景完全够用。模型尺寸选择上如果只是做草莓检测n 版本nano通常就够了。s 版本small精度会高一些但速度下降明显。m 版本以上就不建议了边缘设备跑不动服务器部署又没必要。3.2 训练参数配置与调优过程训练环境用 PyTorch 加 Ultralytics 框架这是目前最省事的方案。数据集配置文件 data.yaml 要写清楚训练集、验证集路径和类别名称。类别名称建议用英文比如 unripe、semi_ripe、ripe避免中文编码问题。关键训练参数如下参数建议值说明epochs150-200草莓数据集通常 2000 张左右150 轮足够收敛batch16根据显存调整8G 显存用 164G 用 8imgsz640输入分辨率小目标多可以提到 800lr00.01初始学习率lrf0.01最终学习率系数momentum0.937动量weight_decay0.0005权重衰减warmup_epochs3预热轮数mosaic1.0马赛克增强概率mixup0.1混合增强不要太高训练过程中要盯着验证集的 mAP50 和 mAP50-95。如果 mAP50 在 100 轮之后还在涨说明可以继续训。如果连续 20 轮不涨就可以停了。我遇到过一种情况训练集 loss 一直在降但验证集 mAP 不涨反跌这是典型过拟合。解决办法是增加数据增强强度或者减少模型参数量。3.3 小目标检测的针对性优化草莓在 640 分辨率下可能只有 30x30 像素属于小目标。YOLOv11 默认的检测头对小目标已经做了一些优化但还可以进一步调整。第一个手段是提高输入分辨率。把 imgsz 从 640 提到 800 甚至 1024小目标的像素面积会增大检测效果明显提升。代价是推理速度下降需要根据实际硬件权衡。第二个手段是调整 anchor 尺寸。虽然 YOLOv11 是 anchor-free 的但特征金字塔的层级分配会影响小目标检测。可以在训练配置里增加 P2 层的输出专门检测极小目标。不过这会增加计算量建议先试默认配置效果不够再改。第三个手段是切片推理。如果图像分辨率很高比如 4000x3000直接缩放到 640 会丢失大量细节。可以把大图切成 640x640 的小块分别推理再合并结果。这个方法在遥感图像检测里很常用草莓大棚巡检也可以用。4. 从训练到部署的完整实操链路4.1 模型导出与格式转换训练完成后Ultralytics 框架会保存 best.pt 和 last.pt 两个权重文件。best.pt 是验证集表现最好的部署时用这个。导出 ONNX 的命令很简单yolo export modelbest.pt formatonnx imgsz640 opset12 simplifyTrueopset 版本建议用 12兼容性最好。simplify 参数会调用 onnx-simplifier 做图优化去掉冗余节点推理速度能提升 10% 到 15%。如果部署到 Jetson 设备建议直接导出 TensorRT 引擎yolo export modelbest.pt formatengine imgsz640 halfTrue device0halfTrue 表示 FP16 量化精度损失很小速度提升明显。注意 TensorRT 引擎是跟设备绑定的在 A 设备上导出的引擎不能直接拿到 B 设备上用必须在目标设备上重新导出。4.2 推理代码实现与结果保存推理脚本的核心逻辑是加载模型、读取图像、前向推理、解析输出、绘制结果。用 Ultralytics 的 Python API 最省事from ultralytics import YOLO import cv2 model YOLO(best.engine) results model.predict(sourcetest.jpg, conf0.5, iou0.45, saveTrue) for r in results: boxes r.boxes for box in boxes: cls_id int(box.cls[0]) conf float(box.conf[0]) xyxy box.xyxy[0].tolist() print(f类别: {model.names[cls_id]}, 置信度: {conf:.2f}, 位置: {xyxy})conf 阈值建议设 0.5太低会引入大量误检太高会漏掉半熟果实。iou 阈值用 0.45 到 0.5 之间草莓果实之间通常不会严重重叠这个值够用。如果要保存推理结果视频可以用 OpenCV 的 VideoWriter 逐帧写入。注意帧率要和原视频一致否则播放速度会不对。4.3 边缘设备部署的性能调优在 Jetson Nano 上部署时有几个调优点。第一是电源模式Nano 默认是 5W 模式性能受限可以切换到 10W 模式推理速度能提升 30% 左右。命令是sudo nvpmodel -m 0 sudo jetson_clocks第二是内存管理。Nano 只有 4G 内存如果同时跑摄像头采集和模型推理容易爆内存。建议用 GStreamer 管道直接读取摄像头数据避免中间拷贝。第三是推理分辨率。如果 640 跑不到 10 FPS可以降到 416 或者 320。草莓检测对分辨率的要求没有通用目标检测那么高320 分辨率下 mAP 可能只掉 5 个点但速度能翻倍。5. 常见问题排查与避坑经验5.1 模型把未熟草莓误判为成熟怎么办这是最常见的问题根本原因通常是训练数据里成熟样本太少或者标注时把一些边缘样本标错了。排查步骤先看混淆矩阵确认是哪个类别被误判最多。如果是未熟被误判为成熟说明模型对红色特征过度敏感。解决办法增加未熟类别的困难样本特别是那些颜色偏红但实际未熟的品种。有些草莓品种在未熟阶段就带红色条纹这种样本必须大量加入训练集。另外可以在损失函数里给未熟类别更高的权重让模型更关注这个类别的错误。5.2 推理速度达不到实时要求先确认瓶颈在哪里。用time命令测一下纯推理时间如果推理本身就很慢那是模型或硬件问题。如果推理快但整体流程慢那是数据预处理或后处理的问题。模型层面的优化换更小的模型n 版本、降低输入分辨率、做 FP16 或 INT8 量化。数据层面的优化用多线程读取图像、用 GPU 做预处理、避免不必要的图像拷贝。我实测下来Jetson Nano 上 YOLOv11n 加 TensorRT FP16640 分辨率纯推理时间大约 50 到 60 毫秒加上前后处理总共 80 到 100 毫秒也就是 10 到 12 FPS。对于大棚巡检来说够用了但如果要做实时分拣可能需要换 Orin Nano 或者 Xavier NX。5.3 不同大棚之间模型效果差异大这是域适应问题。A 大棚训练出来的模型拿到 B 大棚用光照条件、草莓品种、背景环境都不一样效果下降很正常。解决办法有两个一是在 B 大棚采集少量数据做微调通常 200 到 300 张标注图像就能明显改善二是用风格迁移做数据增强把 A 大棚的图像风格迁移到 B 大棚的光照条件下扩充训练集。提示微调时学习率要设小建议用初始学习率的十分之一训练轮数 30 到 50 轮就够了避免把原来学到的特征覆盖掉。5.4 常见问题速查表问题现象可能原因排查方法解决措施成熟度误判严重类别不平衡看混淆矩阵过采样类别权重小果实漏检分辨率不足可视化特征图提高 imgsz 或加 P2 层推理速度慢模型过大测纯推理时间换 n 版本量化跨棚效果差域偏移对比两棚图像微调风格增强训练不收敛学习率不当看 loss 曲线调 lr0 和 warmup边界框不准标注质量差抽查标注文件重新标注困难样本6. 成熟度检测的延展应用与个人体会这套方案不只适用于草莓。蓝莓、番茄、樱桃、柑橘的成熟度检测技术路线几乎一样只需要重新采集数据和调整分类标准。甚至茶叶嫩芽的采摘等级判断、烟叶烘烤阶段的颜色分级都可以用类似的思路。我在实际项目里最大的体会是数据比模型重要标注规范比数据量重要。见过太多人花大量时间调模型结构结果数据集里一半的标注是错的怎么调都上不去。先把标注规范定好找两个人交叉验证一致性达到 95% 以上再开始训练后面会省很多事。另一个体会是部署环境要提前考虑。训练时用服务器显卡部署时用边缘设备两者算力差距可能是几十倍。如果一开始就按服务器算力设计模型后面移植会很痛苦。建议在选型阶段就拿目标设备跑一下基准测试确认速度能满足需求再往下走。最后分享一个小技巧如果大棚里光照变化剧烈可以在摄像头旁边装一个补光灯用固定光源消除自然光变化的影响。成本很低但能让模型稳定性提升一个档次。这个做法在工业视觉里很常见农业场景同样适用。
返回列表