资讯详情

资讯详情

基于YOLOv5的温室番茄果串检测系统设计与实践

1. 项目概述与核心目标拆解1.1 这是一个什么样的项目我一直在帮某农业智能实验室做一些作物长势监测的视觉算法前段时间接到一个需求针对温室大棚里的番茄不仅要检测出果实还要把一串一串的果串整体识别出来。相比于单果检测果串形态的预测难度要高不少因为番茄果串的特征太不规律了——大小不一、角度各异、密集生长、相互遮挡再加上温室里复杂的光照和叶片遮挡很多常规检测模型在实验室数据集上表现不错一放到真实温室就翻车。这个项目的核心任务是设计并实现一套基于YOLOv5的温室番茄果串检测系统能够对输入图像中的番茄果串进行实时定位与分类。毕业设计、农业AI课题、甚至温室智能化改造项目里这类需求都很常见。如果有人想学习目标检测从数据标注到模型落地的完整流程这个项目也非常适合因为它的数据采集和标注环节很考验对目标定义的理解。系统整体包含数据采集、标注处理、模型训练、后端推理和可视化展示几个模块。我直接把源码整理成了一个完整仓库训练和预测的命令都已封装好拿到之后按说明跑起来就行。为了让这篇文章能真正帮到人我会把整个过程中踩过的坑、调参的心得、数据标注的细节全部写出来。1.2 为什么温室场景比普通场景更难做一开始我有过错觉觉得番茄果串检测不就是多目标检测吗拿YOLOv5默认配置跑一跑精度应该差不到哪里去。实际跑完第一轮实验之后才发现温室场景下的检测难度被低估了。首先温室大棚中光线变化剧烈。晴天正午光照强番茄表面会产生高光反射果串轮廓变得模糊阴天或清晨光线弱暗处的果实和叶子颜色接近边界难以区分夜晚补光灯开启时又会产生偏色。这些光照不确定性直接影响目标特征提取。其次果串的目标定义模糊。单果是一个圆溜溜的红色区域边界清晰标注时只要用框框住就行。但果串是由若干果实和茎杆组成的聚合目标什么时候算一串、两个重叠的果串要不要分开标没有明确规则。如果标注标准不统一模型训练出来的效果会非常不稳定。第三个难题是重叠与遮挡。温室番茄通常每穗挂4~6个果实果串之间挨得近叶片又是遮挡大户。很多目标只有不到一半的可见面积YOLOv5这种基于锚框的方法对这种局部可见目标天然存在漏检问题。因此这个项目的难点并不在用什么模型而在于如何定义目标、如何规范数据、如何在训练策略上针对性调整。我在后面的章节里会逐个展开。2. 环境配置与关键技术选型2.1 YOLOv5版本与依赖环境的确定项目落地时我对比过YOLOv5的v6.0、v7.0和官方最新主线分支。最终选了v6.0版本原因很简单稳定。v7.0之后仓库结构改动比较大很多第三方教程、工具链还没跟上而v6.0的文档和社区案例最多遇到问题基本都能搜到解决方案。在工程化项目中选型求的不是最新而是生态成熟度。依赖环境方面我整理了一套可复现的配置Python 3.8 PyTorch 1.7 torchvision 0.8 CUDA 10.2 / 11.2 opencv-python 4.1 matplotlib 3.2 numpy 1.18推理阶段我建议用PyTorch原生的模型结构配合ONNX导出做加速。训练阶段如果显存不够可以在配置文件中关闭一些不必要的模块后面我会详细说。2.2 硬件配置与性能预期我训练用的是一张12GB显存的显卡实测YOLOv5s输入分辨率640x640时单卡能跑到56左右。番茄果串检测对这种边缘农业场景来说对实时性要求没那么极端生产环境中每秒处理3~5帧完全够用。更大的瓶颈在数据侧而不是模型侧。这里有一个容易忽略的点温室场景下摄像头通常安装在固定机位拍到的图像角度变化很小光照变化却很大。因此推理模型不需要很强的多尺度旋转适应性反而需要很强的光照鲁棒性。这也是后续数据增强策略的出发点。为了给不同预算的使用者提供参考我把硬件方案分成三档档位配置训练能力适用场景入门CPU训练 小数据集仅可微调小模型速度极慢验证流程、学习调试标准8~12GB显存GPU SSDYOLOv5s/yolov5m500张图约3~6小时中小规模温室实验进阶24GB显存GPU 高速存储YOLOv5l/x千张以上数据规模化、多季节覆盖2.3 模型骨架的选择为什么是YOLOv5s很多人一上来就选YOLOv5x觉得模型越大精度越高。但在番茄果串检测这个项目里目标并不算特别小通常占画面面积的十分之一以上所以大模型的提升有限反而明显拖慢推理速度。我实测过YOLOv5s和YOLOv5l在相同验证集上的mAP差距只有1~2个百分点但推理速度差距接近3倍。综合考虑成本和效果最终确定YOLOv5s作为主力模型。如果现场算力允许、且对精度有更高要求可以用YOLOv5m作为备选只需在训练命令里换一个权重文件不用改其他代码。提示模型规模选择的逻辑应该根据目标在画面中的尺度占比和实时性要求来定而不是一味堆参数。温室固定机位场景下优先考虑轻量模型。3. 数据集的构建与标注规范3.1 温室番茄图像采集策略很多第一次做农业视觉项目的同学在数据采集上容易犯两个错误要么图省事只在一天的一个时间段去拍一次要么盲目追求数量一天拍上千张但内容高度重复。我的建议是按照时间-天气-角度-距离四维矩阵来拍。具体策略如下第一时间维度。番茄果实的颜色和温室光照在一天中变化很大。我分别在早上7点、中午12点、下午4点、晚上补光灯开启后四个时间段采集。中午高光容易导致红色过饱和晚上补光下颜色偏黄这些都是训练集必须覆盖的。第二天气维度。晴天、阴天、多云各占一定比例。温室里的散射光和直射光对图像特征影响完全不同如果只拍晴天模型会在阴天场景下精度骤降。第三角度维度。固定机位虽然视角固定但检测系统前期测试时难免要手持设备移动。我拍的时候包含了俯拍、平视、斜角45度左右等角度。第四距离维度。果串距离镜头50厘米和150厘米时成像尺度差别很大。虽然YOLOv5本身具备多尺度检测能力但训练数据还是要尽量覆盖不同尺度否则泛化能力会打折扣。最终采集了约1200张图像清洗掉模糊、过度曝光、完全被挡住的无效图像后剩下约1000张可用。对温室场景项目来说1000张图已经能训练出一个不错的效果。3.2 类别定义与边界框标注的细节问题标注是果串检测项目里最容易被忽视、却又最影响最终精度的环节。我刚才提到果串边界模糊需要在标注前制定一份明确的规范而且团队所有人都要按同一规范执行。我定下来的标注规则是这样的类别一成熟果串。果串中至少有1个果实达到成熟红色且以整个果穗的轮廓作为检测目标框要覆盖所有果实及相连的茎段。类别二未成熟果串。果实整体呈绿色或青白色同样以整串边界为准。标注时如果两个果串在图像里重叠但能明确分辨出各自果实归属就分别标两个框如果果实互相交错、连人都分不清归属就直接融合成一个框不要强行切分。这个过程有人可能会问为什么要把成熟和未成熟分开原因是温室番茄采摘、疏果、花期管理的作业决策完全不同分开类别能为后续产量预估和分级管理提供基础。如果只做单纯的有没有果串检测数据价值会低很多。标注工具我用的是LabelImg它是VOC格式标注的常用工具导出为YOLO需要的txt格式也很方便。具体标注流程是先用矩形框框住目标再选择类别保存为XML格式再通过脚本批量转换成YOLO格式的txt文件。转换脚本的核心逻辑如下import xml.etree.ElementTree as ET import os def xml_to_yolo(xml_file, classes, out_dir): tree ET.parse(xml_file) root tree.getroot() size root.find(size) w, h int(size.find(width).text), int(size.find(height).text) lines [] for obj in root.iter(object): cls obj.find(name).text if cls not in classes: continue cls_id classes.index(cls) box obj.find(bndbox) x1, y1 float(box.find(xmin).text), float(box.find(ymin).text) x2, y2 float(box.find(xmax).text), float(box.find(ymax).text) dw, dh 1.0 / w, 1.0 / h cx, cy (x1 x2) / 2.0 * dw, (y1 y2) / 2.0 * dh bw, bh (x2 - x1) * dw, (y2 - y1) * dh lines.append(f{cls_id} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}) with open(os.path.join(out_dir, os.path.splitext(os.path.basename(xml_file))[0] .txt), w) as f: f.write(\n.join(lines))3.3 数据增强不只为了提点更是为了解决光线过拟合YOLOv5自带了很丰富的数据增强策略包括马赛克增强、水平翻转、HSV色域变换、随机缩放、随机剪裁等。刚开始我用默认配置训练完发现白天高光下的检测效果特别差仔细分析后发现是训练集里高光样本太少默认增强没有产生足够多的对抗性样本。于是我专门针对温室环境做了一套增强方案。在YOLOv5的超参数配置文件hyp.scratch-low.yaml里重点调整了色域相关参数hsv_h: 0.015 # 色调偏移控制红色到橙色的变化 hsv_s: 0.7 # 饱和度增强模拟不同天气下的颜色浓淡 hsv_v: 0.5 # 明度增强模拟高低光照差异同时把马赛克增强的概率提高到1.0让每张训练图都由4张图拼接而成。这样做的另一个好处是温室里叶片和果实的分布本身就有很强的重复纹理马赛克增强能让模型学会特征组合而不只是记住整体布局。还有一个很容易被忽略的点我没有直接使用YOLOv5自带的自动学习增强参数而是先固定这套手动配置跑了一轮得到baseline之后再去微调。原因是自动增强在温室这种强光照场景下可能会把果实颜色增强到严重失真反而破坏语义信息。3.4 数据集划分与标注质量控制数据集按8:1:1划分成训练集、验证集、测试集。这里有一个额外的约束同一个果串在同一个摄像头视角的不同时间点拍到的图像不能同时出现在训练集和验证集中。我按照物理果串编号来做划分而不是随机抽图像。如果同一串番茄的图像既在训练集又在验证集mAP会有虚高训练看起来效果很好实际部署验证时立刻现原形。标注质量控制方面我会在所有图像标注完成后再单独做一轮交叉检查。检查的重点是是否存在漏标。比如果串只露出一小部分标注员可能漏掉。边界框是否过紧或过松。框过紧会把部分果实切出框外框过松会框入大量叶片都会干扰学习。类别是否混淆。青色番茄和成熟番茄在颜色过渡期很难区分需要在标注规范里增加过渡期归属规则果实超过三分之一变为橙色就算成熟。全部检查完毕再用一个统计脚本检查每个类别的目标数量是否均衡。如果成熟果串数量远多于未成熟果串就要补充采集未成熟阶段的图像否则模型会对未成熟果串严重欠拟合。4. 模型训练与调优全流程4.1 训练前的准备工作数据集准备好之后还需要检查两件事。第一件事是数据格式。YOLOv5要求图像放在images文件夹下对应标签放在labels文件夹下文件名必须一一对应。标签文件的每行格式是类别ID 中心点x 中心点y 宽度 高度所有坐标值都是归一化到0~1之间的小数。我写了一个校验脚本专门检查标签文件中是否有越界坐标、空文件、负值等常见错误。这一步很重要因为标签文件一旦出错会在训练过程中引发奇怪的loss波动。第二件事是生成数据集配置文件。YOLOv5通过yaml文件指定数据路径和类别名我的配置文件如下train: /data/tomato_training/datasets/images/train val: /data/tomato_training/datasets/images/val test: /data/tomato_training/datasets/images/test nc: 2 names: [ripened_harvest, unripened_harvest]names的顺序必须和转换脚本中classes列表的顺序一致否则类别对不上训练白跑。4.2 核心训练参数的选择与解析我把训练命令写在下面这套参数是用YOLOv5s在1000张图上的实测优选配置python train.py \ --img 640 \ --batch 16 \ --epochs 200 \ --data tomato_data.yaml \ --weights yolov5s.pt \ --cache \ --patience 50 \ --name tomato_yolov5s逐个解释一下关键参数。--img 640表示输入分辨率640x640。这个值不能随意改它决定了模型看到的细节程度。如果果串在图像中占比小可以提高分辨率但显存占用会明显增加。温室场景下的果串占比比较大640是性价比不错的选择。--batch 16在12GB显存下刚好卡在临界值。Batch size影响的是BN层统计量的稳定性。Batch太小BN均值方差波动大模型训练不稳定Batch太大一次迭代耗时长收敛变慢。16是一个经过验证的稳妥值。--epochs 200看起来偏多但实际训练中有过早停机制。--patience 50表示如果连续50轮验证集mAP没有提升训练自动停止。我实测最快的一次在第90轮就停住了说明模型在前期已充分拟合盲目跑满200轮反而浪费时间。--cache参数会把图像加载到显存中缓存显著减少数据读取的IO开销。1000张图完全放得下训练速度提升明显。如果显存紧张建议不要开。还有两个在代码里默认开启但值得单独说明的选项--multi-scale和--label-smoothing。我建议在基础训练阶段关闭multi-scale因为多尺度采样会引入额外的输入分布抖动先固定尺寸让模型稳定收敛。等基础模型精度稳定后再打开multi-scale做第二轮微调可以再提升一些泛化能力。4.3 训练过程观察loss曲线与mAP变化训练不是把命令丢进去就完事了需要持续观察日志。YOLOv5的训练日志里有两个关键指标box_loss和cls_loss。box_loss反映边界框回归的误差刚开始会在0.08到0.1之间波动如果正确训练会逐步降到0.03左右。cls_loss反映分类误差对于成熟/未成熟两个类别由于类别区分度明显loss下降速度应该很快通常在20轮内就会低于0.02。如果发现box_loss训练过程中出现剧烈震荡、甚至反弹很可能是学习率设置偏高。YOLOv5默认初始学习率是0.01配合SGD优化器训练前期适合大多数场景。如果数据集较小或者标注噪声较大学习率要降到0.005左右。除了loss还要看验证集上的mAP0.5和mAP0.5:0.95。mAP0.5是IoU阈值0.5下的平均精度反映模型大致框得准不准的能力通常要求能达到0.9以上。mAP0.5:0.95是IoU从0.5到0.95每隔0.05计算一次的平均值反映框的精确度这个指标对果串这种非刚性目标来说能达到0.55以上就算很好了。为什么mAP0.5:0.95对果串检测这么难因为果串的框并不像人脸、车牌那样有明确的边界。同一个标注框人眼觉得标得挺好但IoU计算出来可能只有0.6。这是目标模糊特性决定的不是模型能力不行不用过分焦虑。4.4 针对温室场景的专项调优第一轮训练完成后我拿到了一个baseline模型mAP0.5为0.91mAP0.5:0.95为0.53。对通用检测任务来说已经不错但拿到温室测试集上跑了一遍发现了两个典型问题重叠密集果串存在漏检夜间的暗光图像精度下降明显。针对第一个问题我把NMS的IoU阈值从默认的0.45调到了0.35。这样做的逻辑是果串密集重叠时两个真实目标框的交叠程度本身就高如果阈值太大NMS会把相邻的果串当成同一个目标直接抑制掉。降低阈值后相邻目标被保留的概率变大漏检减少。针对第二个问题我在数据集中增加了暗光图像的占比并且通过多尺度训练来增强模型对光照和尺度的鲁棒性。同时把置信度阈值从0.25调到0.3过滤掉夜间低置信度的假阳性框。这些参数在代码里不是超参而是推理脚本里的常规参数修改起来没有风险model.conf 0.3 model.iou 0.35 model.max_det 100这里的max_det也要注意。果串最多、混叠最严重的图像里检测框数量可能超过默认的89个所以我把上限放宽到100个避免后处理阶段丢掉真正的目标。4.5 模型评估与效果验证训练结束后我用了三种方式验证模型效果而不是只看mAP数字。第一个是精确率-召回率曲线。看曲线之前在哪个置信度阈值下达到平衡。如果曲线在0.9附近还保持较高的召回率说明模型在保证准确的同时不会漏掉太多目标。番茄果串检测场景中漏检的代价比误检更大因为漏检意味着这个果串可能一直没被管理所以我宁可牺牲一点精确率也要保持召回率。第二个是PR曲线的可视化和对角线检查。如果PR曲线下面积小说明模型输出的置信度分布不够合理需要回到数据标注层面排查大多数情况下是标注不一致导致的。第三个是典型场景实测。我专门挑了一组密集重叠、强逆光、轻度遮挡的高难度图像做推理可视化。把检测框画出来跟原始图像对比看人工能不能接受。这一步靠的不是指标而是视觉经验。很多时候mAP很高但框的细节严重抖动在真实管理场景中并不好用。5. 检测系统的整体设计与部署实现5.1 系统架构设计整个检测系统从上到下分为三层交互展示层、业务服务层、算法推理层。交互展示层是我用PyQt5写的一个简洁可视化界面功能包括选择图片、启动检测、框结果展示、保存标注结果。业务服务层负责图像预处理、调用推理接口、解析检测结果、格式化输出。算法推理层承载YOLOv5模型提供检测能力。对于需要部署到生产环境的场景我建议把算法推理层单独封装成HTTP服务用Flask或FastAPI实现业务层通过接口调用。这样做的好处是模型和业务解耦后续模型更新不需要修改其他代码。5.2 推理流程的工程化封装原始YOLOv5的detect.py脚本适合调试不适合直接集成到系统里因为它依赖命令行参数且输出格式固定。我在实际项目中单独写了一个推理封装文件核心逻辑如下import torch import cv2 import numpy as np from pathlib import Path class TomatoDetector: def __init__(self, weights_path, device0, conf0.3, iou0.35): self.model torch.hub.load(ultralytics/yolov5, custom, pathweights_path, force_reloadFalse) self.model.conf conf self.model.iou iou self.model.max_det 100 self.device device def predict(self, img): if isinstance(img, str): img cv2.imread(img) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) results self.model(img) boxes results.xyxy[0].cpu().numpy() return boxes这个封装返回的boxes数组每一行包含[x1, y1, x2, y2, conf, cls_id]后续只需要按自己的数据格式转换即可。部署时还遇到一个问题PyTorch模型权重在CPU机器上推理速度偏慢。我把模型导出为ONNX格式利用ONNX Runtime做推理加速。在CPU环境下单张640x640图像的推理时间从300毫秒降到了100毫秒左右。导出命令如下python export.py --weights runs/train/tomato_yolov5s/weights/best.pt --include onnx --opset 12如果部署机器有NVIDIA显卡并且安装了TensorRT还可以进一步导出为engine格式推理延迟能压到20毫秒以内。温室实时监测场景一般不需要这么高的帧率但做大棚视频流巡检时速度肯定越快越好。5.3 前端展示界面的实现要点界面部分我用了PyQt5实现因为做桌面工具最方便。关键需求有三个图片加载与显示、检测结果绘制、结果导出。检测框的绘制要特别注意图层顺序先画原图再画检测框和标签避免遮挡关键信息。颜色方面我用绿色表示成熟果串用黄色表示未成熟果串在温室背景下对比度比较清晰。标签文本包含类别名和置信度比如熟果串 0.92。导出功能是整个系统使用频率最高的功能之一。检测结果需要保存为标准COCO格式或JSON格式方方便后续产量统计。我实现的导出逻辑是把检测坐标转换为相对原图的绝对像素坐标并附上采集时间、图像文件名。整个界面代码结构按照界面逻辑与业务逻辑分离的原则拆分。界面窗口类只负责布局和控件事件响应业务逻辑放在独立模块里。这样后续如果要把桌面版改成Web服务只需要替换交互层算法和业务逻辑不用动。5.4 源码工程结构一览这个项目的源码结构整理如下方便拿到代码后快速定位tomato_detection/ │ ├── data/ │ ├── images/ │ │ ├── train/ │ │ ├── val/ │ │ └── test/ │ ├── labels/ │ │ ├── train/ │ │ ├── val/ │ │ └── test/ │ └── tomato_data.yaml │ ├── src/ │ ├── train.py │ ├── detect.py │ ├── export.py │ ├── detector.py │ └── utils/ │ ├── xml_to_yolo.py │ └── validate_labels.py │ ├── ui/ │ └── main_window.py │ ├── weights/ │ ├── yolov5s.pt │ └── best.pt │ └── requirements.txttrain.py和detect.py直接通过命令行运行detector.py是集成接口main_window.py是GUI入口。对于只需要跑通流程的读者可以跳过GUI部分直接调detector.py。6. 常见问题与排查技巧实录6.1 训练loss不下降或者直接爆掉训练过程中最常遇到的问题就是loss不降。我排查过几次问题基本出在三个地方。第一个是标签文件出错。YOLO格式的坐标值必须在0到1之间如果转换脚本里除以图像宽高的逻辑写错坐标就会变成几万这种离谱值模型永远学不会。校验脚本能解决这个隐患。第二个是数据集类别分布严重不均衡。如果成熟果串占了90%未成熟果串只有10%那么模型训练时梯度大部分由成熟样本提供分类指标会呈现整体mAP偏高、但某个类别几乎完全检测不到的假象。处理办法是给稀有类别分配更高的损失权重或者对稀有类别的样本做复制增强。第三个是学习率设置过高。YOLOv5默认0.01在通用数据集上没问题但数据量小时容易出现初始阶段loss就爆炸的情况。把学习率降到0.005甚至0.002可以让训练过程更稳定。我遇到过一种更诡异的状况训练前期loss正常下降到第80轮左右开始震荡上升。最后定位到原因是训练过程中关闭了标签平滑导致的优化目标突变。YOLOv5的标签平滑默认在训练集较小时产生正则化效果改来改去反而好事变坏事不同阶段修改损失函数相关的配置时要谨慎。6.2 读数据太慢导致GPU利用率低1000张图如果用HDD机械硬盘做数据读取训练时GPU会经常陷入等待状态显卡利用率可能只有30%。解决办法是加--cache参数把图片全部缓存进内存或显存数据读取不再是瓶颈。如果数据集太大无法完全缓存建议先把所有图像缩放到统一分辨率再做caching。另外Windows环境下OpenCV读取图像、PyTorch的DataLoader开启多进程时偶尔会报Too many open files错误。这是Windows的文件句柄限制导致的把num_workers从默认值调小到2或1问题就解决了。6.3 检测出来的框总是偏大或偏小这是一个很有意思的现象。模型明明收敛了mAP也不错但可视化后发现框普遍比果串实际轮廓大一圈或者只框住了部分果实。原因通常出在标注环节模型学到的是标注的分布均值。如果多人标注时有人习惯留白有人习惯紧贴果实模型会学到一种平均框法输出框自然介于两者之间。解决办法是在标注规范里要求每个目标框紧贴轮廓再对已有标注做批量偏移修正。我写了一个脚本计算所有训练框与人工微调框之间的平均偏移量然后应用到整个标签集。这个脚本虽然简单但对框精度有明显改善。6.4 模型在夜间图像上的表现不如白天温室白天和夜间的图像特征差异太大了单独增加一点暗光样本起不到决定性作用。我的做法是分两步先做全局ImageNet风格归一化再把曝光偏低的图像做直方图均衡化增强后加入训练集。还有一个自研的小技巧对夜间图像做CLAHE自适应直方图均衡增强局部对比度让果串与叶片边界不那么模糊。这个预处理可以放在数据增强管线里也可以放在推理前置步骤中。我实测夜间mAP0.5从0.72提升到了0.83提升明显。6.5 推理时内存不断上涨连续处理视频帧时PyTorch的显存或内存占用会持续增长看起来像内存泄漏。实际上大多数情况下是因为在for循环里频繁创建tensor没有及时释放或者detector实例被重复创建。我处理的办法是常驻一个全局模型实例推理时只把图像数据传给同一个实例不重新加载模型。如果确实需要在循环里多次调用推理建议在每轮结束执行torch.cuda.empty_cache()。但频繁调用这个函数也有性能开销正确使用姿势是每隔固定帧数调用一次而不是每帧都调用。7. 从项目源码延伸到场景化应用7.1 果串计数与产量预估的扩展思路训练好的果串检测模型不只是个检测框可视化工具它还可以为产量预估提供基础数据。在温室管理中管理者关心的是每个大棚总共有多少串番茄成熟了、多少串还需要多长时间成熟。检测系统输出的每一帧果串坐标配合多视角标定和一定的跟踪算法就能完成这一目标。最简单的做法是固定机位连续拍摄用帧间检测框的重叠度做目标匹配统计果串出现次数。如果同一位置的果串连续多帧都出现就判定为同一个目标重复计数会被剔除掉。对于移动拍摄的情况则需要结合位姿估计复杂度会高很多但对于产量预估的初级版本固定机位就够了。7.2 移动端与边缘设备部署的轻量化温室场景里很多农业设备是嵌入式设备算力远不如服务器。我在项目后期做了一轮轻量化尝试思路有两个一是用TensorRT对模型做FP16量化二是用剪枝去掉不重要的通道。前者的精度损失几乎可以忽略推理加速明显后者需要重训练补偿工作量相对大。还有一个更省事的方法直接用官方提供的YOLOv5n模型权重作为起点在温室数据集上继续微调。YOLOv5n比YOLOv5s参数量少了几倍在边缘设备上运行更流畅精度只是略低。适合对精度要求不极端、但设备资源有限的场景。7.3 与温室管理系统的联动如果整个系统不止要看见番茄果串还要触发后续的浇灌、施肥、采摘提醒等动作检测系统需要输出标准化的信息格式。我建议把检测结果统一打包成JSON包含图像ID、目标类别、边界框坐标、置信度和时间戳。这样后端的管理系统只要解析JSON就能做业务逻辑。比如某果串连续三次检测均为成熟状态就触发可采摘提醒区域内成熟果串数量超过阈值就在大屏上显示需优先处理标记。这种系统对接不需要改模型代码JSON协议就是接口的全部定义。8. 实操中的真实心得与避坑记录写这篇文章时我又重新回顾了一遍整个项目的开发过程。有一些经验如果当初有人提前告诉我可以少走很多弯路。第一点数据标注的优先级一定高于模型调优。有很多人拿到项目后第一反应是尝试各种模型结构、调优各种超参数却发现精度一直没有质变。回头检查数据时才发现标注里到处都是边界框漂移、类别错标、漏标浪费了大量时间。一个干净的数据集配上一套稳定的默认参数效果往往超过脏数据配上精心调优的参数。第二点温室场景中最有决定性的技术动作是搭建多轮闭环验证。第一轮训练出的模型必须拿它到真实温室里跑一轮把预测错的案例全收集回来补齐到训练集里再训练第二轮。重复两三轮之后模型的泛化能力会有一个明显跳跃。很多公开的算法比赛不需要这一轮因为数据固定不变但落地项目必须做这种迭代否则测试集之外的场景能力很不够。第三点不要迷信单一指标。模型mAP高不一定意味着系统好用尤其是果串检测这类边界模糊的任务。生产环境里真正起作用的是系统在特定光照条件下的视觉表现。所以我会在每次模型更新后做一次人工目检视觉上感觉框的位置合理、类别判断准确才算验收通过。最后分享一个关于推理速度的小技巧如果只是做离线分析对帧率要求不高可以批量处理多个文件而不是逐张调用预测函数。YOLOv5支持传入图像列表内部会自动做一个batch推理速度提升很明显而且代码改动很小。温室番茄果串检测这个方向本质上是用视觉方法帮助农业生产者把看果子这件重复劳动自动化。YOLOv5提供了成熟好用的检测框架但真正决定系统可用性的是项目设计中对数据、目标和部署环境的细致考量。这套方法不只是适用于番茄辣椒、黄瓜、草莓这类挂在藤蔓上的串状作物同样可以迁移使用。沿着这条思路继续扩展还可以尝试用分割模型做果串轮廓提取为自动采摘机器人提供更精细的定位信息。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →