C# 机器视觉实战:单相机引导机械手精准贴合,从拍照、偏差计算(平移+旋转)到坐标补偿全解

C# 机器视觉实战:单相机引导机械手精准贴合,从拍照、偏差计算(平移+旋转)到坐标补偿全解

想象你让机械手把一个零件贴到指定位置:机械手本身能重复走到同一个点,但每次来料摆放总有偏差、治具有误差,如果"闭着眼"直接贴,难免错位。视觉引导就是给机械手装上"眼睛"------相机先拍一张,算出这次来料相对标准位置"偏了多少",再让机械手往回补偿这点偏差,就能精准贴合。本文基于一份《单相机机械手引导》PPT,把固定相机引导的布局、坐标系、纯平移与带旋转的偏差补偿原理讲透,并给出可直接套用的 C# 实现,适合做机器视觉/自动化的初学者,也适合复习回顾。


一、什么是机械手视觉引导

机械手视觉引导,是用相机获取目标(产品、特征点)的位置,引导机械手完成抓取、装配、贴合等动作。常见场景:屏幕/镜片贴合、FPC/连接器插件、零件装配、散乱抓取、上下料等。

它解决的核心问题是:机械结构和来料存在误差,纯"示教再现"无法保证每次都准,需要用视觉实时测量并补偿偏差。

相机的安装方式主要分两种:

对比项 固定相机(Stand-alone / Fixed) 相机装在机械手上(Eye-in-Hand)
安装 相机固定在机架上,不动 相机随机械手一起运动
拍照 机械手把产品移动到固定拍照位 机械手移动到产品上方拍照
标定 相机坐标 ↔ 机械手坐标(一次标定) 手眼标定(眼在手)
特点 稳定、节拍可预期,本文采用 灵活、视野可变,标定相对复杂

本文采用**固定相机、镜头朝上(下往上看)**的方案。


二、方案布局与整体流程

2.1 布局

相机固定安装在工作台下方/机架上,镜头朝上;机械手抓取产品移动到相机上方的拍照位,相机从下往上拍摄产品特征:

2.2 整体工作流程

整体是一个"示教一次、每次补偿"的循环:先标定/示教得到基准;每次来料拍照、算偏差(有旋转则先旋正);把偏差补偿到基准贴合坐标,机械手精准贴合:


三、三个坐标系与标定、示教

理解引导,先要分清几个"坐标":

坐标 含义
机械手坐标 机械手底座坐标系下的位置(X, Y, 角度),贴合动作最终用它
相机坐标 视觉测量到的特征位置。视觉直接输出的是像素坐标
基准(示教)坐标 示教时记录的标准位置,是补偿的"参照"

标定 :视觉输出的是像素坐标,而机械手只认机械手坐标,两者之间需要通过标定建立映射

(固定相机常用九点标定,本质是求一个仿射变换;Eye-in-Hand 用手眼标定)。标定后,视觉

就能直接输出"机械手坐标系下的特征坐标"。

示教两个基准(本方案的关键):

  1. 一个标准产品放到正好贴合 的位置,记录此时机械手坐标,即基准贴合坐标 (Xt, Yt);
  2. 产品在拍照位,记录视觉输出的基准特征坐标 (X0, Y0)。

说明:本文 PPT 直接在"机械手坐标系"下列出坐标来算偏差,即默认标定已经完成、视觉
输出的已是机械手坐标
。本文聚焦"标定之后,如何算偏差并补偿";九点/手眼标定是另一个

主题,实际项目中务必先做好标定。


四、纯平移引导:偏差计算与补偿

先看最简单、也最常见的情况:产品只有位置偏移(X、Y),姿态(角度)不变。

4.1 计算思路

  • 基准拍照坐标:(X0, Y0)
  • 当前来料拍照坐标:(X1, Y1)
  • 当前相对基准的偏差:
text 复制代码
Dx = X0 - X1
Dy = Y0 - Y1

把这个偏差补到基准贴合坐标上,得到本次贴合坐标:

text 复制代码
贴合 X = Xt + Dx
贴合 Y = Yt + Dy

4.2 数字例子(对应 PPT)

项目 坐标
贴合位置机械手坐标 (Xt, Yt) (100, 100)
基准拍照坐标 (X0, Y0) (50, 100)
当前来料拍照坐标 (X1, Y1) (40, 120)

计算:

text 复制代码
Dx = 50 - 40 = 10
Dy = 100 - 120 = -20

本次贴合坐标 = (100 + 10, 100 - 20) = (110, 80)

直观理解:相机发现这次特征比标准位置"偏了",就让机械手在标准贴合点基础上反向挪同样的

量,正好把误差抵消。下图展示了基准点、当前点与偏差向量:


五、有旋转:点绕点旋转公式与综合补偿

当产品不仅有平移、还转了一个角度 a 时,直接比 X、Y 就不准了------旋转之后,点的 x、y
都会发生变化
。需要先做坐标旋转换算,再算偏差。

5.1 点绕点旋转公式

点 A(x, y) 绕中心点 B(rx0, ry0) 旋转角度 a(弧度,逆时针为正)后得到

C(x0, y0),公式为:

text 复制代码
x0 = cos(a)·(x - rx0) - sin(a)·(y - ry0) + rx0
y0 = sin(a)·(x - rx0) + cos(a)·(y - ry0) + ry0

含义:先把坐标平移、让旋转中心变成原点(减去 rx0、ry0),做二维旋转,再平移回去。

示意图如下:

注意:C# 的 Math.Cos/Sin 用的是弧度 ,角度要先 角度 × π/180 换算。

5.2 平移 + 旋转综合补偿(对应 PPT 第 6 页)

综合步骤:

  1. 基准:贴合坐标 (Xt, Yt)、基准拍照 (X0, Y0);
  2. 当前:拍照 (X1, Y1),角度 a;
  3. 用旋转公式,以基准拍照点为参考把当前特征旋正(消除姿态差);
  4. 再按第四节方法算位置偏差 Dx、Dy,角度偏差 Da = a;
  5. 补偿:贴合坐标 (Xt + Dx, Yt + Dy, 0 + Da)。

角度的正负、旋转方向(顺时针/逆时针)必须和具体机器人的坐标系定义一致,实际调试时

以标定方向为准,下面代码给出通用框架并做了注释。


六、C# 代码实现

下面把"点旋转、纯平移补偿、平移+旋转综合补偿"封装成可复用方法,注释尽量详细。

csharp 复制代码
using System;

/// <summary>
/// 二维点(表示机械手坐标系下的一个位置)
/// </summary>
public class Point2D
{
    public double X;
    public double Y;

    public Point2D(double x, double y)
    {
        X = x;
        Y = y;
    }
}

public static class RobotGuide
{
    /// <summary>
    /// 点 p 绕中心点 center 旋转 angleDeg 度,返回旋转后的点
    /// 对应公式:
    ///   x0 = cos(a)·(x-rx0) - sin(a)·(y-ry0) + rx0
    ///   y0 = sin(a)·(x-rx0) + cos(a)·(y-ry0) + ry0
    /// </summary>
    /// <param name="p">待旋转的点</param>
    /// <param name="center">旋转中心</param>
    /// <param name="angleDeg">旋转角度(度,逆时针为正)</param>
    public static Point2D RotatePoint(Point2D p, Point2D center, double angleDeg)
    {
        // Math.Cos/Sin 使用弧度,先把角度换算成弧度
        double rad = angleDeg * Math.PI / 180.0;
        double cos = Math.Cos(rad);
        double sin = Math.Sin(rad);

        // 平移到以旋转中心为原点
        double dx = p.X - center.X;
        double dy = p.Y - center.Y;

        // 二维旋转后再平移回去
        return new Point2D(
            cos * dx - sin * dy + center.X,
            sin * dx + cos * dy + center.Y);
    }

    /// <summary>
    /// 纯平移补偿:根据基准拍照点与当前拍照点的偏差,修正示教贴合坐标
    /// </summary>
    /// <param name="teachTie">示教的基准贴合坐标 (Xt,Yt)</param>
    /// <param name="baseCcd">基准拍照坐标 (X0,Y0)</param>
    /// <param name="curCcd">当前来料拍照坐标 (X1,Y1)</param>
    /// <returns>本次应贴合的坐标</returns>
    public static Point2D TranslateCorrect(Point2D teachTie, Point2D baseCcd, Point2D curCcd)
    {
        // 当前相对基准的偏差
        double dX = baseCcd.X - curCcd.X;
        double dY = baseCcd.Y - curCcd.Y;

        // 把偏差补到基准贴合坐标上
        return new Point2D(teachTie.X + dX, teachTie.Y + dY);
    }

    /// <summary>
    /// 平移 + 旋转综合补偿,返回本次贴合的 X、Y 和角度
    /// </summary>
    /// <param name="teachTie">示教贴合坐标 (Xt,Yt)</param>
    /// <param name="teachA">示教贴合角度(一般为 0)</param>
    /// <param name="baseCcd">基准拍照坐标 (X0,Y0)</param>
    /// <param name="baseA">基准拍照姿态角</param>
    /// <param name="curCcd">当前拍照坐标 (X1,Y1)</param>
    /// <param name="curA">当前拍照姿态角</param>
    public static (double X, double Y, double A) GuideCorrect(
        Point2D teachTie, double teachA,
        Point2D baseCcd, double baseA,
        Point2D curCcd, double curA)
    {
        // 1. 角度偏差:当前相对基准转了多少
        double dA = baseA - curA;

        // 2. 以基准拍照点为中心,把当前点旋转 dA,旋正到与基准相同姿态
        //    (旋转方向若与机器人定义相反,这里取 -dA,按现场标定调整)
        Point2D rotated = RotatePoint(curCcd, baseCcd, dA);

        // 3. 姿态一致后,按纯平移方法算位置偏差
        double dX = baseCcd.X - rotated.X;
        double dY = baseCcd.Y - rotated.Y;

        // 4. 补偿到基准贴合坐标,得到本次最终贴合位姿
        return (teachTie.X + dX, teachTie.Y + dY, teachA + dA);
    }

    // 简单自测
    public static void Test()
    {
        // 纯平移例子:基准贴合(100,100),基准拍照(50,100),当前拍照(40,120)
        var tie = TranslateCorrect(
            new Point2D(100, 100),
            new Point2D(50, 100),
            new Point2D(40, 120));
        Console.WriteLine($"纯平移贴合坐标:({tie.X}, {tie.Y})"); // (110, 80)
    }
}

实际工程中,视觉算出的特征点(已标定到机械手坐标)作为 curCcd 传入,方法返回值直接

作为机械手的目标位姿即可。


七、常见坑与注意事项

  1. 没做标定或标定不准:像素坐标不能直接当机械手坐标用,先做好九点/手眼标定并验证。
  2. 坐标系方向不一致:相机 X/Y 方向、原点与机械手可能不同,标定/换算时方向要对齐。
  3. 角度单位搞错 :Math.Cos/Sin 用弧度,记得换算;角度正负方向以机器人定义为准。
  4. 旋转后直接比 X/Y:有角度时必须先用旋转公式旋正,否则位置偏差算错。
  5. 基准选取不规范:示教要用"正好贴合"的标准产品,基准拍照点要稳定、特征清晰。
  6. 拍照位不一致:固定相机方案要保证每次产品被送到同一拍照位、高度一致,避免视野/缩放变化。
  7. 补偿方向反了:偏差是"基准 − 当前",补偿是加到贴合坐标;方向反了会越补越偏,可先用小量验证。
  8. 忽略角度对位置的耦合:旋转中心选取会影响结果,多轴/大角度场景建议用机器人自带的姿态变换或完整手眼方案。

八、小结

  1. 视觉引导的本质:相机测出当前相对基准 的偏差,让机械手在基准动作上补偿这点偏差;
  2. 固定相机方案:相机不动、镜头朝上,机械手送产品到固定拍照位,需做相机↔机械手标定;
  3. 示教记录两个基准:贴合坐标 (Xt,Yt) 和基准拍照坐标 (X0,Y0);
  4. 纯平移:Dx = X0-X1、Dy = Y0-Y1,贴合坐标 (Xt+Dx, Yt+Dy);
  5. 有旋转:先用点绕点旋转公式把当前特征旋正,再算 Dx、Dy、Da,补偿位置和角度;
  6. 注意弧度换算、坐标方向、旋转中心与补偿方向。

建议对照本文代码,用实际相机和机械手(或仿真)跑一遍"示教 → 拍照 → 补偿 → 贴合",

能很快建立对视觉引导的整体认识。

相关推荐
智能直播1 小时前
RK3528 RGA+DRM框架 HDMI out视频输出:从多图层合成到显示送显
视觉检测·音视频·实时音视频·视频编解码
慧都小妮子1 小时前
Stimulsoft 2026.4 发布:Markdown 组件、桑基图与 .NET 11 支持
.net·数据可视化·stimulsoft·版本更新·报表控件·桑基图·.net 11
外收内放1 小时前
Python基础语法练习题(62原始版本及其优化版本)
开发语言·python
马剑威(威哥爱编程)1 小时前
【AI全栈后端12-12】Spring Boot 3.x 到 4.x 迁移实操:Jakarta 11、Jackson 3 与 AI 2.0
java·开发语言·spring boot·后端
三月微暖寻春笋1 小时前
【和春笋一起学C++】(七十二)类模板
开发语言·c++·实例·类模板·使用类模板·数组模板
释厄6232 小时前
智能体释放度子集律——文本 ⊂ 音频 ⊂ 视频⊂ 游戏
开发语言·游戏·microsoft·音视频
Sarvartha2 小时前
Object 类
java·开发语言
j7~2 小时前
【C++ 标准项目】发布订阅消息队列 (篇七):项目创建与基础工具模块搭建
开发语言·c++·log4j·uuid·protobuf·helper工具·消息定义类型和交换机类型定义
leisoo80972 小时前
股票筹码分布怎么用获利比例成本区间与集中度实战 IG50免费开源股票数据API接口
开发语言·jvm·数据库·python·开源