当前位置:首页>农业>智慧农业采摘革命:基于ROS与YOLO-Pose关键点检测的水果采摘点识别数据集全解析

智慧农业采摘革命:基于ROS与YOLO-Pose关键点检测的水果采摘点识别数据集全解析

  • 2026-10-25 11:11:36
智慧农业采摘革命:基于ROS与YOLO-Pose关键点检测的水果采摘点识别数据集全解析

人口老龄化与劳动力短缺正严重制约水果种植业发展,智能采摘机器人成为破解“谁来种地、谁来采收”困局的关键。而机器人能否精准、无损地完成采摘,核心在于对果实采摘点的视觉定位能力——这要求算法不仅要检测果实,还需精确识别果梗等关键部位。本文深入解析一个专为水果采摘机器人设计的视觉感知数据集,包含937张图像、标注2,500个果实及3个关键特征点,并提供基于YOLO-Pose v11在ROS环境下的训练与部署代码,助力精准农业与机器人自动化。

📊 数据集核心档案

属性
详情
数据集名称
水果采摘点关键点检测数据集
总图像量937张
标注目标数约2,500个
水果实例
水果种类
苹果、橘子、草莓 (或其他需采摘的果实)
标注格式
边界框 (Bounding Box) + 3个关键点 (Keypoints)
关键点定义
底部、顶部、采摘点 (果梗/果柄)
任务类型
目标检测 + 姿态估计 (YOLO-Pose)
配套资源
多个微调模型权重 (result1.pt, result2.pt) + ROS推理脚本
核心应用
农业采摘机器人视觉系统、精准农业自动化

🔍 数据集深度剖析

🎯 三个关键点,直指采摘核心

该数据集的最大特色在于关键点的任务导向设计:

  1. 底部 (Bottom)
    :果实与果梗的连接处下方,辅助定位果实整体方位。
  2. 顶部 (Top)
    :果实远离果梗的一端,用于判断果实大小和朝向。
  3. 采摘点 (Picking Point)
    :核心关键点,即果梗或果柄的切断位置。机器人末端执行器需精确移动至此,完成无损采摘。

通过检测这三点,可推导出果实的姿态、成熟度(通过大小)以及最优剪切角度,为机械臂规划提供充分视觉信息。

🍎 多类水果,挑战通用性

数据集包含苹果、橘子、草莓等形态、大小、颜色差异显著的水果,对模型的跨物种通用性和细粒度特征提取能力提出高要求。训练出的模型有望在不同果园场景中部署。

📈 数据规模与应用场景

937张图像、2,500个实例的规模属于中小型专用数据集,但结合迁移学习足以训练出可用的采摘点检测模型。其配套的ROS推理模块表明该数据集天然面向机器人实际部署,而非仅学术研究。

🚀 实战代码:基于YOLO-Pose v11的采摘点检测

以下提供基于Ultralytics YOLO-Pose v11的训练、评估与ROS接口核心代码,并演示如何调整OKS权重以匹配采摘点精度需求。

1. 环境准备

pip install ultralytics rospy cv-bridge sensor-msgs  # ROS环境需额外安装

2. 数据集准备与关键点配置

假设数据标注为YOLO-Pose格式(class_id x_center y_center width height kp1_x kp1_y kp1_v kp2_x kp2_y kp2_v ...),关键点顺序为:底部、顶部、采摘点。

创建数据集配置文件 fruit_picking.yaml:

# ============================================================
# 场景:水果采摘点关键点检测 - YOLO-Pose配置
# 关键:定义3个关键点及其可见性,调整OKS权重
# 经验:采摘点(索引2)权重最高,以优化采摘精度
# ============================================================
path: ./fruit_picking_dataset  # 数据集根目录
train: images/train
val: images/val
test: images/test  # 可选

nc:1# 类别数 (此处假设为'fruit'一类,可细分)
names:['fruit']

# 关键点定义 (YOLO-Pose要求)
kpt_shape:[3,3]# [num_kpts, num_dims] -> 3个关键点,每个有x,y,visible
# OKS权重: 用于计算关键点相似度 (必须与kpt_shape对应)
# 底部:0.05, 顶部:0.05, 采摘点:0.1 (突出其重要性)
kpt_weights:[0.05,0.05,0.1]

3. 模型训练 (迁移学习 + 关键点损失调优)

# ============================================================
# 场景:水果采摘点检测 - YOLO-Pose v11训练
# 策略:使用COCO预训练的pose模型,冻结骨干网络前几层
# 调优:重点关注关键点损失,调整OKS权重已体现在配置中
# ============================================================

from ultralytics import YOLO
import wandb

wandb.init(project="fruit-picking-pose", name="yolov11-pose-finetune")

# 加载预训练的YOLO-Pose模型 (v11)
model = YOLO('yolo11n-pose.pt')# 或 yolo11s-pose.pt

# 训练参数
results = model.train(
    data='fruit_picking.yaml',
    epochs=120,
    imgsz=640,
    batch=12,
    device=0,
    workers=4,
    optimizer='AdamW',
    lr0=0.0005,# 较低学习率,保护预训练关键点特征
    lrf=0.01,
    momentum=0.937,
    weight_decay=0.0005,
    warmup_epochs=3,
# ----- 关键点损失权重 (在ultralytics中通过loss配置) -----
# 在YOLOv11中,关键点损失(pose loss)权重可通过配置文件调整,此处为示意
# 实际可在模型yaml中修改 loss_kpt 参数
    box=7.5,# 框损失增益
    cls=0.5,# 分类损失
    dfl=1.5,# DFL损失
    pose=12.0,# 关键点损失增益 (可调大,突出关键点学习)
    kpt_obj=1.0,# 关键点目标损失
# ----- 数据增强 (对关键点敏感) -----
    mosaic=1.0,
    mixup=0.1,
    copy_paste=0.0,# 复制粘贴可能破坏关键点语义,关闭或降低
    hsv_h=0.015, hsv_s=0.7, hsv_v=0.4,
    degrees=10,# 小角度旋转
    scale=0.5,
    fliplr=0.5,# 水平翻转 (需确认是否改变关键点顺序)
    project='runs/train',
    name='fruit_pose_exp',
    exist_ok=True
)

print(f"最终Pose mAP@0.5: {results.results_dict['metrics/pose_mAP_0.5']:.4f}")

4. 模型评估与采摘点精度分析

# ============================================================
# 场景:评估模型在验证集上的关键点精度
# 关注:采摘点(第3个关键点)的OKS和平均误差
# ============================================================

from ultralytics import YOLO
import numpy as np

model = YOLO('runs/train/fruit_pose_exp/weights/best.pt')

# 验证并获取详细指标
metrics = model.val(data='fruit_picking.yaml', split='val', plots=True)

# 解析关键点指标 (假设输出中包含)
# 手动计算采摘点平均欧氏距离误差 (需要真实和预测坐标)
# 此处为示意框架
defcalc_kpt_error(results, kpt_index=2):
"""计算指定关键点(索引)的归一化欧氏距离误差"""
    total_error =0
    count =0
for result in results:
if result.keypoints isnotNone:
# 获取预测关键点 (xy坐标)
            pred_kpts = result.keypoints.xy[0].cpu().numpy()# [3, 2]
# 此处需从数据集中获取真实关键点,简化省略
# error = np.linalg.norm(pred_kpts[kpt_index] - gt_kpts[kpt_index])
# total_error += error
            count +=1
    avg_error = total_error / count if count else0
print(f"采摘点平均归一化误差: {avg_error:.4f}")
return avg_error

# 注意:实际需配合数据集真实标注计算,这里仅演示结构

5. ROS接口集成 (核心部署模块)

#!/usr/bin/env python3
# ============================================================
# 场景:ROS节点,订阅摄像头图像,发布采摘点坐标
# 功能:加载训练好的YOLO-Pose模型,执行推理,提取采摘点
# 消息:发布采摘点的3D坐标 (相机坐标系) 用于机械臂规划
# ============================================================

import rospy
import cv2
import torch
import numpy as np
from sensor_msgs.msg import Image
from geometry_msgs.msg import PointStamped
from cv_bridge import CvBridge
from ultralytics import YOLO

classFruitPickingNode:
def__init__(self):
        rospy.init_node('fruit_picking_pose', anonymous=True)
        self.bridge = CvBridge()
# 加载模型 (使用训练好的result2.pt)
        self.model = YOLO('path/to/result2.pt')# 替换为实际权重路径
# 发布采摘点 (相机坐标系)
        self.pub_pick = rospy.Publisher('/fruit/picking_point', PointStamped, queue_size=10)
# 订阅图像话题 (根据实际相机调整)
        self.sub_img = rospy.Subscriber('/camera/rgb/image_raw', Image, self.image_callback)
        rospy.loginfo("YOLO-Pose 采摘节点已启动,等待图像...")

defimage_callback(self, msg):
try:
            cv_img = self.bridge.imgmsg_to_cv2(msg,'bgr8')
except Exception as e:
            rospy.logerr(f"图像转换失败: {e}")
return

# 执行推理 (指定关键点置信度阈值)
        results = self.model(cv_img, conf=0.25, iou=0.45, kpt_conf=0.3)

# 处理检测结果
for result in results:
if result.keypoints isnotNone:
# 提取置信度最高的目标 (或根据需求选择)
                kpts = result.keypoints.xy[0].cpu().numpy()# [3, 2]
                confs = result.keypoints.conf[0].cpu().numpy()if result.keypoints.conf isnotNoneelse[1,1,1]

# 找到采摘点 (索引2)
                pick_point = kpts[2]# (x, y) 像素坐标
                pick_conf = confs[2]

if pick_conf >0.5:# 置信度过滤
# 像素坐标转相机坐标系 (需相机内参和深度信息)
# 此处仅发布像素坐标示例,实际应使用深度图或双目视差计算3D点
                    point_msg = PointStamped()
                    point_msg.header = msg.header
                    point_msg.point.x = pick_point[0]
                    point_msg.point.y = pick_point[1]
                    point_msg.point.z =0.0# 假设深度已知或由其他方式获取
                    self.pub_pick.publish(point_msg)
                    rospy.loginfo(f"发布采摘点: ({pick_point[0]:.1f}, {pick_point[1]:.1f})")

# (可选) 可视化并发布带关键点的图像
        annotated_frame = results[0].plot()
        annotated_msg = self.bridge.cv2_to_imgmsg(annotated_frame,'bgr8')
# pub_img.publish(annotated_msg)  # 若定义了发布者

if __name__ =='__main__':
try:
        node = FruitPickingNode()
        rospy.spin()
except rospy.ROSInterruptException:
pass

📝 关键注释与优化建议

  1. OKS权重调整
    :这是提升采摘点精度的关键。在kpt_weights中给予采摘点(索引2)更高权重(如0.1),模型在训练时会更侧重于优化该点的定位误差。
  2. 损失函数调参
    :在YOLO-Pose中,可调整pose(关键点总损失)和kpt_obj(关键点目标损失)的增益。建议从小数据集开始网格搜索最佳比例。
  3. 数据增强限制
    :对于关键点任务,水平翻转需谨慎,若翻转会改变左右关键点语义(如采摘点始终在果梗侧),则需关闭或配合标注修改。旋转和缩放是安全的增强。
  4. 3D定位扩展
    :当前视觉仅输出2D像素坐标。在真实机器人系统中,需结合深度相机(如Intel Realsense)或双目视差,将2D点投影到三维空间,发布PointStamped消息供moveit等规划模块使用。

🏷️ 拓展思考与行业趋势

  • 从2D到3D姿态估计
    :当前标注为2D关键点,若引入多视角标注或深度数据,可训练3D姿态估计模型,直接输出采摘点在机器人基坐标系下的空间坐标,简化手眼标定流程。
  • 成熟度关联预测
    :可扩展标注,增加果实成熟度标签,使机器人在一次检测中同时决定“采或不采”,实现选择性收获。
  • 动态场景适应
    :果园环境中果实在风中摆动、枝叶遮挡频繁。引入时序信息(视频流)和跟踪算法(如ByteTrack),能提升系统在复杂自然条件下的稳定性。

🔖 文章标签

#农业机器人 #水果采摘 #YOLOPose #关键点检测 #ROS #智慧农业 #自动采收 #精准农业 #计算机视觉 #机器人控制

最新文章

随机文章