2、棋盘格标定板:为什么选择棋盘格?角点检测的数学原理
做相机标定,第一件事就是选标定板。市面上有圆点阵、同心圆环、ArUco码,但为什么绝大多数人——包括我——上手都用棋盘格?
说白了,棋盘格有两个核心优势:角点天然具备亚像素精度,而且检测算法极其鲁棒。我在项目里试过圆点阵,光照一变,椭圆拟合就飘;换回棋盘格,稳得很。
2.1 棋盘格 vs 其他标定板
先看一张对比表,你就明白为什么棋盘格是工业界默认选项了。
| 标定板类型 | 特征点类型 | 检测鲁棒性 | 亚像素精度 | 实现难度 | 我的评价 |
|---|---|---|---|---|---|
| 棋盘格 | 角点(鞍点) | ★★★★★ | ★★★★★ | 低 | 首选,无脑上 |
| 圆点阵 | 圆心 | ★★★☆☆ | ★★★★☆ | 中 | 光照敏感,椭圆拟合易偏 |
| 同心圆环 | 圆心 | ★★★★☆ | ★★★☆☆ | 高 | 抗透视好,但实现复杂 |
| ArUco/ChArUco | 角点+ID | ★★★★☆ | ★★★★☆ | 中 | 适合多视角无序采集 |
你想想看,圆点阵的圆心检测依赖椭圆拟合,一旦镜头畸变大或者光照不均匀,椭圆边缘提取就出问题。棋盘格不一样——它检测的是黑白交界处的鞍点,这个点对光照变化不敏感,因为梯度方向在角点处是正交的。
2.2 棋盘格角点的数学定义
棋盘格上的角点,数学上叫鞍点(saddle point)。什么意思?
想象一个二维曲面 f(x, y),在鞍点处:
- 沿一个方向看,它是极小值(比如沿棋盘格黑块内部)
- 沿另一个方向看,它是极大值(比如沿棋盘格白块内部)
用数学语言说,Hessian 矩阵 H 在鞍点处是不定矩阵——特征值一正一负。
H = [[f_xx, f_xy],
[f_xy, f_yy]]
det(H) < 0 → 鞍点
det(H) > 0 → 极值点(峰或谷)
这个性质非常关键。因为鞍点对图像亮度偏移不敏感——你把整张图调亮或调暗,鞍点的位置不会移动。我在一次户外标定中,阳光从侧面照过来,棋盘格一半亮一半暗,圆点阵直接废了,但棋盘格角点检测依然稳定。
2.3 角点检测的数学原理
实际算法怎么找这些鞍点?主流方法是Harris 角点检测的变体,加上亚像素精化。
2.3.1 Harris 响应函数
Harris 的核心思想:用一个窗口在图像上滑动,看窗口内灰度变化有多大。
对于像素 (x, y),定义自相关矩阵 M:
M = [[Σ(I_x²), Σ(I_x I_y)],
[Σ(I_x I_y), Σ(I_y²)]]
其中 I_x、I_y 是图像在 x、y 方向的梯度。然后计算响应值:
R = det(M) - k * (trace(M))²
当 R 很大且为正时,是角点;R 为负时,是边缘;|R| 很小时,是平坦区域。
但棋盘格角点比较特殊——它是鞍点,R 值其实偏负。所以 OpenCV 的 findChessboardCorners 并没有直接用 Harris,而是用了基于轮廓和四边形拟合的方法,先找到棋盘格的大致位置,再在局部做精化。
2.3.2 亚像素精化
像素级角点不够用。相机标定对特征点精度要求很高,通常需要亚像素级(sub-pixel)精度,也就是小数像素坐标。
亚像素精化的原理很简单:在角点附近,梯度方向应该与角点到该点的向量垂直。
数学表达:
对于角点 q 附近的每个点 p_i,
梯度 ∇I(p_i) 与向量 (q - p_i) 的点积 ≈ 0
即:∇I(p_i)ᵀ · (q - p_i) = 0
把所有 p_i 的方程堆起来,用最小二乘法解出 q 的亚像素坐标。OpenCV 的 cornerSubPix 就是这么干的。
- winSize:搜索窗口大小,一般设为 (5,5) 或 (11,11)
- zeroZone:中心死区,避免梯度为 0 的像素干扰
- criteria:迭代终止条件,通常用 (CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 30, 0.001)
2.4 完整检测流程
我把棋盘格角点检测的完整流程画成了一张图,方便你理解整体脉络。
2.5 为什么棋盘格角点适合标定?
标定需要的是高精度、可重复、易检测的特征点。棋盘格角点恰好满足所有条件:
- 梯度正交性:角点处两个方向的梯度正交,亚像素精化收敛快、精度高
- 光照鲁棒:鞍点位置对亮度偏移不敏感,不像圆点阵的圆心会随光照偏移
- 结构先验:角点之间的拓扑关系固定,可以自动排序,不需要人工干预
- 亚像素精度高:通常可以达到 0.1 像素甚至更高,满足高精度标定需求
2.6 棋盘格设计建议
最后,给你一些棋盘格设计的实用建议:
| 参数 | 建议值 | 说明 |
|---|---|---|
| 内角点数 | 9×6 或 11×8 | 行列数不要相等,否则方向歧义 |
| 方格尺寸 | 20-40 mm | 根据视场角调整,占图像 20%-50% |
| 方格边长比 | 1:1 | 正方形,不要矩形 |
| 打印精度 | ≥ 600 DPI | 贴在刚性平板上,不要起皱 |
| 背景色 | 白色 | 方便二值化,不要用花纹背景 |
我个人习惯用 9×6 内角点的棋盘格,方格边长 25 mm。这个尺寸在大多数场景下都能兼顾精度和视场覆盖。你如果做小物体标定,可以缩小到 10 mm;做大场景,可以放大到 50 mm 以上。