如何用YOLOv11训练高精度苹果检测模型:从数据标注到边缘部署实战手册

在果园自动化管理和智能分拣系统中,苹果检测一直是计算机视觉落地的典型场景。去年帮助某农业科技公司部署了一套苹果产量预估系统时,我深刻体会到从数据准备到模型部署的全流程中,每个环节都存在需要特别注意的技术细节。本文将分享基于YOLOv11的完整技术方案,特别针对农业场景中的光照变化和小目标检测等难点提供优化策略。

1. 数据准备与标注工程

优质的数据集是模型效果的基石。在苹果检测项目中,数据采集需要覆盖以下关键场景:

  • 多时段光照:清晨逆光、正午强光、傍晚弱光
  • 多生长阶段:幼果期(直径<3cm)、膨大期、成熟期
  • 多遮挡情况:枝叶遮挡(30%-70%遮挡率)、果实重叠

推荐使用X-AnyLabeling进行标注,这款工具相比LabelImg增加了智能辅助标注功能。安装后通过以下命令启动标注服务器:

python anylabeling.py --port 8000 --host 0.0.0.0

标注时要注意的细节:

  1. 对遮挡超过50%的苹果仍需要标注
  2. 反光造成的镜面高光区域不应作为标注边界
  3. 密集小目标建议使用放大镜工具精细标注

标注完成后,建议按以下比例划分数据集:

数据集类型比例图片数量示例
训练集70%3100
验证集15%665
测试集15%665

2. YOLOv11模型训练技巧

YOLOv11相比前代在backbone中引入了EMA权重更新和SIoU损失函数,这对农业场景特别有利。以下是关键训练配置:

# data.yaml
train: ../train/images
val: ../valid/images

nc: 1  # 仅苹果单类别
names: ['apple']

# hyp.yaml
lr0: 0.01
lrf: 0.1
momentum: 0.937
weight_decay: 0.0005
warmup_epochs: 3
warmup_momentum: 0.8
box: 0.05  # box loss增益
cls: 0.3   # 分类loss增益

针对小目标检测的改进策略:

  1. 修改anchor尺寸:通过k-means重新聚类得到适合苹果尺寸的anchor
  2. 增加P2特征层:在原有3个检测头基础上增加160x160分辨率的小目标检测层
  3. 使用SPPF-DWR结构:深度可分离卷积减少计算量

训练命令示例:

python train.py --img 640 --batch 32 --epochs 100 --data data.yaml \
--cfg models/yolov11s.yaml --weights '' --device 0 --hyp hyp.yaml \
--name apple_det --patience 20

3. 农业场景专项优化

3.1 光照适应方案

测试发现模型在逆光场景下AP值下降约15%,采用以下方案改善:

  1. 数据增强组合:

    • HSV色域扰动(H±30%)
    • RandomGamma(gamma=0.5-1.5)
    • 模拟镜头光晕效果
  2. 模型层面:

    # 在model.yaml中添加
    backbone:
      # [...]
      - [CBAM, []]  # 添加注意力模块
    

3.2 密集小目标检测

当苹果间距小于果实直径时易出现漏检,推荐策略:

  1. 数据层面:

    • 对密集区域进行oversampling
    • 使用copy-paste增强
  2. 后处理优化:

    # 修改nms参数
    iou_thres = 0.4  # 原0.6
    conf_thres = 0.2  # 原0.25
    

4. 边缘设备部署实战

在Jetson Xavier NX上的部署优化记录:

  1. TensorRT加速:

    python export.py --weights runs/train/apple_det/weights/best.pt \
    --include engine --device 0 --half
    
  2. 量化对比测试:

    精度模式推理速度(FPS)mAP@0.5
    FP32380.89
    FP16620.885
    INT8(校准后)910.872
  3. 部署代码关键片段:

    class AppleDetector:
        def __init__(self, engine_path):
            self.ctx = cuda.Device(0).make_context()
            with open(engine_path, "rb") as f:
                self.engine = runtime.deserialize_cuda_engine(f.read())
            
        def detect(self, img):
            # 预处理
            img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            img = letterbox(img, new_shape=(640, 640))[0]
            img = img.transpose(2, 0, 1)  # HWC to CHW
            img = np.ascontiguousarray(img)
            
            # 推理
            with self.engine.create_execution_context() as context:
                outputs = do_inference(context, img)
            
            # 后处理
            return non_max_suppression(outputs)
    

5. 实际应用效果验证

在山东某苹果园进行的三个月实地测试显示:

  • 晴天场景:AP@0.5达到92.3%
  • 阴雨天气:AP@0.5保持在86.7%
  • 遮挡情况(40-60%遮挡):检测率81.2%

系统成功将人工抽检耗时从每公顷4小时缩短到20分钟,同时将漏检率控制在3%以下。最令人惊喜的是模型对套袋苹果的识别准确率达到了88%,这超出了初期预期。

Logo

聚焦RDK与具身智能,汇集机器人开发教程、开源案例和技术交流

更多推荐