3. 视觉系统搭建:相机选型、手眼标定与实操

视觉系统搭建,说白了就是给机器人装上一双“眼睛”。这双眼睛怎么选、怎么装、怎么校准,直接决定了抓取的成功率。我在这个领域摸爬滚打了好几年,踩过的坑比吃过的盐还多。今天咱们就聊聊相机选型、手眼标定原理,以及标定板怎么用。

3.1 相机选型:RGB-D vs 单目

选相机这事儿,我建议你先问自己一个问题:你到底需不需要深度信息?

单目相机,说白了就是一个普通摄像头。它只能拍出二维图像,没有深度信息。你想想看,如果只是做平面上的抓取,比如传送带上的工件,单目完全够用。我在一个3C电子组装项目里,就用单目配合模板匹配,抓取精度做到了±0.5mm,成本还低。

但如果你要抓的是堆叠的零件、或者形状不规则的物体,单目就抓瞎了。这时候就得请出RGB-D相机。

RGB-D vs 单目:核心区别

  • 单目:只有RGB图像,深度靠算法估算(比如结构光、运动恢复结构),精度有限,但成本低、速度快。
  • RGB-D:直接输出深度图,比如Intel RealSense、Microsoft Kinect、奥比中光。精度高,但受环境光影响大,室外基本不能用。

我记得有一次,客户非要省钱用单目做立体仓库的抓取。结果因为货物堆叠,单目根本分不清前后层次,抓取成功率不到60%。后来换了RGB-D,直接干到95%以上。所以啊,别在关键地方省钱

对比项 单目 RGB-D
深度信息 无(需估算) 直接获取
成本 低(几百元) 中(几千元)
适用场景 平面抓取、简单识别 堆叠抓取、复杂场景
环境要求 光照稳定 室内、避免强光

我的建议:如果预算允许,直接上RGB-D。别为了省几千块钱,后面花几万块改方案。我见过太多这样的案例了。

3.2 手眼标定原理:Eye-in-Hand vs Eye-to-Hand

相机选好了,接下来就是怎么装。这里有两个经典方案:Eye-in-Hand(眼在手上)Eye-to-Hand(眼在手外)

说白了,就是相机装在机器人末端,还是装在固定位置。

3.2.1 Eye-in-Hand(眼在手上)

相机固定在机器人末端法兰上,跟着机器人一起动。好处是视野灵活,可以近距离观察工件。坏处是每次抓取前都得先“看一眼”,然后计算相对位置。

我在一个汽车零部件抓取项目里用的就是Eye-in-Hand。当时工件位置有偏差,但相机跟着手走,每次都能精准定位。不过要注意,标定的时候需要解算相机坐标系和末端坐标系的关系,这个后面细说。

3.2.2 Eye-to-Hand(眼在手外)

相机固定在工作台上方,机器人动,相机不动。好处是视野固定,适合大范围抓取。坏处是如果工件被遮挡,相机就看不到了。

举个例子,在物流分拣线上,我见过用Eye-to-Hand的。相机挂在传送带上方,机器人从传送带上抓取包裹。这种方案标定相对简单,因为相机和机器人基座的关系是固定的。

核心区别总结

  • Eye-in-Hand:相机跟着手走,适合小范围、高精度抓取。标定复杂,需要解算相机到末端的变换矩阵。
  • Eye-to-Hand:相机固定,适合大范围、固定场景。标定简单,解算相机到机器人基座的变换矩阵。

3.3 标定板使用与实操

标定板,说白了就是一块印着黑白格子的板子。别小看它,手眼标定的精度全靠它。

我刚开始做标定时,总觉得随便打印一张棋盘格就行。结果标定出来的误差大得离谱,抓取时总是偏几毫米。后来才发现,标定板的平整度、格子尺寸精度,直接影响标定结果

3.3.1 标定板的选择

  • 棋盘格:最常用,角点检测稳定。建议用A3或A4大小,格子边长10-30mm。
  • 圆点标定板:适合大角度拍摄,圆心检测精度高。但制作成本高。
  • Charuco板:棋盘格和ArUco码的结合,支持部分遮挡,适合复杂场景。

避坑指南:我曾经用普通打印纸打印标定板,结果纸一皱,标定就废了。建议用亚克力板或铝板,背面贴磁铁,方便固定。

3.3.2 标定流程(以Eye-in-Hand为例)

标定流程其实不复杂,但细节决定成败。我一般按以下步骤来:

  1. 固定标定板:放在机器人工作空间内,确保相机能清晰看到。
  2. 移动机器人:让相机从不同角度拍摄标定板,至少拍10-15张。
  3. 记录位姿:每拍一张,记录机器人末端的位姿(x, y, z, rx, ry, rz)。
  4. 解算变换矩阵:用OpenCV或Halcon解算相机到末端的变换矩阵。
  5. 验证精度:让机器人移动到已知点,看相机检测到的位置是否一致。

这里有个小技巧:拍摄时让标定板占图像面积的1/3到1/2,太小了角点检测不准,太大了容易超出视野。

3.3.3 代码示例(Python + OpenCV)

下面是我常用的标定代码片段,核心就是解算相机内参和外参:

import cv2
import numpy as np

# 棋盘格参数
pattern_size = (9, 6)  # 内角点数量
square_size = 0.025    # 格子边长(米)

# 准备世界坐标系点
objp = np.zeros((pattern_size[0] * pattern_size[1], 3), np.float32)
objp[:, :2] = np.mgrid[0:pattern_size[0], 0:pattern_size[1]].T.reshape(-1, 2)
objp *= square_size

# 存储所有图像的点
objpoints = []  # 世界坐标系点
imgpoints = []  # 图像坐标系点

# 读取图像并检测角点
for fname in image_files:
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, corners = cv2.findChessboardCorners(gray, pattern_size, None)
    if ret:
        objpoints.append(objp)
        imgpoints.append(corners)

# 标定相机
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(
    objpoints, imgpoints, gray.shape[::-1], None, None
)

print("相机内参:\n", mtx)
print("畸变系数:\n", dist)

提示:标定完成后,记得用重投影误差评估精度。一般误差小于0.5像素就算合格。如果误差太大,检查标定板是否平整,或者拍摄角度是否太单一。

3.4 知识体系总览

为了让你更直观地理解本章内容,我画了一张流程图,把相机选型、手眼标定、标定板使用串起来:

视觉系统搭建知识体系 相机选型 单目(平面抓取) vs RGB-D(堆叠/复杂场景) 手眼标定 Eye-in-Hand(眼在手上) vs Eye-to-Hand(眼在手外) 标定板使用与实操 棋盘格 / 圆点板 / Charuco 标定流程 + 代码实现 输出:高精度抓取位姿

这张图把整个视觉系统搭建的流程串起来了。从相机选型开始,到手眼标定,再到标定板实操,每一步都环环相扣。你想想看,如果相机选错了,后面标定再准也没用。所以啊,每一步都要认真对待

本章核心要点

  • 单目适合平面抓取,RGB-D适合复杂场景。别为了省钱选错。
  • Eye-in-Hand灵活但标定复杂,Eye-to-Hand固定但视野受限。
  • 标定板要平整、尺寸精确,别用普通打印纸。
  • 标定流程:固定板 → 多角度拍摄 → 记录位姿 → 解算矩阵 → 验证精度。

好了,这一章就聊到这儿。视觉系统搭建是机器人抓取的“眼睛”,眼睛亮了,后面的活儿才好干。下一章咱们聊聊抓取策略和路径规划,到时候见。


公众号:蓝海资料掘金营,微信deep3321