1. 项目背景与需求拆解
草莓大棚里最让农技员头疼的不是浇水施肥,而是采摘。草莓成熟期集中、果实娇嫩、茎秆又短又脆,人工采摘一天下来弯腰几百次,效率上不去,损耗还高。这几年智慧农业喊得凶,但真正落到"自动采摘"这一步,卡点就卡在视觉识别上——机器人得知道草莓在哪儿、红没红、该从哪儿下剪子,这一连串问题本质上都在问一件事:图像分割识别到底能不能做到又快又准。
这个项目做的就是这件事:用基于深度学习的YOLO26算法对草莓采摘点做图像分割识别,把"果实定位、成熟度判断、采摘点坐标计算"一条龙打通。YOLO26这个名字可能有人觉得陌生,它本质上是YOLO系列检测加分割范式的一个项目内部版本代号,延续了一阶段检测的实时性优势,同时引入实例分割分支,输出每个草莓的轮廓mask,再结合后处理算出精准的剪切位置和夹取位置。整套方案不只服务采摘机器人,也可以反过来做草莓生长状态监测,比如统计不同成熟度的果实数量、预测采摘窗口期,最终把大棚管理变成一个数据驱动的闭环系统。
适合谁参考?准备做农业机器人视觉方案的技术团队、想用深度学习解决果实采摘问题的研究生、以及已经在做智慧农业但卡在模型落地环节的一线开发者。下面我会把这套方案从数据、训练、部署到田间踩坑,按实操顺序完整拆开来讲。
2. 数据准备与标注策略:比模型本身更影响成败的工程环节
很多团队一上来就急着调模型,实际做了之后才明白,深度学习项目里最花时间、最决定上限的往往是数据。草莓采摘识别这种细粒度分割任务尤其如此,田间和温室环境杂乱、光照变化大、果实互相遮挡,如果数据质量跟不上,换再强的backbone也很难救回来。
2.1 采集设计:覆盖"真实采摘场景"而不是"好看的照片"
我见过不少项目拿网上公开数据集训练,效果看着还行,一到现场全废,问题就出在数据分布和真实场景不一致。草莓机器人的工作场景是温室或大棚,光照从晴天的直射到阴天的散射都有,果实有的正面朝外,有的藏在叶子后面,有的半遮半掩只露出一半。这些场景必须靠自己在目标大棚里采。
采集这块建议分三路走。第一路是固定机位拍摄,模拟机械臂末端摄像头从多个角度观察草莓的视角;第二路是手持相机扫拍,覆盖不同垄间、行距、光线条件下的图像;第三路是刻意制造"困难样本"——把叶子拨到果实前面制造遮挡、把果实转成背光角度、让相机产生轻微模糊,这些别扭样本在后续训练中能显著提升模型鲁棒性。
设备方面不需要太奢侈,某型号工业相机配适当光源就能干活。但要注意一个关键点:采集图像的分辨率要和部署时的实际摄像头输出保持一致,或者至少要保证模型推理输入尺寸能够容纳果实细节。草莓从绿果到成熟果大小差异可能有两三倍,小果在640像素输入下可能只有二三十个像素,这种情况必须考虑高分辨率输入或者多尺度训练。
2.2 标注类别设计:不只标"草莓",还要标"茎"和"剪断点"
标注类别设计是采摘任务和其他分割任务最大的不同点。不能只标一个"strawberry"类别,因为机器人既要判断果实能不能摘(成熟度),还要知道在哪儿下剪子(采摘点),更要避免夹爪抓到茎秆伤害果柄。所以我在项目中把标注对象拆成三个子类:
- 草莓果实本体(进一步按成熟度拆分:绿果、白果、半熟果、成熟果)
- 果柄/茎秆(采摘时需要避开的区域)
- 采摘点关键位置(果柄与果实连接处的临界断裂点)
这样设计的目标是让模型同时输出语义信息和关键点位,后期后处理可以直接基于果实mask和果柄mask的空间关系来计算剪切点,而不是只靠一个粗糙的检测框去猜。成熟度拆分方面,我建议至少分成"未成熟"和"成熟可摘"两个优先级,如果人力充足再细化到四级。因为自动采摘系统的核心动作是"只摘该摘的",分级越细,后续决策才能越精准。
标注工具用常见的标注软件即可,这里重点说几个标注原则:
- 果实边缘紧贴轮廓标注,不要把叶子包进mask;
- 半遮挡果实只标可见区域,同时单独标注"遮挡级别"属性(无遮挡/轻度遮挡/重度遮挡),方便后面做分层评估;
- 多个果实重叠时,相接边界要按照视觉轮廓自然分界,不能含糊;
- 果柄标注要有延续性,被叶子完全遮挡的部分可以不标,但可见部分要连贯。
这套标注规范看起来琐碎,实际训练时就会发现它的价值。分类是否严格、边界是否干净,直接决定mask损失能不能收敛到位。
2.3 数据增强与集划分:把温室变成了"虚拟雨季"
数据增强解决的是模型泛化问题。果园和温室里,同一种草莓在不同光照下成像差异非常大,靠收集真实数据覆盖所有情况不现实,必须靠增强去模拟。
我用了三组增强策略,分别针对光照、几何和目标遮挡。第一组是颜色抖动:随机调整亮度、对比度、饱和度、色相,模拟不同天气和早晚光照;第二组是几何变换:随机旋转、平移、缩放、翻转,模拟机械臂从不同高度和角度观察;第三组是Copy-Paste和Mosaic增强,把不同果实区域拼贴到一起,增加单张图像的目标密度,让模型在密集场景下也能稳定输出。光照方面还可以加一个Gamma校正和CLAHE直方图均衡化,这两种方式对改善反光和阴影效果非常明显。
数据集的划分大家通常习惯按8:1:1做训练/验证/测试,但农场景象有时间特性,一个成熟周期要几周,前期采的数据可能都是青果,后期全是红果。如果随机切分,训练集里两种状态都有还好,但测试集可能因为随机性过高或过低。更稳的做法是按采集日期分组切分:前80%时间采集的数据做训练和验证,后20%单独做测试,这样能测出模型面对"未来新数据"的真实表现。
3. 模型选型与训练细节:YOLO26在算力受限设备上的适配思路
YOLO26从名字延续了YOLO系列的迭代习惯。熟悉这块的读者都知道,YOLO家族一直在平衡"速度快"和"精度高"这对矛盾。采摘机器人对实时性的要求非常高——视觉推理速度直接决定机械臂能不能跟上运动节奏,所以我选型时把"能在边缘设备跑实时"作为硬约束,把"mask精度高"作为优化目标。
3.1 网络结构解析:为什么一阶段分割适合采摘场景
YOLO26模型整体还是"Backbone + Neck + Head"的框架。Backbone负责从图像里抽取特征,一阶段模型普遍采用类似CSP结构的跨阶段连接方式,保证特征提取过程中梯度更顺畅,同时降低计算量;Neck部分用特征金字塔结构把不同尺度的特征融合起来,解决草莓大小不一的问题;Head部分输出两个分支——检测分支给出每颗草莓的框和类别,分割分支给出对应的像素级mask。
有一点需要特别说明:采摘场景里的草莓通常不会特别小,但密集度高,一株上挤着好几颗,互相遮挡。这种场景用一阶段检测加分割的优势在于推理快,一个小模型在嵌入式AI计算平台上可以跑到30帧以上;缺点是遮挡严重时mask边缘容易模糊。基于此,我在模型中加了注意力机制模块,让网络更关注果实和果柄交界处的细节纹理,代价是推理耗时增加不到10%,但mask边界质量提升非常明显。
具体结构参数我用了一个轻量版配置:输入分辨率1280x1280(考虑到小果实和果柄细节),Backbone以轻量卷积为主,通道数控制在64到512之间,分割分支的mask输出尺寸是160x160。这个设计的逻辑是:4096个mask格子覆盖一颗草莓,每个格子大约对应果实表面的几个毫米区域,对后续采摘点计算足够了。
3.2 训练配置与关键参数:一组可以直接抄作业的基础配置
训练时的参数设置对最终效果影响极大,我直接给出一份经实测调过的配置参考:
| 配置项 | 数值 | 说明 |
|---|---|---|
| 输入分辨率 | 1280x1280 | 保留小目标细节,比640提升约5-8% mask mAP |
| batch size | 16 | 边缘设备显存有限,按需可降为8 |
| 优化器 | SGD momentum 0.937 weight_decay 5e-4 | 比AdamW更稳 |
| 初始学习率 | 0.01 | 配合warmup 3 epochs,再余弦衰减到0.001 |
| 训练轮数 | 200 epochs | 实测120轮左右趋于平稳,200轮全量收敛 |
| 损失权重 | box 0.05 / cls 0.5 / seg 1.0 | 分割是核心任务,权重最高 |
训练过程中要留意几个坑。首先是学习率问题,如果训练曲线在50轮以后仍然剧烈波动,优先把余弦衰减的周期改短或者降低初始学习率,不要急着改模型结构。其次是分割分支的损失容易出现"类别不平衡"——背景像素远远多于果实像素,mask损失被背景主导,导致果实边界学不干净。解决办法是给mask分支加上Focal Loss,或者把前景背景的比例在损失函数里做一个动态平衡。第三,YOLO26的anchor设置虽然是自动生成的,但草莓的形状偏椭圆,和通用目标的先验差异大,建议训练前先跑一遍k-means聚类看看anchor分布,必要时手动修正。
3.3 模型优化与裁剪:让边缘设备跑得动
训练好的模型直接部署到嵌入式平台往往跑不动,推理延迟可能超过100毫秒,这个速度根本跟不上机械臂的闭环控制。我在实际项目中做了两层优化。
第一步是导出ONNX格式并做TensorRT加速。这一套下来推理时间通常能压到原来的五分之一到三分之一。关键操作包括:把BN层融合进卷积层、用FP16精度推理、关闭动态shape、固定输入尺寸。实测效果十分明显。
第二步是模型剪枝和通道裁剪。很多通道的激活值在推理时接近零,这些通道没有实际贡献,裁剪掉可以减小模型体积。我在分割分支裁掉了约40%通道,mAP只掉了1个点左右,推理速度却提升了约20%。如果项目对精度要求极高,这一步可以跳过,直接在FP16加速层面就够了。
4. 图像分割识别实操流程:从一帧图像到机械臂坐标
模型训好只是第一步,要把一个模型变成"采摘引导系统",中间还有一条完整的工程链路。很多团队就是在这个环节栽跟头,模型指标很高,但机器人下爪总是差一点。下面把整个推理与后处理流程拆开讲。
4.1 推理管线的完整拆解
整个系统每帧的处理流程是:图像采集 → 预处理 → 模型推理 → 后处理 → 坐标映射输出。
预处理阶段要做三件事:缩放、归一化和颜色校正。缩放用letterbox方式,把原始图像等比缩放并补边到1280,避免图像变形;归一化就是把像素值从0-255映射到0-1;颜色校正是很多人忽略的一步,温室里钠灯和太阳光色温差异大,如果相机白平衡不稳定,模型输入的颜色分布会漂移。我的做法是在预处理里加一个基于HSV空间的色偏矫正,让红色通道在特定光照下自动回归。
模型推理阶段输出的是:检测框(坐标、置信度、类别)、分割mask(二值图)和类别概率。NMS阈值我一般设在0.5,置信度设0.25-0.3。要注意的是,草莓密集场景下如果NMS阈值过严,重叠草莓会被严重抑制掉,后面机械臂就会漏摘。
坐标映射阶段要把模型输出的mask坐标还原到原图坐标,这个看似简单,实际操作中有个关键点:不能直接把缩放系数乘回去,因为letterbox补边会让坐标偏移。必须先减掉padding,再除以缩放系数,否则坐标会整体偏移十来个像素。十像素偏移对采摘来说就意味着夹爪蹭到果实表皮,造成损伤。
4.2 采摘点计算:核心算法与常见失败模式
采摘点计算是本项目的核心。很多人以为草莓采摘点就是果实中心,那对机器人的末端执行器设计来说太天真了。实际上,草莓采摘的关键是找到"果柄和果实连接的脆弱点",通常位于果实顶部的小凹陷处和果柄的交界线。
我用了这样一套计算流程:根据分割出来的果实mask,找到mask的重心点;再沿重心垂直向上寻找mask顶端轮廓的弧线中心;在果实顶部生成一个环形搜索区域,将果柄mask与该区域求交;交集中心就是最终的采摘点坐标,同时计算出果柄的角度方向,供机械臂调整夹爪姿态。
这个方法的关键在于利用了两类mask的空间关系。如果果柄被叶子完全遮挡导致没有果柄mask,算法会自动退回到"果实顶部预测点加固定偏置"的模式,虽然精度略降,但至少不会让机械臂空跑。
实际测试中,采摘点识别成功率在无遮挡果实上可以达到95%以上,半遮挡情况下会降到85%左右,严重遮挡时基本失效——这种情况本来也不应该去摘,因为夹爪可能碰到旁边的果实。
4.3 成熟度判定与采摘优先级排队
草莓不是同时成熟的,一棵植株上可能同时挂着绿果、白果、半红果和成熟红果。机械臂如果见一个摘一个,第二天再来这批果就废了。所以系统要把成熟度判定做到采摘决策里。
我的方法是:对每颗果实的分割mask区域做颜色统计,计算红色像素占比。阈值分三级:红色占比超过70%判定为"成熟可摘",40%-70%判定为"近熟待定",低于40%判定为"未熟暂不摘"。同时结合果形数据——成熟草莓通常是圆锥形,未熟果更偏向球形,果形特征可以辅助颜色判定,避免因光照偏色导致误判。
采摘优先级方面,系统会在每个决策周期内把成熟果按"位置可达性"和"遮挡程度"排序,优先处理无遮挡且位于机械臂行程中央的果实,最大程度减少机械臂路径规划难度和碰撞风险。
5. 系统部署与智慧农业管理闭环:从单点算法到完整平台
很多团队把模型跑通就以为项目结束了,但真正的工程挑战在于怎么把它装进一台能在大棚里长期运行的设备里,并且和其他系统联动起来。这部分讲一讲我在部署和集成层面的方案。
5.1 硬件平台选型与现场安装注意事项
硬件方案我推荐"边缘计算设备 + 工业相机 + 补光灯"的组合。边缘计算平台不需要顶配,关键是支持TensorRT加速且接口丰富,算力大致相当于几十TOPS级别即可满足单路相机的实时推理。工业相机选择时注意两点:一是帧率不低于30fps,二是具备自动曝光/自动白平衡功能,温室光照变化快,手动调参根本忙不过来。
安装位置方面有几条实测经验:
- 相机固定在机械臂末端时,需要做手眼标定(eye-in-hand),标定方法可以用张氏棋盘法,但一定要考虑草莓果实表面的反光干扰;
- 补光灯不要用普通白光直射,果实表面会形成高光spot,反光区域会让mask分割出现空洞。改用低角度漫射光加偏振镜可以有效缓解;
- 设备外壳要做好防潮防尘处理。大棚里早晚湿度大,电路板结露会导致推理卡顿甚至设备损坏,我至少见过两次因为防水没做好导致系统短路的。
5.2 与采摘机械臂的联动:坐标变换与通信
视觉系统输出采摘点坐标后,需要转换到机械臂的基坐标系下才能执行。这里涉及一个刚体变换链:像素坐标 → 相机坐标 → 机械臂末端坐标 → 机械臂基坐标。变换参数来自手眼标定结果,理论上标定一次就能用,但实际上机械臂关节磨损、负载变化都会让标定参数慢慢漂移,最好每隔一段时间做一次自动复核。
通信方面我用的是轻量级消息协议,在边缘设备上运行视觉推理节点,在机械臂控制器上运行执行节点,两者通过局域网通信。视觉节点每完成一帧处理输出一次结果,包括目标ID、采摘点坐标、果柄角度和置信度;机械臂节点只接收置信度高于阈值的指令。整套链路延迟实测在15毫秒左右,视觉推理约30毫秒,机械臂动作决策约10毫秒,总延迟可以控制在60毫秒内,这个水平对低速采摘动作来说完全够用。
5.3 从"识别果实"到"管理果园":数据反向赋能种植
这套系统最有价值的地方,是它不仅服务一台采摘机器人,还能变成整个草莓园的"数字眼"。
运行过程中,系统会持续记录每个区域的草莓成熟度分布、果实密度、采摘量。这些数据聚合到管理平台后,可以做几件很实在的事:
第一是产量预测:结合当前成熟果数量和近几天的成熟速率,预测未来48小时可采摘数量,方便安排人员或者调度机器人作业计划。第二是异常预警:如果某垄连续多天成熟数量极低,而另一垄又集中爆果,说明温室的温差、灌溉或通风可能存在区域差异,管理者可以直接针对性地查问题。第三是采摘记录追溯:每一颗被摘走的草莓都有图像记录存档,一旦发生食品安全或质量纠纷,可以精准回溯到是哪一块田、哪一株、什么时间摘的。
这些数据功能不需要额外开发太多算法,核心依赖的模型输出本身就是结构化的——只要在部署时把每帧推理结果落库,再写几个统计查询接口就够了。但正是这个"顺手为之"的数据层,让项目从"机器换人"变成了"数据指导种植",价值提升了一个量级。
6. 常见问题与排查技巧实录:温室环境中的那些坑
这一段我把自己实际调试过程中踩过的坑、以及身边同行遇到的高频问题整理成速查表,希望能帮后来者少走弯路。
| 现象 | 可能原因 | 排查/解决方式 |
|---|---|---|
| 成熟草莓mask出现内部空洞 | 表面反光导致高光区域特征丢失 | 补光加偏振片;图像预处理加局部直方图增强;训练数据增加高光样本 |
| 温室强光下检测框抖动 | 自动曝光频繁波动 | 固定曝光参数;采用HDR模式取帧 |
| 果实重叠处分割粘连 | 两个实例边界特征太相似 | 提高mask损失权重;增加边缘感知损失;使用更细的mask输出 |
| 远距离小果漏检 | 目标在输入图上像素过少 | 调高输入分辨率到1280以上;对图像分块推理再拼接(SAHI方案) |
| 推理速度不达标 | 模型过大 / 未做加速 | 导出ONNX后做TensorRT FP16加速;通道剪枝;蒸馏到轻量结构 |
| 机械臂下爪位置偏上或偏下 | 手眼标定参数漂移 | 重新标定;在系统增加定期自动标定程序;检查相机安装是否有松动 |
| 果柄mask时有时无 | 果柄过细,分割模型学习不充分 | 单独提升果柄类别的损失权重;使用切片放大推理 |
| 连续雨天模型表现骤降 | 训练数据晴天占比过高 | 收集或合成阴雨天样本;增强里加大亮度/对比度扰动强度 |
| 训练loss曲线在epoch 80后震荡 | 学习率过大 | 提前触发余弦衰减;或降低初始lr,延长warmup |
6.1 反光和光线突变问题
反光是草莓视觉任务里最烦人的干扰源,没有之一。成熟草莓表面光滑,在补光灯下会形成一个高亮的镜面反射区,分割模型在这个区域经常给出错误输出。第一个解决思路是从硬件层面出发:改变光源角度、加柔光罩或偏振片。我实测过偏振片方案效果最直接,但会损失部分进光量,需要相应提高曝光时间或ISO。
第二种思路是从算法层面对抗。在训练集的增强管线里刻意加入"模拟高光"操作:随机选取果实区域,把局部像素值拉高并加上白色斑点噪声。这样模型会学着忽略高光区域,而不是把它们当成异常特征。经过增强训练后,高光区域造成的mask空洞比例下降了大概六成。如果还不满意,可以在后处理里对mask做一个孔洞填充,用面积阈值判断哪些小空洞需要补上。
6.2 遮挡场景的决策策略
草莓大棚里完全无遮挡的果实其实是少数,多数果实不是被叶子挡了一角,就是和其他果实挤在一块。系统在遮挡场景下不能硬摘,也不能全放弃,关键是要建立"遮挡程度"的量化指标。
我用一个简洁实用的算法来评估:取果实检测框的面积和果实mask面积的比值(fill ratio),可以理解为果实露出程度。比值接近1说明几乎无遮挡,低于0.5说明遮挡严重。系统设定0.6作为安全采摘阈值,也就是说,只要露出面积超过60%,就可以尝试采摘——配合机械臂的柔性夹爪,实际成功率仍然很高;低于这个阈值则跳过该果实,等待下一轮巡检时再评估。
这套策略的优点在于它不追求所有果实都精确分割,而是用工程可判定的方式处理不确定性。很多模型指标看似完美,但落地时真正提升采摘成功率的,恰恰是这些工程决策规则。
6.3 模型迭代与数据回流机制
模型上线后不能一劳永逸。大棚环境的季节变化、品种更换、光照模式改变,都会让模型性能缓慢下降。我从项目启动第一天就建立了一个数据回流闭环:每台部署设备都会自动把低置信度推理结果截图上报到一个数据池,每周定时人工筛选一部分进行补充标注,然后增量训练模型,再灰度发布到部分设备上对比效果。
增量训练有个细节要特别注意:不能只用新数据训练,否则模型会遗忘旧场景的特征。我在每个增量训练周期里都会混合抽取20%-30%的原始训练数据,和新增样本一起进入训练集。这个"回放"机制是防止灾难性遗忘的关键,实测引入回放后,模型在旧场景上的表现几乎不下降。
7. 写在最后的一点体会
这套系统从数据集搭建到最终上车部署,整个过程最大的感受是:深度学习模型在其中的占比,远没有很多人想象的那么高。模型结构选型、训练参数调优当然重要,但真正决定项目能不能用的,往往是数据标注是否细致、后处理规则是否贴合机械结构、坐标变换标定是否精准、以及现场遇到反光和遮挡时有没有一套稳住的预案。
草莓采摘识别这类农业视觉任务,和城市里做自动驾驶或者工业质检有一个本质差异——它的目标物体是活的、是变化的、是长在复杂的自然环境里的。果实不会等着你调整好光线再变红,叶子永远在挡路,温室里的湿度和温度在一天之内可以横跨好几个季节。能在这种环境下稳定运行的开发者,靠的永远不是某一次完美的训练,而是持续的迭代和现场观察。
如果让我给后来者一条最具操作性的建议,那就是:从一开始就为"数据回流"做设计,而不是等项目上线后再补。在系统架构里留好数据落盘、低置信度上报、增量训练这三条通道,后面所有优化都会快很多。等你的模型在真实大棚里稳稳跑完一个完整采摘周期,看见机械臂精准避开绿果、只摘那一颗刚好红透的草莓时,你会觉得前面所有调试到凌晨的夜晚都值了。