游乐游手机版
首页/AI热点日报/热点详情

基于X3派的智能搬运机器人目标物块识别与抓取

类型:热点整理2026-07-14
基于旭日X3派与颜色识别算法,通过机械结构固定目标物块于摄像头固定位置,利用HSV模型识别特定区域像素颜色,减少环境光干扰,实现精准抓取。识别结果通过串口发送至下位机控制。

智能搬运机器人系列之利用X3派实现目标物块的识别与抓取

本教程将系统讲解如何借助旭日X3派(Horizon X3 Pi)搭配机械结构设计与颜色识别算法,使机器人能够精准识别并抓取目标物块。内容涵盖原理分析、颜色识别代码实现、动作执行逻辑以及下位机控制代码,适合具有基础嵌入式开发经验的读者学习参考。

原理讲解

根据目标物块的特征,首先通过机械结构确保每次识别时,目标物块都处于摄像头的固定角度和固定距离。这样一来,摄像头每次拍摄时,目标物块都会出现在照片中固定的像素区域。

其次,根据目标物块之间的差异仅体现在颜色上,只要对物块所在区域的像素颜色进行识别,即可准确判断具体是哪一个目标物块。因此,本方案采用针对特定区域像素点的颜色识别算法。从演示视频可以看到,每次抓取前,机器人会先通过U型推手将目标物块固定在车身正前方,如下图所示。

此时补光灯开启补光,以减少环境光线对识别结果的干扰。从图片中也能看出,识别阶段摄像头正对目标物块且距离很近,这种设计使得摄像头拍摄到的大部分像素都被目标物块的颜色覆盖,从而增大了识别面积。

可以看到,摄像头拍摄的图像中,目标物块几乎填满了整个画面。接着,旭日X3派借助OpenCV采用HSV颜色模型进行颜色识别,完成对目标物块颜色的判定。

颜色识别

  • 导入所需库文件
import cv2 as cv
import time
import numpy as np
import sys
import os
import serial
import serial.tools.list_ports
  • 配置串口参数,波特率设为115200,使用40PIN中的UART3接口
os.system('ls /dev/tty[a-zA-Z]*')
uart_dev= '/dev/ttyS3' #定义串口端口
baudrate = 115200 #波特率
ser = serial.Serial(uart_dev, int(baudrate), timeout=1)
  • 选择8号相机作为视频输入源
cap_follow = cv.VideoCapture(8)

对获取的图像进行裁剪,仅保留并处理正中央的小块区域

ret, frame = cap_color.read()
#cv.imshow("frame", frame)#代码在电脑上测试时候用于观察,放在X3派上要注释掉
ROI = frame[50:150, 50:200]#get useful ROI

获取一帧图像并裁剪,只保留目标物块的部分像素点。这样做有两个原因:

(1)整帧图像周围包含非目标物块的背景环境,若全部纳入计算会影响识别准确率
(2)缩小图像尺寸可以降低CPU负载,提高运算速度

  • 将裁剪后的图像转换为HSV颜色模型,并创建三个数组分别存储转换后HSV图像中每个像素点的H、S、V通道数值
hsv = cv.cvtColor(ROI, cv.COLOR_BGR2HSV)
#cv.imshow("hsv", hsv)
color_h = []
color_s = []
color_v = []
  • 逐像素取出HSV模型图像中的每个像素点,相加后取平均值(取平均可减少噪点对最终结果的影响)。再将求平均值后的H、S、V三通道数值赋给新变量,用于后续比较判断
color_h.append(np.mean(hsv[:,:,0]))
color_s.append(np.mean(hsv[:,:,1]))
color_v.append(np.mean(hsv[:,:,2]))
h = color_h[0]
s = color_s[0]
v = color_v[0]
  • 将最终数值与预设颜色范围进行比对,确定识别结果,并通过串口将结果发送至下位机
if 35 <= h <= 77 and 43 <= s <= 255 and 46 <= v <= 255:
    print('green')
    ser.write(b'g')
    #red_h 10 --> 20
elif 0 <= h <= 20 and 43 <= s <= 255 and 46 <= v <= 255:
    print('red')
    ser.write(b'r')
elif 156 <= h <= 180 and 43 <= s <= 255 and 46 <= v <= 255:
    print('red')
elif 100 <= h <= 124 and 43 <= s <= 255 and 46 <= v <= 255:
    print('blue')
    ser.write(b'b')
elif 0 <= h <= 180 and 0 <= s <= 255 and 0 <= v <= 46:
    print('black')
    ser.write(b'B')
    #white_v 221 --> 200
elif 0 <= h <= 180 and 0 <= s <= 30 and 180 <= v <= 255:
    print('white')
    ser.write(b'w')
else:
    print('I do not know')
    ser.write(b'e')

下面对串口发送字符的含义进行说明:

g —— green
r —— red
b —— blue
B —— black
w —— white
e —— error(字母'e'表示识别到的颜色不在预设范围内)

为什么选用HSV颜色模型而不是RGB?

RGB是我们最常接触的颜色空间,由红(R)、绿(G)、蓝(B)三个通道表示图像。这三种颜色通过不同组合几乎可以形成所有颜色。然而人眼对这三个分量的敏感程度不同,其中对红色最不敏感,对蓝色最敏感,因此RGB颜色空间均匀性较差。如果直接用欧氏距离度量颜色相似性,结果与人眼视觉会产生较大偏差。对于某种颜色,我们很难精确推测其三个分量的具体数值。因此RGB颜色空间适合显示系统,却不适合图像处理。

在图像处理领域,HSV颜色空间应用更为广泛。它比RGB更接近人类对彩色的感知经验,能够直观地表达颜色的色调、鲜艳程度和明暗程度,便于进行颜色对比(详细解释可参考地平线开发者社区)。

在HSV颜色空间下,比BGR更容易追踪特定颜色的物体,常用于分割指定颜色的目标对象。

HSV表达彩色图像的方式由三个分量组成:Hue(色调、色相)、Saturation(饱和度、色彩纯净度)、Value(明度)。下图圆柱体可表示HSV颜色空间,圆柱横截面近似极坐标系,H用极角表示,S用极轴长度表示,V用圆柱中轴高度表示。

Hue以角度度量,取值范围0~360°,表示色彩信息,即处于光谱颜色的位置,具体如下:

颜色圆环上的所有颜色均为光谱色,从红色开始逆时针旋转,Hue=0表示红色,Hue=120表示绿色,Hue=240表示蓝色等。在RGB中,颜色由三个值共同决定,例如黄色为(255,255,0);而在HSV中,黄色仅由一个值决定,Hue=60即可。HSV圆柱体的半边横截面(Hue=60)图示如下:

其中水平方向表示饱和度,饱和度代表颜色接近光谱色的程度。饱和度越高,颜色越深,越接近光谱色;饱和度越低,颜色越浅,越接近白色。饱和度为0表示纯白色。取值范围0~100%,数值越大颜色越饱和。

竖直方向表示明度,决定颜色空间中颜色的明暗程度。明度越高,颜色越明亮,范围0-100%。明度为0表示纯黑色(此时颜色最暗)。

来源:https://m.elecfans.com/article/2135028.html

相关热点

继续查看同栏目近期热点。

延伸阅读

补充最近整理过的热点入口。