相机标定原理:标定板的选择、标定流程、内参外参的物理意义

相机标定,说白了就是给相机做一次「体检」。

你得知道它看东西有没有变形,焦距准不准,光心在哪儿。更重要的是——你得知道相机在空间里到底站在什么位置。我刚开始做视觉项目时,总觉得标定是件麻烦事,能省就省。结果呢?一个定位项目,精度死活差了 0.5mm,折腾了两天才发现是标定没做。嗯,从那以后,我再也不敢跳过这一步了。

标定板的选择:不是随便一张棋盘就能用

标定板是标定的「尺子」。尺子不准,后面全白搭。

常见的标定板有三种:

类型 特点 适用场景
棋盘格 角点检测稳定,算法成熟 通用场景,精度要求中等
圆点阵列 圆心定位精度高,抗噪好 高精度测量、远心镜头
ChArUco 板 棋盘格+ArUco码,支持部分遮挡 大视野、多相机、动态场景

我个人习惯,普通项目用棋盘格就够了。但如果你做的是高精度测量,比如 0.01mm 级别的,我建议用圆点阵列。为什么?因为圆心的亚像素定位比角点更稳定,受光照影响小。

我的经验:标定板一定要平整。我曾经用一张贴在亚克力板上的棋盘格,结果亚克力本身有微弯,标定出来的内参偏差很大。后来换了陶瓷基板的标定板,问题才解决。

标定流程:三步走,别跳步

标定流程其实不复杂,但每一步都有坑。我把它拆成三步:

  1. 采集图像——拍 15~20 张不同位姿的标定板图像
  2. 提取特征——检测角点或圆心,建立像素坐标
  3. 求解参数——用最小二乘法解出内参和外参

你想想看,为什么需要拍那么多张?因为单张图像只能解出部分参数。你需要标定板在视野里「动起来」——平移、旋转、倾斜,各种角度都来一遍。这样才能把镜头的畸变参数也解出来。

避坑指南:我曾经遇到一个项目,标定板只拍了 8 张,结果畸变参数一直收敛不了。后来加到 20 张,一次就过了。所以,别偷懒,至少拍 15 张。

在 HALCON 里,标定的核心代码其实很简洁:

* 创建标定模型
create_calib_data ('calibration_object', 'calibration_plate', CalibDataID)

* 设置标定板描述文件
set_calib_data_calib_object (CalibDataID, 0, 'caltab_30mm.descr')

* 设置相机初始内参
set_calib_data_cam_param (CalibDataID, 0, 'area_scan_division', [0.008, 0, 0.008, 0, 640, 512, 1280, 1024])

* 添加标定图像
for i := 1 to 20 by 1
    read_image (Image, 'calib_' + i$'02d')
    find_calib_object (Image, CalibDataID, 0, 0, i-1, [], [])
endfor

* 执行标定
calibrate_cameras (CalibDataID, Errors)

这段代码里,find_calib_object 会自动检测标定板上的特征点,calibrate_cameras 会一次性解出所有参数。你只需要保证图像质量够好就行。

内参的物理意义:相机自己的「基因」

内参是相机本身的固有属性。它不会因为你把相机挪了个位置就改变。

内参矩阵长这样:

     [ fx  0  cx ]
K =  [ 0  fy  cy ]
     [ 0   0   1 ]

每个参数都有物理意义:

  • fx, fy —— 焦距,单位是像素。它决定了物体在图像上放多大。
  • cx, cy —— 光心,也就是镜头中心在图像上的投影点。理论上应该在图像正中心,但实际总有偏差。
  • 畸变参数 —— 径向畸变(k1, k2, k3)和切向畸变(p1, p2)。说白了就是镜头把直线拍弯了,需要纠正回来。

我记得有一次,一个客户说他们的相机拍出来的工件总是歪的。我一看内参,cx 和 cy 偏了 20 多个像素。这就是典型的镜头安装偏差。重新标定后,问题就解决了。

外参的物理意义:相机在空间里的「站位」

外参描述的是相机坐标系和世界坐标系之间的变换关系。它由两部分组成:

  • 旋转矩阵 R —— 3x3 矩阵,表示相机朝哪个方向看
  • 平移向量 t —— 3x1 向量,表示相机在空间里的位置

你想想看,外参其实就是回答了三个问题:

  1. 相机在哪儿?(平移)
  2. 相机朝哪儿看?(旋转)
  3. 相机有没有歪?(旋转的细节)

在 HALCON 里,外参通常用 pose 来表示。一个 pose 包含 6 个参数:三个平移量(X, Y, Z)和三个旋转量(Rx, Ry, Rz)。

关键点:内参只标定一次,外参每次换位置都要重新标。这就是为什么在机器人视觉里,手眼标定那么重要——它本质上就是在求外参。

知识结构图:标定的核心逻辑

下面这张图,把相机标定的核心逻辑串起来了。你可以看到,标定板、内参、外参三者之间的关系:

相机标定核心逻辑 标定板 特征提取 内参 (K) 焦距、光心、畸变 外参 (R, t) 旋转、平移 说明 标定板提供已知尺寸的物理特征 → 特征提取建立像素坐标与物理坐标的对应关系 → 内参描述相机自身属性,外参描述相机在空间中的位置

标定中的常见问题

最后,我列几个实际项目中容易踩的坑:

  • 标定板反光——金属标定板在强光下会反光,导致角点检测失败。我建议用哑光材质的标定板。
  • 标定板太小——如果标定板只占视野的 1/3,畸变参数基本解不出来。至少占 1/2 以上。
  • 图像模糊——运动模糊或对焦不准,都会导致特征提取精度下降。拍之前先确认图像清晰。
  • 标定板不平——前面说过了,标定板必须平整。贴在墙上都比贴在弯曲的亚克力上好。
一个小技巧:标定完成后,记得用 get_calib_data 查看标定误差。如果平均误差超过 0.3 像素,我建议重新标定。误差在 0.1 像素以内,才算合格。

嗯,相机标定这部分,内容其实不少。但只要你理解了内参和外参的物理意义,后面的手眼标定、坐标转换,就都顺理成章了。