标定原理:棋盘格标定法原理与张正友标定法核心思想
说到相机标定,很多刚入行的朋友会觉得这是玄学。其实没那么复杂。
说白了,标定就是给相机做一次「视力检查」。看看它看世界时,到底歪了多少、扭了多少。我做了这么多年光学成像,最深的体会就是:没有标定过的广角镜头,拍出来的东西只能叫「艺术」,不能叫「测量」。
为什么非要用棋盘格?
你可能会问:为什么大家都用棋盘格?用圆点不行吗?用二维码不行吗?
嗯,这里有个关键原因:棋盘格的角点检测极其稳定。
我在项目中试过各种图案。圆形靶标受光照影响大,边缘检测容易飘。二维码嘛,信息量太大,反而干扰了几何定位。棋盘格的黑白交界处,那个角点位置,在亚像素级别都能被精确锁定。
举个例子:
- 棋盘格角点:两个梯度方向同时变化,定位精度可达0.1像素
- 圆形中心:受透视变形影响,中心位置会偏移
- 随机纹理:根本没法做重复性标定
核心要点:棋盘格角点 = 亚像素级稳定 + 透视不变性 + 自动检测
张正友标定法:一个聪明的解法
张正友在1998年提出的这个方法,我愿称之为「相机标定界的瑞士军刀」。为什么?因为它解决了三个痛点:
- 不需要高精度3D靶标——一张打印的棋盘格就够了
- 操作简单——拍几张不同角度的照片就行
- 精度够用——对大多数应用场景绰绰有余
我记得第一次用张正友法标定一个120度广角镜头时,心里还犯嘀咕:这么简单能行吗?结果跑完标定,重投影误差0.3像素。嗯,真香。
核心思想:三步走
张正友法的精髓,我总结成三步:
第一步:找对应关系
棋盘格上的每个角点,在物理世界是已知坐标的(比如(0,0), (1,0), (2,0)...毫米)。相机拍下来后,这些点在图像上也有像素坐标。我们就是要找这两者之间的映射关系。
我的习惯:打印棋盘格时,一定量一下格子实际尺寸。别信打印机的100%缩放,实际量出来往往差0.5-1mm。这个误差会直接进到标定结果里。
第二步:解内参矩阵
这一步是数学活。通过多张不同角度的棋盘格照片,我们可以解出相机的内参:
内参矩阵 K = [fx, 0, cx;
0, fy, cy;
0, 0, 1]
其中:
- fx, fy:焦距(像素单位)
- cx, cy:主点坐标(光轴与成像平面的交点)
你想想看,如果镜头没有畸变,这个矩阵就够用了。但广角镜头嘛,肯定有畸变。
第三步:估计畸变参数
广角镜头的畸变主要是径向畸变和切向畸变。张正友法用了一个多项式模型来拟合:
径向畸变:k1, k2, k3
切向畸变:p1, p2
我曾经遇到一个极端案例:某款国产广角镜头,k1值高达-0.45。用默认的标定流程跑出来,边缘畸变校正后反而更扭曲了。后来发现是k3项没开,加上后效果立竿见影。
避坑指南:我曾经以为畸变参数越多越好,结果过拟合了。对于普通广角镜头,用k1, k2, p1, p2就够了。只有鱼眼镜头才需要k3甚至更高阶项。
标定流程:实战步骤
说了这么多理论,来点实际的。我一般按这个流程走:
- 准备棋盘格:A4纸打印,贴在硬纸板上。格子数建议9x6或12x9
- 拍摄照片:15-20张,覆盖不同角度和位置。注意:
- 棋盘格要占画面1/3以上
- 边缘区域一定要拍到
- 避免反光和阴影
- 角点检测:用OpenCV的findChessboardCorners()
- 标定计算:calibrateCamera()一步到位
- 验证结果:看重投影误差,一般<0.5像素就算合格
一个经验值:重投影误差0.1-0.3像素是优秀,0.3-0.5像素是良好,超过0.5像素就要检查数据了。我见过有人标定出1.2像素的误差还继续用,那校正后的图像边缘都是波浪形的。
核心逻辑框架图
下面这张图,是我自己画的一个标定流程框架。你看一眼就能明白整个逻辑:
几个容易踩的坑
做标定这么多年,我踩过的坑比走过的路还多。挑几个典型的说说:
- 棋盘格不平整:贴在弯曲的表面上,角点位置全偏了。我建议用3mm亚克力板做底板
- 照片数量不够:少于10张,解出来的参数不稳定。我一般拍20张保底
- 角度变化太小:所有照片都是正面拍摄,那标定出来的畸变参数基本是废的
- 忽略边缘区域:广角镜头边缘畸变最大,如果棋盘格只放在画面中央,边缘畸变根本标定不出来
一个小技巧:标定完成后,用标定好的参数去校正一张新拍的棋盘格照片。如果校正后棋盘格的直线还是直的,那就对了。如果边缘出现波浪形,说明畸变参数没标好。
好了,关于棋盘格标定法和张正友法的核心思想,就聊这么多。说白了就是:用已知的棋盘格,去反推相机的内参和畸变。这个思路贯穿了整个相机标定领域,理解了它,后面的畸变校正就水到渠成了。