资讯动态

AI果树修剪:从图像到剪口坐标的视觉定位实践

发布时间:2026/10/20 14:26:28 来源:尧图企业网站定制
这几年做智慧农业相关的视觉项目接触最多的一类需求就是“用算法替老师傅干活”。果树修剪这个活儿看着是体力劳动实际上特别吃经验什么枝该留、什么枝该剪、剪口留多长老果农一眼就有数但要让机器也一眼有数就得把这份经验翻译成坐标数据。最近我正好做完一个“AI自动修剪果树”的模拟项目X输入一张树形图片算法自动识别枝条、定位剪口最后输出修剪点的坐标列表。这套流程跑通之后后续接机械臂或者半自动修剪装置就顺理成章了。这篇文章就把整个项目的核心细节、踩坑记录和实操方案完整拆出来给打算做类似视觉定位项目的朋友一个可以直接参考的底稿。1. 项目整体设计思路把“修剪经验”翻译成坐标1.1 为什么选纯视觉方案果树修剪自动化的第一步是解决“看”的问题。有人会问现在果园里不是有激光雷达、深度相机吗直接用点云做三维重建再规划剪口不是更“高级”确实三维方案在实验室里效果很漂亮但落地到真实果园就会遇到几个麻烦设备成本高一台像样的工业级深度相机价格不低果园环境复杂扬尘、逆光、枝叶遮挡会让点云质量急剧下降点云后期的配准和分割算法维护成本也高一个小果园根本养不起这样的技术团队。所以这个项目我一开始就定了基调先从二维图像入手。二维图片获取成本极低手机、监控摄像头、工业相机都能拍标注难度也比点云小普通农技人员培训一下就能上手而且果实、枝条的视觉特征在二维平面上已经足够明显配合深度学习模型完全能搞定“识别”这一环。核心流程拆开就三件事输入一张清晰的树形图片最好是单一果树、背景相对干净。处理目标检测模型识别所有可见枝条同时定位每个潜在剪口位置。输出每个修剪点的像素坐标以及对应的剪口类型、枝条类别和置信度。1.2 系统整体架构整个项目的软硬件架构可以分成四层第一层是图像采集。我在测试中用了两种设备普通RGB工业相机做静态拍摄以及果园巡检小车上的摄像头做动态采集。前者用于算法迭代后者用于验证实际作业场景的鲁棒性。第二层是预处理。包括图像缩放、光照均衡、去噪以及最关键的外围区域裁切——把地面、天空、周边果树都去掉只保留目标树的主干和冠层。第三层是核心算法。采用“两阶段流水线”第一阶段用目标检测模型找出所有枝条实例同时给枝条分类结果枝、营养枝、徒长枝、枯枝第二阶段基于检测框和图像局部特征定位每个枝条上的“候选剪口点”。第四层是坐标输出。把候选点的像素坐标换算成相对于图像中心的归一化坐标再通过相机标定参数映射到机器人基坐标系。这一步是最后联动机械臂的关键。这套架构的好处是每一层都可以独立替换。比如哪天觉得二维精度不够直接在“剪口定位”这一层换成融合深度信息的方案前面的检测结果照样复用不用推倒重来。2. 数据准备与标注决定算法精度的隐形战场2.1 树形图片采集的讲究很多第一次做农业视觉项目的人都会低估数据采集这件事以为“拿手机去果园拍几百张就行”。实际做下来采集环节直接决定整个管线能不能收敛。首先拍摄角度要统一。我对比过俯拍、平拍、仰拍三种视角下模型的检测表现平拍相机光轴与主干垂直高度大致在果树冠层中部的效果最稳定。俯拍会把枝条重叠关系压扁仰拍则容易把树冠下部的大枝误判为树干增加剪口定位的难度。其次光照条件要覆盖全时段。果园作业经常是早出晚归清晨和傍晚的侧光、正午的顶光、阴天的散射光都会让枝条的边缘特征发生明显变化。项目里我要求采集人员在三个时段分别拍摄上午9点前、中午12点到2点、下午4点后每个时段至少占三分之一。最后背景要“脏而不乱”。纯白背景板拍出来的数据训练效果很好但一上果园就废。真实的果园背景里有杂草、有围栏、有其他树的枝条伸进来这些干扰必须在训练数据里占一定比例。我的做法是干净背景占50%带干扰背景占50%最后模型的泛化能力明显更强。2.2 标注规范剪口不是“一个点”这么简单数据标注是这套流程里最容易被低估的环节。初版项目里我让标注员在每根枝条上随便点一个点当剪口结果模型学出来剪口定位漂移非常严重偏差经常超过20个像素。后来复盘才发现问题出在标注规范太粗糙。重新设计后我把剪口分成三类疏枝剪口整根枝条从基部移除剪口位于枝条与母枝或主干交接处要求剪口平滑、不伤母枝。缩枝剪口保留部分枝条剪口定位在该枝条上某个侧芽或分枝点的前方通常保留长度为5到15厘米。短截剪口针对一年生结果枝剪口位置在枝条中前部饱满芽上方0.5到1厘米处。三种剪口在图像上的位置特征差异很大疏枝剪口紧贴分叉点缩枝剪口要避开侧芽短截剪口则要看芽体位置。如果只用单一关键点标注模型根本学不出这种差异。标注工具方面我尝试过LabelMe和X-AnyLabeling。小团队推荐用X-AnyLabeling它支持检测框、关键点、多边形三种标注模式混合还能调用预训练模型做半自动预标注人工只需要微调能把标注效率提升一倍以上。这里有个技巧先让目标检测模型跑一遍初版推理把检测框和关键点预测结果导入标注工具标注员只需要修改错框、拖动错点而不是从零开始标效率提升非常明显。2.3 数据集规模参考很多朋友问到底要多少张图才能把模型训出来。这个没有固定答案跟我自己的实测数据有关系。单棵果树、单一品种的场景1300到2000张标注图就能让检测模型的mAP达到0.75以上。如果涉及多个品种、多种树形开心形、纺锤形、主干形建议每增加一个品种至少补500张图否则模型会明显偏向于样本量大的那个品种。我个人强烈建议做一次数据难度分级简单样本枝条稀疏、背景干净、光照均匀占30%中等难度枝条中等密度、部分遮挡占50%困难样本多枝重叠、逆光、背景杂乱占20%。这个比例训出来的模型不容易“偏科”。3. 枝条识别与剪口定位模型选型与参数调优3.1 目标检测模型为什么选YOLOv8而不是更“先进”的方案枝条检测本质上是一个密集小目标检测任务一张树形图上可能有几十根枝条而且很多枝条纤细、边缘模糊、互相重叠。初版我对比过几个主流检测模型包括Faster R-CNN、YOLOv8和RTMDet在没有做针对性优化的情况下YOLOv8n的推理速度最快mAP50也能到0.72左右Faster R-CNN虽然精度略高一点点但推理速度差了将近8倍。项目最后选了YOLOv8n作为基线模型。原因很实际我们后续要把模型部署到边缘盒子或者工控机上算力有限而且果园作业要求实时反馈——“算得准但慢”在自动化修剪场景里等于没用。模型结构调整上我给检测头加了一个小改动因为枝条是长条形目标默认的方形anchor效果不好我把anchor ratio从基础的[1, 1]扩展成[0.5, 1, 2, 4]专门适配长条形目标。这个改动让枝条检测框的宽高比误差下降了约15%。训练超参方面直接分享一组我的常用配置输入分辨率640×640经过裁剪处理不进行额外缩放。batch size32受限于显存也可以用梯度累积代替。初始学习率0.01配合余弦退火调度器。训练轮数200轮加了早停机制验证集loss连续20轮不下降就停。数据增强mosaic增强、随机翻转、随机亮度对比度调整、随机遮挡。这里有个值得留意的点mosaic增强对枝条检测是“双刃剑”。它确实能提升模型对遮挡和重叠的鲁棒性但如果mosaic比例调太高模型会学到太多“拼图感”的纹理真实场景上反而掉点。我实测mosaic开启概率0.7是甜点值超过0.9就会有明显过拟合风险。3.2 剪口定位从检测框到关键点的两步跳枝条检测框给出的是“这根枝条在哪”但修剪机械臂需要的是“剪口在哪”这是两个层面的问题。第一阶段我用语义分割把枝条从背景里分离出来得到精准的枝条掩膜。这里U-Net结构就够用不需要上Transformer类的分割模型。掩膜的用处有两个一是过滤掉检测框里混入的背景像素二是为下一步计算枝条骨架做准备。第二阶段是骨架提取和剪口候选点计算。对每条枝条的掩膜做形态学细化得到单像素宽度的骨架线。骨架线的端点就是天然的剪口候选点——注意不是所有端点都是剪口有些端点是枝条被遮挡后断开的伪端点。所以我加了一个“连通性校验”如果某个端点的邻域在图像边缘或者与另一根枝条的掩膜在5像素范围内重叠就判定它为伪端点直接丢弃。当剪口候选点确定后还需要给每个点打分。打分规则结合了三个维度枝条角度与水平方向夹角越大越是直立枝越可能是需要修剪的营养枝、端点距离该点与枝条基部的距离距离太近或太远都要扣分、剪口类型匹配度短截剪口要求附近有饱满芽通过小窗口内的颜色和纹理差异来判断。在这一步我踩过一个很典型的坑骨架细化算法在枝条分叉处会生成多余的细小分支造成剪口候选点多出四成。后来我用“端点角度过滤”解决计算骨架端点处的切线方向与该端点到枝条中心线的夹角夹角小于15度的分支直接合并候选点数量立刻回归正常。3.3 输出修剪点坐标格式与后处理模型最终输出的不只是单一坐标而是一份结构化的修剪方案。我在项目里定义了一个简化的输出格式JSON格式包含这样一些核心信息{ tree_id: sample_001, camera_pose: [0.5, -1.2, 2.1], pruning_points: [ { id: 1, pixel_coord: [320, 245], normalized_coord: [0.62, 0.48], branch_class: sucker, pruning_type: thinning, confidence: 0.93 } ] }normalized_coord是把像素坐标除以图像宽高得到的比例值这样无论后续接机械臂还是做可视化复核坐标都不会因为图像尺寸变化而失效。后处理阶段还有一个关键操作非极大值抑制的改进版。多个剪口候选点如果距离小于10像素只保留置信度最高的那一个如果距离在10到20像素之间额外检查两个候选点是否属于同一条枝条如果属于同一枝条就合并成居中点如果不属于同一枝条说明两条枝条在图像上投影距离很近但仍需区分这种情况保留两个点交给机械臂执行层做避让规划。4. 从像素坐标到机械臂可执行的坐标4.1 相机标定一步都不能省很多做图像算法的朋友容易忽略这一步觉得“反正我用的是归一化坐标机械臂那边自己会转换”。真到联调的时候才发现坐标系不统一后面全是扯皮。我的做法是标准的手眼标定流程。相机固定在机械臂末端或果园作业平台的固定支架上用棋盘格标定板采集15到20组图像计算相机的内参矩阵和畸变系数。然后通过多个视角下的标定板位姿求解相机坐标系到机械臂基坐标系的变换矩阵。标定板的尺寸选择有讲究对于果树这样的大型目标建议用A2以上尺寸的标定板。如果标定板太小在作业距离约1.5到2.5米下只能覆盖画面中心区域标定出来的畸变参数在画面边缘误差很大。标定结果我用重投影误差来验收。具体来说把标定板放在3个不同距离、5个不同角度下让模型找到角点并重投影计算平均像素误差。我给自己定的标准是重投影误差小于0.5像素才能进入联调阶段否则重新采集标定数据。这个标准看起来严格实际多花半小时拍摄能省下后面三天调机械臂的功夫。4.2 深度信息缺失怎么补二维图像最大的短板是没有深度信息。剪口坐标如果是二维的机械臂只能在一个平面内运动显然不符合真实修剪需求。我的方案是“分步逼近”。第一步利用相机标定参数和相机安装高度把二维像素坐标投影到地面高度的水平面上得到三维坐标的初步估计。这个做法基于一个假设果树主干附近的目标其深度与主干深度接近。对于疏枝剪口和缩枝剪口这个假设基本成立。第二步对初步估计的三维点做基于深度相机的局部修正。如果作业环境部署了深度相机那机械臂运动到目标位置附近后深度相机再做一次近距离局部成像在剪口候选点附近搜索局部深度值得到更精确的Z坐标。如果果园没有深度相机也还有一条补救路径基于两张不同视角的图片做三角测量。具体做法是在巡检车行进过程中对同一棵树拍摄两张视差明显的图片利用两帧之间的位姿变换和特征点匹配计算剪口点的三维坐标。这个方法标定复杂一些但在静态果园场景下精度比单目投影高得多。这两条路我都实验过。项目最终采用了“单目全局粗定位 双目局部精定位”的组合方案三维坐标误差控制在3到5厘米范围内。对于果树修剪来说这个精度已经足够。4.3 机械臂执行时的剪口姿态坐标解决了机械臂还要知道“剪刀以什么角度切入”。这里我引入了一个额外的姿态参数。剪口的切入方向由枝条骨架线的局部切线方向决定。在剪口候选点附近取前后各10个像素的骨架点做最小二乘直线拟合得到切线方向角θ。然后把这个方向角传到机械臂控制接口让末端执行器的剪刀平面垂直于该切线方向。这一步非常重要如果剪刀切入方向与枝条走向不垂直剪口容易劈裂造成果树伤口愈合不良。实际联调中我发现机械臂执行时还要考虑作业顺序。策略是“先下后上、先外后内”优先修剪树冠外围低处的枝条再逐步处理内部和高处的枝条。这样做可以避免剪掉的枝条下落时砸到机械臂或挡住相机视线干扰后续定位。5. 部署测试与典型问题排查5.1 模型推理速度与硬件选型模型跑通之后要考虑实际部署硬件。我测试过两种方案一种是在工控机上用GPU推理另一种是在边缘计算设备上做量化推理。GPU方案用了常见的推理加速框架YOLOv8n模型加上U-Net分割640×640输入下整体推理耗时约35毫秒换算出来大概能跑到28FPS。边缘盒子方案则需要做INT8量化推理速度降到约60毫秒但好处是整机功耗低、体积小可以直接装在巡检小车上。在模型压缩方面我其实更推荐用“剪枝蒸馏”的组合而不是单纯的量化。训练时让大模型YOLOv8m做教师蒸馏到小模型YOLOv8n上同时配合通道剪枝去掉冗余卷积核。这个组合方案比直接训练小模型能提升约6%的mAP。这里还要提醒一个性能陷阱数据处理管线的瓶颈往往不在模型本身而在图像预处理和坐标后处理。我用多线程管线把图像解码、缩放、归一化和后处理放到独立线程与模型推理并行执行整体端到端延迟从130毫秒降到了70毫秒效果立竿见影。如果你排查后发现模型推理很快但整体延迟高优先检查这一块。5.2 枝条重叠与遮挡剪口候选点丢失怎么办这是整个项目里最顽固的问题。果树冠层内部枝条密集互相遮挡极其严重很多候选剪口在图像上根本不可见。我试过几种应对策略多视角融合巡检车围着树转一圈采集多张图片把不同视角下检测到的剪口点投射到统一坐标系里做融合。这个方案效果最好但需要解决跨视角的同一枝条匹配问题工程复杂度高。可见性预判利用骨架线的连续性预测被遮挡枝条的延伸方向把剪口候选点外推到遮挡物边缘。这个办法在遮挡不太严重时有效但它本质上是“猜”置信度不能设得太高。语义规则兜底如果某个枝条的剪口点置信度低于阈值直接触发决策规则——比如“超过5毫米粗的枝条必须保留剪口点”由调度程序将这条任务标记为“需人工复核”。项目最终采用的方式是第三种兜底加多视角融合相结合效果最为稳健也方便和农艺师的复核流程对接。5.3 光照变化与阴影干扰的排查清单果园里的光照变化比室内复杂得多我整理了一份排查清单遇到识别异常时可以按顺序检查第一步检查是否过曝或欠曝。果树冠层阴暗差异极大直射光下容易出现局部过曝。建议在采集端开启HDR模式或使用自动曝光补偿让枝条边缘的梯度信息尽量保留。第二步检查是否有大面积阴影块。阴影会让枝条颜色特征失真导致检测框漂移。处理办法是在预处理阶段增加一个“阴影检测”模块用亮度通道的局部直方图分布来判断是否存在阴影区若存在则对该区域做局部直方图均衡化。第三步检查地面反光。很多果园地面铺反光膜阳光反射会把树冠下部照亮导致模型把地面反光误识别为枝条。这个场景我建议用“垂直边缘响应”做过滤——真实枝条在图像上会有明显的双向边缘而反光区域的边缘响应通常只在单方向强烈二者可以通过梯度方向直方图区分。5.4 不同树形和品种的泛化问题换一个果树品种模型往往就不太灵了。这背后有两个原因一是不同品种的枝条颜色、纹理差异大二是在不同修剪体系下比如桃树的“开心形”和苹果树的“纺锤形”枝条分布密度和层次感完全不同。做泛化测试时我在桃树数据上训练的模型直接测试苹果树的数据mAP从0.78掉到0.41几乎不可用。但加了几百张苹果树的图像做微调之后mAP又回到了0.72。这说明模型的特征提取能力是够的缺的是对新品种分布的认识。进一步的方案是“域自适应”用少量目标品种的未标注图片在特征提取器输出层加入对抗学习分支让网络学会“忽略”品种差异、专注枝条结构特征。这样即使不加标注数据也能把mAP提升到0.6左右作为冷启动方案效果不错。6. 实操经验与后续扩展方向6.1 我从这个项目里总结的几条心得数据规范比模型结构更值得花时间。我一度执着于改网络结构效果提升一直很小后来回头优化标注规范和采样平衡mAP提升幅度远超调结构。二维视觉方案不是“将就”而是工程上最优解。很多场景根本不需要三维点云那种“全面但昂贵”的感知能力二维图像加上合理的几何假设和分步逼近就能达到落地要求关键是想清楚每步的误差来源和补偿方式。人机协作是当前更现实的落地形态。现阶段“全自动修剪”在技术和法规上都不成熟但“AI辅助修剪员”已经可以落地——算法输出候选剪口农技人员在移动终端确认并微调再由机械装置执行。这个流程既降低了劳动强度保留了农业专家的判断力也避开了复杂场景下的长尾问题。6.2 这套方案还能怎么扩展剪口定位解决了“剪哪里”的问题接下来更自然是“怎么剪”和“剪完怎么处理”。切口状态评估在剪口执行后拍摄切口照片识别切口是否平整、是否劈裂、是否感染病菌。这相当于把质量控制闭环加进来。修剪量估算基于检测到的枝条数量和剪口位置估算单棵树的修剪量进一步推算果园整体的修剪工作量调度作业计划。剪口保护剂喷洒规划修剪后需要涂抹愈合剂可以基于剪口坐标规划机械臂的喷洒路径提高作业效率减少药剂浪费。多年连续修剪记录逐年保存每棵树的修剪方案和树形图片训练一个生长预测模型结合当年的环境数据提前为下一年的修剪策略提供参考。未来如果想让这套系统真正在果园里无人机化、全天候作业核心逻辑都是相通的把农业经验数字化把数字化结果坐标化再把坐标变成机器的动作指令。6.3 最后一个实用小技巧最后分享一个很实用的小技巧是我在实际测试中发现的在做骨架提取之前先对枝条掩膜做一次小的闭运算操作。很多真实图像中枝条存在宽窄不均的情况闭运算可以填补枝条内部的小空洞让骨架线更连续剪口定位的稳定性显著提升。kernel size用5×5就够太大会让骨架线过度平滑反而丢失真实的剪口位置信息。另外如果需要在移动端或低算力设备上运行整套流程建议把目标检测和剪口定位的两段模型合并成一个多任务网络。共用主干检测头只输出枝条框和分类在检测框内部额外接一个轻量关键点头。这样端到端推理耗时可控制在40毫秒以内而且两个任务的特征可以互相增强比单独跑两个模型精度更高。这个项目从最初的“试试看”到能稳定输出剪口坐标走了不少弯路但最终的架构和方案基本验证了“二次元视觉足够启动果树修剪自动化”这个判断。如果你也在做类似的农业视觉项目希望这篇记录能帮你少踩几个坑更快把算法跑起来。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑