1. 标定基础:机器视觉中的标定概念、为什么需要标定、标定的核心参数

各位同学,咱们今天正式开讲标定。说实话,标定这玩意儿,在我刚入行那会儿,总觉得是个「玄学」——明明相机摆在那,拍出来的东西怎么就歪了?后来踩的坑多了,才明白标定其实是整个视觉系统的「地基」。地基没打好,后面算法再牛也白搭。

1.1 标定到底是什么?

说白了,标定就是给相机「量尺寸、定位置」。你想想看,相机镜头是个物理器件,它把三维世界投影到二维图像上,这个过程必然有变形和偏差。标定要做的,就是把这些偏差的规律找出来,然后反过来补偿回去。

我习惯把标定分成两个层面理解:

  • 几何层面:搞清楚相机内部的光学结构(焦距、光心、畸变)
  • 空间层面:搞清楚相机在世界坐标系里的位置和朝向

这两个层面搞定了,你才能从图像上的像素坐标,反推出真实世界的物理坐标。嗯,这就是标定的核心价值。

一句话总结:标定 = 建立「像素 ↔ 物理」的映射关系,消除镜头畸变,确定相机位姿。

1.2 为什么非标不可?

我记得刚带团队时,有个新人问我:「老师,我直接用 OpenCV 测距,不标定行不行?」我让他去测一个 100mm 的标准块,结果测出来 97mm。他还不信,换了三个角度测,每次结果都不一样。这就是不标定的后果——精度不可控。

具体来说,不标定会带来三个致命问题:

  1. 测量失真:镜头畸变会让直线变弯,边缘物体被拉伸,你量出来的尺寸全是错的
  2. 空间错位:多相机系统里,每个相机看到的「世界」都不一样,拼都拼不到一起
  3. 重复性差:换个安装位置、换个镜头,之前的参数全废了,得从头调

我在做 3C 电子产线项目时遇到过一件事:一个手机中框尺寸检测工位,用了 4 个相机从不同角度拍。没做联合标定之前,同一个特征点在不同相机里的坐标差了好几个像素。后来做了全局标定,误差直接压到 0.02mm 以内。你说标定重不重要?

避坑指南:我曾经在一个项目里图省事,用了出厂默认内参。结果换了个环境温度,镜头热胀冷缩,内参全变了,产线直接停了两天。从那以后,我每次换镜头、换相机、甚至换光照,都会重新标定一遍。

1.3 标定的核心参数

标定参数分三大类:内参、外参、畸变系数。咱们一个一个说清楚。

1.3.1 内参(Intrinsic Parameters)

内参是相机「娘胎里带的」属性,跟安装位置无关。它描述的是光线怎么从镜头进到传感器上。

参数 符号 含义 单位
焦距 fx, fy 镜头光心到成像平面的距离,x/y 方向可能不同 像素
光心 cx, cy 主点在图像上的像素坐标(理想情况在正中心) 像素
倾斜因子 s 像素坐标系 x/y 轴不垂直的偏差(现代相机几乎为 0) 无量纲

内参矩阵长这样(HALCON 里叫 CamParam):

内参矩阵 K = [fx,  s, cx;
               0,  fy, cy;
               0,   0,  1]

我个人习惯在 HALCON 里用 calibrate_cameras 算子直接算,它会返回一个包含所有内参的元组。但你要理解每个值的物理意义,不然调参时根本不知道往哪个方向改。

1.3.2 外参(Extrinsic Parameters)

外参描述的是相机在世界坐标系里的「姿势」——它在哪、朝哪看。说白了就是相机坐标系到世界坐标系的旋转和平移。

参数 符号 含义 自由度
旋转 R (3×3) 相机坐标系相对于世界坐标系的旋转 3
平移 T (3×1) 相机光心在世界坐标系中的位置 3

外参在 HALCON 里通常用 Pose 表示,包含 6 个值:3 个旋转角 + 3 个平移量。我刚开始用 HALCON 时,老把 Pose 的顺序搞混——它用的是 [X, Y, Z, RotX, RotY, RotZ],跟某些库不一样。这个坑我踩过,你们记一下。

1.3.3 畸变系数(Distortion Coefficients)

镜头不是完美的,光线经过透镜时会发生弯曲,这就是畸变。畸变分两种:

  • 径向畸变:光线在透镜边缘弯曲更厉害,造成「桶形」或「枕形」变形
  • 切向畸变:镜头和传感器不平行,造成图像倾斜

HALCON 里常用的畸变模型是 Division 模型和 Polynomial 模型。我一般用 Division 模型,参数少、收敛快。畸变系数通常用 k1, k2, k3(径向)和 p1, p2(切向)表示。

经验之谈:别被这些系数吓到。在 HALCON 里,你只需要拍 10-20 张标定板图片,调用 calibrate_cameras,所有参数自动算好。但你要能看懂结果——比如 k1 是负的说明是桶形畸变,正的说明是枕形畸变。

1.4 标定的知识体系

下面这张图把标定的核心逻辑串起来了,你一看就明白:

标定知识体系总览 标定目标:像素 ↔ 物理空间映射 内参(相机固有属性) 外参(相机位姿) 畸变系数(镜头误差) 内参具体值 fx, fy, cx, cy, s 焦距、光心、倾斜因子 外参具体值 R (旋转矩阵) + T (平移向量) HALCON 中为 Pose [X,Y,Z,Rx,Ry,Rz] 畸变具体值 k1, k2, k3 (径向) p1, p2 (切向) 标定方法:HALCON 标定板 + calibrate_cameras 算子 输出:CamParam + Pose → 可复用的标定脚本

1.5 标定在 HALCON 中的位置

HALCON 把标定封装得相当友好。你不需要手写矩阵运算,但得理解背后的逻辑。我常用的标定流程就三步:

  1. 采集标定板图像:不同角度、不同位置拍 10-20 张
  2. 提取标定板角点:用 find_caltab + find_marks_and_pose
  3. 计算参数:用 calibrate_cameras 一次性算出内参、外参、畸变系数

你看,HALCON 把最复杂的数学部分都藏起来了。但如果你不懂内参外参的含义,就算跑通了代码,出了问题也不知道怎么排查。这就是为什么我坚持要先讲基础——工具可以黑盒,但认知不能黑盒。

核心要点回顾:

  • 标定解决的是「像素坐标 → 物理坐标」的映射问题
  • 内参是相机固有属性,外参是相机位姿,畸变系数是镜头误差
  • HALCON 用 CamParam 存内参+畸变,用 Pose 存外参
  • 不标定 = 精度不可控,换环境必须重新标定

好了,标定的概念和核心参数就讲到这里。这些东西看着简单,但往后学你会发现,所有高级操作——手眼标定、多相机拼接、3D 重建——都建立在这个基础上。基础打牢了,后面才能跑得快。