
智慧农业这几年喊得响但真正能落地的场景里番茄成熟度识别绝对算一个刚需。不管是大棚里挂满枝头的樱桃番茄还是连栋温室里的串收大果采摘自动化要解决的第一件事就是让机器知道“哪个该摘、哪个不该摘、该摘的位置在哪”。这篇文章我会从项目实战的角度把基于深度学习的番茄成熟度识别和采摘点识别整个链路拆开讲一遍包括数据怎么准备、模型怎么选、训练有哪些坑、部署到嵌入式设备上怎么提速、最后怎么把检测框变成机械臂能用的三维坐标。适合正在做农业视觉项目的人、想入门智慧农业的学生以及想把自己的算法真正装到采摘机器人上的开发者。我前期做过一个模拟项目X目标就是在大棚环境里实时识别番茄成熟度并给出果柄上的采摘点。过程中踩了不少坑也总结了一些相对可靠的思路。下面不绕弯子直接按实操顺序聊。1. 项目整体拆解番茄成熟度识别到底在解决什么问题1.1 从采摘自动化倒推视觉需求很多人以为采摘机器人最难的是机械臂实际做下来你会发现视觉感知才是真正的瓶颈。机械臂再灵活你得先告诉它“摘哪里”它才能动。一个完整的采摘流程是摄像头采集图像 → 识别出番茄的位置和成熟度 → 定位果柄采摘点 → 计算三维坐标 → 机械臂规划路径 → 末端执行器剪切或夹持。这里面每一步的输入都依赖视觉算法给出准确结果。所以成熟度识别不只是做个分类它是整个自动化采摘链条的入口。如果模型把绿番茄当成红番茄机械臂过去一把抓轻则抓空重则把还没熟的果拽下来损失就大了。更麻烦的是番茄是成串生长的果实之间遮挡严重一个框里往往有多个番茄而且成熟度各不相同。这就要求模型不仅要能分类还得具备较强的空间感知能力。1.2 成熟度分级标准与业务定义在动手写代码之前先把业务标准定清楚。农业上番茄成熟度一般分绿熟期、转色期、粉红期、浅红期、红熟期。但直接按这个来做多分类落地时会发现标注难度大、类别之间边界模糊。我实际用下来更推荐按“可采摘/不可采摘”二分类或者按“未熟/半熟/成熟”三分类业务目标更明确。这里有个关键经验不要为了追求技术上的精细分类而增加模型负担。很多团队喜欢把成熟度做成6档结果标注员累死模型准确率还提不上去。采摘逻辑很简单——能不能摘。所以我最终采用的是三分类未熟绿色、半熟偏黄或粉、成熟红色同时设定成熟占比超过70%才判定为“可采摘”。这个阈值可以根据实际品种调整比如串收番茄要求更红那就把阈值提到80%。采摘点识别是另一个独立任务。所谓采摘点就是果柄上适合剪切的位置通常靠近果实顶部与果柄连接处。这里要注意采摘点不是果实中心而是果柄关节处。传统目标检测算法只能给一个矩形框无法直接给出果柄位置所以需要单独做关键点检测或小目标检测。2. 数据采集与标注模型效果的真正天花板2.1 数据采集的几个要点和很多朋友聊项目时大家一上来就纠结模型结构结果第一版数据就几百张跑出来效果自然不行。我得说农业场景的数据采集难度比公开数据集高一个量级因为环境太复杂了。番茄生长在大棚里光从侧面和顶部同时照下来果实表面会有反光叶片阴影会挡住半个果子不同时段的光线色温也不一样。如果只在晴天中午采数据模型一到阴天就歇菜。所以采集时要刻意覆盖多种条件晴天上午、下午、阴天、雨天棚内、补光灯开启时、遮阳网拉上时。角度上除了平视还要有俯拍和仰拍模拟机械臂不同高度的视野。设备方面用工业相机或者普通手机都可以。关键是保证图像清晰不要有运动模糊。如果是RGB-D相机比如常见的深度相机还能同时拿到深度图对后面算三维坐标有好处。分辨率建议不低于1280×720原始图片太小的目标很难检出。采集数量上我建议单类别至少1000个标注实例。比如“成熟番茄”这个类别要保证图像里有1000个成熟的果实而不是1000张图。因为一张图里通常有多个番茄所以2000张图像一般够用。如果品种特别多比如有大红番茄、粉红番茄、樱桃番茄那每个品种都要单独覆盖。2.2 标注细节与工具选择标注工具我用过不少最顺手的组合是LabelImg处理目标检测compatible配合一些半自动工具做分割标注。但实际项目里番茄成熟度识别用矩形框就够用了不一定非要实例分割。矩形框标注速度快训练成本低而且结合接下来的关键点标注完全能满足采摘需求。标注规范上我建议这样定每个可见的、面积大于某阈值的番茄都标注类别按成熟度标。被遮挡超过50%的可以不标避免给模型传递太多模糊信息。若有疑问宁可漏标不要错标因为错标直接教坏模型。采摘点标注是另一个标签维度。我会在每张图里给成熟的番茄标一个“采摘点”点的位置放在果柄与果实连接处的中心。可以把它当作一个关键点用Point的形式标在图像坐标上。如果用的是支持多标签的工具可以在同一份标注文件里既有检测框又有关键点。我用的是自定义脚本把LabelImg的XML转成训练需要的格式再做关键点标注效果还不错。数据增强方面随机翻转、亮度调整、对比度调整、随机裁剪都常用。但有一个必须注意——不能随意改变番茄的颜色通道。比如把红色混入绿色成分或者做较强的色调偏移会把“成熟度”这个核心特征破坏掉导致模型学到的颜色语义错乱。所以增强时色相Hue的扰动幅度要控制在很小范围只对亮度、饱和度和几何变换下手。3. 模型选型与训练技巧从准确率到实时性3.1 目标检测模型怎么选当前目标检测领域可选方案很多YOLO系列、Faster R-CNN、CenterNet还有分割模型。我实际测试下来YOLOv8是最合适的起点。原因很直接代码生态成熟中文资料多推理速度快支持嵌入式部署。Faster R-CNN精度不差但速度太慢在大棚里一秒钟处理不了几帧机械臂根本没办法实时跟踪。CenterNet这类无锚框模型稍显冷门新手调参难度大。YOLOv8提供n/s/m/l/x几个版本模型大小依次增加。我个人推荐从YOLOv8m起步Reason在于n和s对小目标的检测能力偏弱。如果你有足够算力可以直接用m后面部署到嵌入式设备再降级或者量化压缩。这里补充一个经验训练和部署用同一个模型结构不要训练时用m部署时换个更小的结构会导致精度损失很大。最好是训练时就以最终部署的模型规模为准或者至少做知识蒸馏。如果是做实例分割可以用YOLOv8-seg但这会引入额外的计算量。番茄采摘点识别不需要分割出果实轮廓只要框和关键点就够。所以检测关键点回归是性价比最高的方案。3.2 关键点回归的实现思路采摘点识别可以单独用一个关键点检测模型也可以和检测任务合在一起。YOLOv8自带姿态估计模型YOLOv8-pose它是为人体关键点设计的但你可以迁移到果柄点上。简单做法是把采摘点当作单关键点在检测框头部增加一个坐标回归分支。但实际训练时我发现单独靠回归分支精度不稳定。后来我改了个更实用的策略把果柄和采摘点当作一个细长的小目标检测框用带方向的角度框或简化为垂直的窄框来检测取框的中心作为采摘点。这种方式的好处是利用检测的anchor机制去捕捉细长的果柄比直接回归坐标更稳。你们也可以试一下。3.3 训练参数与调参细节我反复强调迁移学习在农业视觉里太重要了。农业场景数据量无论怎么加都远少于通用数据集所以要加载COCO预训练权重。训练时前10个epoch冻结backbone只训练detection head之后解冻全部微调。这样能避免初始阶段把学好的特征破坏掉。输入分辨率我设定为640×640但番茄目标在整幅图里经常比较小尤其是行距大的棚里果实可能只有二三十像素。直接训练会漏检严重。这个问题的解法有几个一是采集时尽量凑近二是在原图上做瓦片切分三是使用更高分辨率输入。我最后选了瓦片切分把一张1920×1080的图切成4块960×1080分别推理再合并结果小目标召回率明显提升。代价是推理时间变长需要根据实际部署平台权衡。优化器选AdamW初始学习率1e-4batch size尽量调大。学习率调度我用Cosine Annealing配合线性warmup。权重衰减设0.05。类别不平衡问题在番茄成熟度里也存在未熟番茄远多于成熟番茄采摘期前所以我在Loss里给成熟类加了1.5倍的权重。训练时我用的是随机四分之一到一半概率去预测果柄但可能效果一般。关键还是数据质量和数量。3.4 评估指标怎么看算法工程师习惯看mAP但农业项目必须结合业务看指标。mAP是一个整体指标而到采摘场景漏检率才是致命的。一个成熟番茄漏检机械臂就错过它如果误检率高机械臂可能对着一片叶子空抓。所以我在验证集上会同时统计每类AP、召回率、精确率还专门统计“成熟番茄漏检率”和“未熟番茄误检为成熟”的错误率。实践中我定了一个门槛成熟番茄的recall达到90%以上才算可用精确率可以放到85%左右因为误检了机械臂还可以二次判断但漏检就彻底丢了收益。4. 部署与采摘点计算从模型输出到机械臂动作4.1 嵌入式平台与模型加速模型训练好了最终要跑到机器人上。常见的嵌入式平台有Jetson Nano、Jetson Orin NX、RK3588等。我用的是Jetson Orin NX算力足够跑YOLOv8m。推理加速方面TensorRT是绕不开的工具。把PyTorch模型导出为ONNX再转成TensorRT FP16通常能带来2~3倍速度提升。INT8量化能更快但对番茄成熟度识别这种颜色敏感任务INT8容易让红色和黄色的边界变模糊。我试过INT8成熟度准确率至少掉5个百分点最终保留了FP16。TensorRT转换有几个坑一是自定义后处理算子如NMS最好放到TensorRT外面用Python或C写不然转换容易失败二是动态输入尺寸导出会降低性能尽量固定640×640输入三是如果模型有自定义层ONNX导出时要手动映射算子建议先跑通CPU推理再上TensorRT。4.2 采摘点三维坐标怎么算二维图像里的采摘点只是像素坐标机械臂要抓取必须得到三维坐标。这里要用RGB-D相机。我用的是深度相机它同时输出彩色图和对齐后的深度图。计算流程先把采摘点的像素坐标映射到相机坐标系公式就是常规的反投影用相机内参矩阵。然后从深度图上取该位置的深度值得到相机坐标系下的三维点。注意深度图要提前配准对齐到彩色图很多相机的SDK直接提供aligned depth。但光有单目反投影不够因为番茄是圆的相机看到的采摘点可能在果实背面被遮挡。一个可靠的做法是在三目标检出之后用深度图聚类或者点云分割把果实表面点云拟合出球体再结合彩色图上的关键点估算真正的三维采摘点。这一步会用到简单的几何拟合效果比直接取单点深度好很多。强烈建议不要跳过。4.3 手眼标定与坐标变换有了相机坐标系下的采摘点还要把坐标转到机械臂基座坐标系。手眼标定方案一般有两种eye-in-hand相机装在机械臂末端和eye-to-hand相机固定在外侧。采摘机器人常用eye-to-hand相机固定在大棚顶部或机器人侧面。手眼标定就是求相机到机械臂基座的变换矩阵。用标定板比如棋盘格或者ArUco板在相机视野里移动几个位置同时记录机械臂末端的位姿然后用现有的OpenCV标定函数求解。这一步看上去简单但实际误差特别容易踩坑。我遇到的典型问题是标定板没有完全在相机视野内、或者机械臂末端读数不准、或者标定板不平整三步下来误差直接超过10mm。经验是标定板要够大保持平整贴好防反光机械臂移动范围尽量覆盖采摘工作区域最后一定要在真实番茄上验证确定连续面积的位置不要只在标定板上做。5. 常见问题与坑真实环境中的翻车实录5.1 光照变化导致的成熟度误判这是我在棚里遇到的最大问题。大棚顶部光照充足时红色番茄高光溢出相机拍出来变成粉色模型就认为是半熟。反过来遮阳网下光线暗成熟番茄颜色发暗可能被误判为未熟。应对办法分三条腿走路一是在数据采集时加入不同光照时段和各方向补光条件二是做光照增强预处理比如限制对比度直方图均衡三是在模型输入端采用色彩归一化把LAB色彩空间转换后仅使用A、B通道颜色通道减少亮度干扰。实测下来第三条路效果最明显能够把黄昏时段误判率降很多。5.2 遮挡和果实簇生导致的漏检番茄一簇一簇长果实互相遮挡严重模型经常只检出最外侧的果漏掉里层的。这种情况对采摘自动化很致命因为里层果同样成熟如果不摘就浪费了。我试过几种后处理软NMS比硬NMS强一点但对严重重叠的框还是无能为力。后来改用实例分割YOLO检测混合方案Seg模型能把被遮挡果实的轮廓也还原一部分。为了不过多牺牲速度我只在遮挡严重的部分区域跑Seg整体流程是Detector粗筛如果有密集区域则切出来二次分割。速度能接受漏检率大幅下降。还有一个思路是把“可采摘区域”作为检测目标而不是完整果实。比如只检测番茄表面暴露的红色区域区域面积达标则认为有可采摘果实。这种方法牺牲了审美但实用可以作为备选。5.3 目标尺寸过小且模糊果柄采摘点细长模糊在图像里可能只有几个像素。直接检测花开点效果很差。我用的改进是在上采样后的高分辨率特征图上做检测或者将采摘点检测放到单独的放大区域。具体流程是第一步检测果实拿到成熟果实的框第二步把框外扩一定比例裁剪出来第三步把裁剪图放大到224×224再在这个放大图上跑一个小的关键点检测模型。这样采摘点识别的精度能得到保证。代价是多一次小模型推理但整体算力占用不大。5.4 模型在实测环境中的性能波动模型在测试集上做得不错到场地上效果变差这是几乎所有农业AI项目的通病。主要原因是训练集与实测环境之间存在domain gap。解决办法快速采集现场图片做半自动标注微调模型或者用大量现场图片做无监督域自适应如果用得上的话。我给的建议是只要条件允许预留一天时间做现场数据采集和微调比在实验室里调半天参数更管用。部署之后还要定期巡检数据分布。番茄从青到红颜色一直在变不同生长期环境背景也在变所以模型最好每周或每两周用新的现场图片做一次在线更新。如果算力有限可以只微调最后几层。5.5 如何量化采摘点定位误差采摘点误差很难直接用mAP衡量。我的做法是先定义一个GT点标注人员手工点果实与果柄连接点模型预测点与GT点之间的距离在图像上小于某像素如8px就算正确。但要真正验证必须在机械臂上进行抓取测试看成功率。我会记录每一次机械臂末端位置与实际果柄的距离积累几十次数据后算出平均定位误差和标准差。这个指标是采摘系统能否稳定的核心。一定要重视相机与机械臂的坐标系标定精度。我踩过最大的坑就是模型识别完美、输出坐标也准但机械臂就是抓偏后来检查发现手眼标定时机械臂读数误差累积了15mm。所以标定做完必须用已知点验证而每个机器人安装环境都需要重新标定。写在最后的一点体会这个项目做到后面我越发觉得农业AI的难点不在算法而在工程。数据要贴合大棚实际标注要定义清楚部署要处理光照和遮挡坐标转换要精确到毫米级。这些活看起来琐碎但每一项都在决定项目能不能落地。我自己的体会是先解决“数据是否够真实、标注是否够清楚”再谈“模型结构是否够新、精度是否够高”。很多人一上来就缠着模型刷点反而忽略了数据清洗和前端后端配合最后往往事倍功半。如果你也想做番茄成熟度识别相关项目不妨先花两周把数据根打牢。有问题欢迎随时交流也希望能听到你们在棚里踩坑的经验共同把这个方向做扎实。