4. 切向畸变与薄棱镜畸变

各位,前面我们聊了径向畸变,那是镜头设计本身带来的“硬伤”。但实际项目中,你会发现校正完径向畸变后,图像边缘还是有点“拧巴”。这通常就是切向畸变和薄棱镜畸变在捣鬼。今天我们就来彻底搞定这两个家伙。

4.1 切向畸变:镜头没装正,图像就歪了

切向畸变,说白了就是镜头的光轴和图像传感器的感光面不垂直。你想想看,镜头装歪了一点点,光线穿过透镜后,在传感器上的投影位置就会发生偏移。这种偏移在图像上表现为:原本应该是矩形的物体,变成了梯形或者平行四边形。

我个人习惯把切向畸变想象成“镜头歪脖子”。在产线上,我见过不少因为镜头固定螺丝拧紧力矩不均匀导致的切向畸变。嗯,这里要注意,这种畸变在图像中心区域不明显,越往边缘越严重。

4.1.1 切向畸变的数学模型

切向畸变的数学模型通常用两个参数来描述:p1 和 p2。它们分别代表了x方向和y方向上的畸变分量。公式如下:

// 切向畸变校正模型
// (x, y) 是归一化平面上的畸变点坐标
// (x_corrected, y_corrected) 是校正后的坐标

x_corrected = x + [2 * p1 * x * y + p2 * (r^2 + 2 * x^2)]
y_corrected = y + [p1 * (r^2 + 2 * y^2) + 2 * p2 * x * y]

// 其中 r^2 = x^2 + y^2

这个公式看起来有点复杂,但核心思想很简单:畸变量与位置坐标的乘积有关。p1和p2的值通常很小,一般在10^-3到10^-5量级。如果标定出来的p1、p2值很大,比如超过0.1,那就要检查一下你的镜头安装是不是有问题了。

我的经验: 在Halcon或OpenCV中做标定时,p1和p2的初始值设为0通常没问题。但如果你发现标定结果中p1或p2的符号是负的,别慌,这很正常。负值只代表畸变的方向不同。

4.1.2 切向畸变的影响

切向畸变对视觉测量的影响是“致命”的。它会导致:

  • 角度测量误差: 原本90度的角,测量出来可能是89.5度或90.5度。
  • 直线度失真: 一条直线在图像边缘会变成曲线。
  • 尺寸测量误差: 物体在不同位置,测量出的长度不一样。

我曾经在一个PCB板定位项目中,因为忽略了切向畸变,导致贴片机总是贴不准。后来发现,就是镜头安装时的一个微小倾斜造成的。从那以后,我每次做高精度测量,都会把切向畸变参数p1、p2纳入校正模型。

4.2 薄棱镜畸变:传感器和镜头之间的“楔形”误差

薄棱镜畸变,这个名字听起来有点玄乎。其实它描述的是:镜头和传感器之间,存在一个类似“薄棱镜”的倾斜间隙。这个间隙可能是由于传感器封装不平、镜头座加工公差、或者两者之间的垫片不均匀造成的。

说白了,就是光线穿过镜头后,在到达传感器之前,又经过了一个“楔形”的玻璃层,导致光线再次偏折。这种畸变在高端工业相机中比较少见,但在一些低成本、紧凑型相机模组中,却是个大问题。

4.2.1 薄棱镜畸变的数学模型

薄棱镜畸变同样用两个参数来描述:s1 和 s2。它的数学模型和切向畸变非常相似,但物理意义不同。公式如下:

// 薄棱镜畸变校正模型
// (x, y) 是归一化平面上的畸变点坐标
// (x_corrected, y_corrected) 是校正后的坐标

x_corrected = x + [s1 * (x^2 + y^2) + s2 * (x^2 + y^2)^2 + ...]
y_corrected = y + [s2 * (x^2 + y^2) + s1 * (x^2 + y^2)^2 + ...]

// 注意:实际应用中,通常只取到一次项或二次项
// 简化模型:
x_corrected = x + s1 * r^2
y_corrected = y + s2 * r^2

你可能会问:“这和径向畸变有什么区别?” 区别在于:径向畸变是旋转对称的,而薄棱镜畸变是非对称的。它会在图像上产生一个“单向”的拉伸或压缩效果。

避坑指南: 我曾经在一个项目中,把薄棱镜畸变和切向畸变搞混了。结果标定出来的参数反复横跳,怎么都收敛不了。后来才发现,那个相机模组的传感器封装有问题,薄棱镜畸变占主导。所以,一定要先分析畸变来源,再选择模型。

4.3 综合畸变模型:把所有“歪门邪道”都管起来

在实际的视觉测量系统中,径向畸变、切向畸变、薄棱镜畸变往往是同时存在的。我们需要一个综合模型,把它们全部纳入考虑。这个模型就是:

// 综合畸变模型(OpenCV风格)
// 输入:归一化坐标 (x, y)
// 输出:校正后坐标 (x_corrected, y_corrected)

// 1. 计算径向畸变
r^2 = x^2 + y^2
x_radial = x * (1 + k1 * r^2 + k2 * r^4 + k3 * r^6)
y_radial = y * (1 + k1 * r^2 + k2 * r^4 + k3 * r^6)

// 2. 叠加切向畸变
x_tangential = x_radial + [2 * p1 * x_radial * y_radial + p2 * (r^2 + 2 * x_radial^2)]
y_tangential = y_radial + [p1 * (r^2 + 2 * y_radial^2) + 2 * p2 * x_radial * y_radial]

// 3. 叠加薄棱镜畸变(简化模型)
x_corrected = x_tangential + s1 * r^2
y_corrected = y_tangential + s2 * r^2

// 最终,将校正后的归一化坐标映射到像素坐标
u = fx * x_corrected + cx
v = fy * y_corrected + cy

这个综合模型包含了最多9个畸变参数:k1, k2, k3, p1, p2, s1, s2(有时还有k4, k5, k6)。但我不建议你一股脑全用上。参数越多,标定过程越不稳定,也越容易过拟合。

我的建议: 对于大多数工业视觉测量系统,使用 k1, k2, p1, p2 四个参数就足够了。如果精度要求极高(比如亚像素级),可以再加入 k3。至于s1、s2,除非你确认相机模组有薄棱镜畸变,否则不要轻易启用。

4.3.1 综合畸变模型的知识结构

为了让你更直观地理解这些畸变之间的关系,我画了一张图:

综合畸变模型知识结构图 综合畸变模型知识结构 综合畸变模型 径向畸变 切向畸变 薄棱镜畸变 参数: k1, k2, k3 参数: p1, p2 参数: s1, s2 核心原则 1. 径向畸变:镜头曲率导致,旋转对称,占主导。 2. 切向畸变:镜头与传感器不平行,非对称。 3. 薄棱镜畸变:传感器封装或镜头座倾斜,非对称。

4.4 参数标定与精度控制

有了模型,下一步就是标定参数。这里我分享几个关键点:

畸变类型 参数 标定难度 对测量精度的影响 我的建议
径向畸变 k1, k2, k3 低 高(中心区域小,边缘大) 必标定,k3视情况
切向畸变 p1, p2 中 中(影响角度和直线度) 建议标定
薄棱镜畸变 s1, s2 高 低(仅在低成本模组中显著) 谨慎使用
标定技巧: 我建议使用多姿态标定板。让标定板在视场中占据不同位置、不同角度,这样能更好地激发各种畸变,让标定算法更准确地估计出p1、p2和s1、s2。记住,标定板图像数量不要少于15张,20张以上更稳妥。

4.4.1 如何判断是否需要薄棱镜畸变模型?

你可以做一个简单的实验:

  1. 用标准径向+切向模型标定相机。
  2. 计算所有标定板角点的重投影误差。
  3. 如果误差在图像边缘区域明显大于中心区域,且呈现单向性(比如,只在图像右侧误差大),那么很可能存在薄棱镜畸变。
  4. 此时,再加入s1、s2进行标定,观察重投影误差是否显著下降。

我曾经在一个手机摄像头模组的测试项目中,就是用这个方法发现了薄棱镜畸变。加入s1、s2后,重投影误差从0.15像素降到了0.05像素,效果立竿见影。

重要提醒: 不要为了追求极低的重投影误差而盲目增加参数。参数过多会导致标定结果不稳定,甚至出现“过拟合”——标定板上的点误差很小,但实际测量时误差反而更大。我的原则是:在满足精度要求的前提下,参数越少越好。

好了,关于切向畸变和薄棱镜畸变的建模,我们就聊到这里。记住,理解这些畸变的物理本质,比死记硬背公式更重要。下次当你看到一张边缘扭曲的图像时,你就能快速判断:是镜头歪了?还是传感器没装平?还是两者都有?