番茄红了,我的代码也红了


一、先说清楚这东西在干什么

果园采摘机器人,听起来是个大工程。实际上拆开看,就三件事:

它知道果在哪——通过摄像头和GPS定位,找出果园里哪些果实熟了。

它规划怎么摘——拿到果实位置之后,算出一条最优采摘路径,同时考虑效率和安全。

它判断熟没熟——看图片里红色的比例,超过阈值就算熟。

围绕这三件事,我写了三个模块,今天把它们串起来跑通了。


二、三个模块各自怎么工作

1. fruit_maturity_detector.py —— 成熟度检测

这个模块做的事很直接:读一张图片,算出画面里有多少比例是红色的。

原理是这样的:

# 读取图片,转成HSV色彩空间
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

# 红色在HSV里的范围比较特殊,要分两段取
# 第一段:h在0-10附近
lower_red = np.array([0, 100, 100])
upper_red = np.array([10, 255, 255])
mask1 = cv2.inRange(hsv, lower_red, upper_red)

# 第二段:h在160-180附近
lower_red2 = np.array([160, 100, 100])
upper_red2 = np.array([180, 255, 255])
mask2 = cv2.inRange(hsv, lower_red2, upper_red2)

# 两段合并
mask = mask1 + mask2

# 红色像素占总像素的比例
red_ratio = np.sum(mask > 0) / (image.shape[0] * image.shape[1])

HSV色彩空间的好处是把颜色(Hue)和明度(Value)分开。红色在H通道里分布在0-10和160-180这两个区间,所以要分两段取,不然会漏掉一半。

判断成熟的阈值默认设的是60%。今天测了一张番茄照片,红色占比69.5%,判定成熟。

2. real_data_interface.py —— 数据接口

这个模块负责和外部数据源对接。测试的时候用的是模拟数据:

def get_field_data():
    # 返回GPS轨迹
    # 返回摄像头画面路径
    pass

def get_robot_position():
    # 返回机器人当前GPS坐标
    pass

设计成接口分离的好处是:以后接真实摄像头,不用动其他模块,只要改这里就行。

3. harvesting_robot_planner.py —— 路径规划

这是核心模块。输入是果实列表(位置+成熟度),输出是采摘动作序列。

采摘动作有四种:

  • move_to(x, y) — 移动到果实位置
  • approach() — 接近目标
  • harvest() — 执行采摘
  • retreat() — 收回机械臂

采摘顺序用贪心算法:每次选最近的那个成熟果实去摘。简单,但够用。

# 按距离排序,优先摘最近的
sorted_targets = sorted(
    targets,
    key=lambda t: math.sqrt((t.x - robot.x)**2 + (t.y - robot.y)**2)
)

效率统计也很直接:摘了多少个果子,总共花了多少时间。


三、端到端测试是怎么跑的

今天跑的 test_end_to_end.py 模拟了一次完整流程:

第一步:生成GPS轨迹
  → 输入:果园地图
  → 输出:机器人在果园里移动的路径点序列

第二步:预测农民活动
  → 输入:GPS轨迹
  → 输出:各个区域的作业状态(有人在摘/空闲)

第三步:检测果实
  → 输入:摄像头画面路径
  → 输出:7个果实的位置和成熟度

第四步:规划采摘路径
  → 输入:果实列表
  → 输出:14个采摘动作(7个果实 × 2个动作:接近+采摘)

第五步:统计效率
  → 输出:7个果子,58秒,平均每果8.3秒

第六步:安全状态检查
  → 输出:当前区域安全,机械臂状态正常

20个测试用例全部通过。中间出过一个小bug:时间单位写成秒但传参时用了分钟,导致显示5.8秒而不是58秒,但不影响计算逻辑本身,改一行就行。


四、怎么跑起来

第一步:装依赖

pip install opencv-python numpy pillow

第二步:跑端到端测试

python test_end_to_end.py

看到 20/20 passed 就对了。

第三步:用自己拍的图片测成熟度

把图片放进 test_images/ 目录,然后:

python test_real_images.py

程序会读目录里的每张图片,输出红色占比和判定结果。


五、项目在哪

GitHub:github.com/AWTX550W/agriculture-robot-planner

代码结构如下:

├── fruit_maturity_detector.py   # 成熟度检测
├── real_data_interface.py       # 数据接口
├── harvesting_robot_planner.py  # 路径规划
├── test_end_to_end.py           # 端到端测试
├── test_real_images.py          # 图片测试
├── test_images/                  # 测试图片(番茄、苹果)
├── gps_trace.json               # GPS轨迹数据
└── requirements.txt              # 依赖列表

六、接下来想做什么

现在整个流程跑通了,但还停在模拟层面。真正有意思的是把真实摄像头接进来。

下一步计划:

  1. 接真实摄像头 — 树莓派或者工业相机,拍一张,处理一张
  2. 机械臂约束验证 — 现在只管路径,不管关节角度,以后要加上
  3. 多机器人协作 — 一片果园多台机器人一起干,怎么分配任务

做这个项目的出发点很简单:下次见到真实的果园,我能知道代码能做什么、不能做什么。这个目标今天算是初步达到了。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐