1. 视觉引导基础:机器视觉系统组成、坐标系定义与坐标变换

大家好,我是你们的老朋友。今天咱们正式开讲视觉引导定位的第一章。说实话,我入行那会儿,最头疼的就是坐标系转换。明明相机拍到了,机器人就是抓不准。后来才明白,根子就在坐标系没搞透。

这一章,咱们把地基打牢。我会从系统组成讲起,然后一步步拆解四个坐标系,最后聊聊三种坐标变换。嗯,都是干货,咱们慢慢来。

1.1 机器视觉系统组成

一个典型的视觉引导系统,说白了就是「眼睛 + 大脑 + 手脚」的配合。我习惯把它拆成五个部分:

  • 光源与镜头:给眼睛打光、调焦距。我见过太多项目因为光源角度不对,导致定位精度直接崩掉。
  • 工业相机:核心传感器。CMOS还是CCD?看场景。高速产线我一般选全局快门的CMOS。
  • 图像采集卡/接口:把光信号转成数字信号。GigE、USB3.0、Camera Link,各有各的脾气。
  • 视觉处理单元:工控机或智能相机。跑算法的地方。
  • 执行机构:机器人、运动平台。最终靠它干活。

你想想看,如果光源没选对,再好的算法也白搭。我曾经在一个项目里,因为用了环形光,导致反光件边缘提取全乱套。后来换成背光源,问题秒解。

1.2 四大坐标系定义

这是视觉引导的核心中的核心。我每次培训新人,都会让他们把这四个坐标系刻在脑子里。

1.2.1 世界坐标系 (World Coordinate System)

它是绝对参考系。你可以把它想象成车间里的一个固定点,比如机器人底座中心。所有物体的位置,最终都要换算到这个坐标系下。单位通常是毫米或米。

1.2.2 相机坐标系 (Camera Coordinate System)

以相机光心为原点,Z轴沿光轴方向。这是一个三维坐标系。说白了,相机看到的世界,就是在这个坐标系下的三维点云。

1.2.3 图像坐标系 (Image Coordinate System)

在相机内部,成像平面上的二维坐标系。原点一般在图像中心,单位是毫米。它把三维空间投影到了二维平面上。

1.2.4 像素坐标系 (Pixel Coordinate System)

我们最终看到的图像,就是像素坐标系。原点在左上角,单位是像素(pixel)。注意,它和图像坐标系之间有个缩放和平移关系。

核心关系链:

世界坐标 → 相机坐标 → 图像坐标 → 像素坐标

每一步都对应一个变换矩阵。搞懂了这条链,手眼标定就通了一半。

1.3 坐标变换的数学基础

数学这东西,你把它当成工具就好。我当年学的时候,也是从死记硬背到后来融会贯通。咱们重点讲三种变换。

1.3.1 刚体变换 (Rigid Transformation)

只包含旋转和平移,不改变物体形状。说白了,就是把一个刚体从A位置挪到B位置,它还是它自己。

数学表达:P' = R * P + T

其中R是旋转矩阵,T是平移向量。我建议你用齐次坐标来写,这样旋转和平移可以合并成一个4x4矩阵,计算起来特别方便。

我的小技巧: 实际项目中,刚体变换常用于机器人手眼标定。我曾经用四元数代替欧拉角,避免了万向锁问题,标定一次通过。

1.3.2 仿射变换 (Affine Transformation)

比刚体变换多了一个缩放和剪切。平行线依然保持平行,但角度和长度会变。

数学表达:P' = A * P + T

其中A是2x2矩阵,包含缩放、旋转、剪切。在图像处理中,仿射变换常用于图像校正、模板匹配。

1.3.3 透视变换 (Perspective Transformation)

这是最接近人眼成像的变换。它模拟了「近大远小」的效果。平行线在透视变换下可能相交于一点(灭点)。

数学表达:齐次坐标下,用3x3单应性矩阵H表示。

注意: 透视变换是非线性的。在做视觉引导时,如果相机有倾斜,必须用透视变换来校正。我曾经在一个项目中忽略了这一点,结果定位误差达到了5mm,后来加上透视校正,误差降到了0.2mm。

1.4 知识体系总览

下面这张图,是我自己画的。它把这一章的核心逻辑串起来了。你多看几遍,心里就有谱了。

视觉引导定位知识体系 机器视觉系统组成 四大坐标系定义 坐标变换数学基础 光源与镜头 工业相机 采集卡/接口 视觉处理单元 执行机构 世界坐标系 相机坐标系 图像坐标系 像素坐标系 刚体变换 仿射变换 透视变换 核心逻辑:系统组成 → 坐标系定义 → 坐标变换 → 手眼标定

1.5 实战中的坐标系转换流程

光讲理论不行,咱们来点实际的。下面是一个典型的视觉引导定位流程:

  1. 相机采集图像:得到像素坐标下的特征点位置 (u, v)。
  2. 像素转图像坐标:利用相机内参,把 (u, v) 转成 (x, y),单位毫米。
  3. 图像转相机坐标:加上深度信息(如果有),得到相机坐标系下的三维点 (Xc, Yc, Zc)。
  4. 相机转世界坐标:利用手眼标定得到的变换矩阵,把点转换到世界坐标系下。
  5. 发送给机器人:机器人根据世界坐标去抓取。

关键点: 每一步的精度都会累积。我建议你在每个转换环节都做一次验证,不要等到最后才发现误差。

1.6 一个简单的代码示例

下面是用Python + OpenCV实现像素坐标转世界坐标的示例。代码不长,但很实用。

import cv2
import numpy as np

# 假设我们已经标定好了相机内参和手眼矩阵
camera_matrix = np.array([[fx, 0, cx],
                          [0, fy, cy],
                          [0, 0, 1]], dtype=np.float32)

dist_coeffs = np.zeros((4,1))  # 假设无畸变

# 手眼标定得到的变换矩阵 (相机到世界)
R_cam2world = np.eye(3)
T_cam2world = np.array([[0.1], [0.2], [0.5]])

def pixel_to_world(u, v, Zc):
    # 1. 像素转归一化坐标
    x_norm = (u - cx) / fx
    y_norm = (v - cy) / fy
    
    # 2. 归一化坐标转相机坐标
    Xc = x_norm * Zc
    Yc = y_norm * Zc
    Zc = Zc
    
    # 3. 相机坐标转世界坐标
    P_cam = np.array([[Xc], [Yc], [Zc]])
    P_world = R_cam2world @ P_cam + T_cam2world
    
    return P_world.flatten()

# 示例:像素点 (320, 240),深度 Zc = 500mm
world_point = pixel_to_world(320, 240, 500)
print(f"世界坐标: {world_point}")

注意: 实际项目中,Zc通常由深度相机提供,或者通过标定板上的已知尺寸反算。我习惯用棋盘格标定板,既简单又可靠。

1.7 避坑指南

最后,分享几个我踩过的坑:

  • 坐标系方向搞反:我曾经把相机坐标系的Z轴方向搞反了,结果机器人往地下抓。后来我养成了一个习惯:每次标定完,先用手动模式验证一下方向。
  • 忽略镜头畸变:很多新手直接用原始图像做定位,结果边缘误差很大。记住,一定要先做畸变校正。
  • 单位不统一:有人用毫米,有人用米,还有人用像素。我建议统一用毫米,省得换算出错。

好了,这一章就到这里。内容不少,但都是基础中的基础。你把这些搞懂了,后面学手眼标定就会轻松很多。


专注资料整理