5.22. 镜头与透视校正¶
有两类几何校正会以矩形到矩形映射无法实现的方式扭曲图像。镜头校正(Lens correction)用于消除真实广角镜头引入的径向畸变——这种鱼眼凸起会使场景中的直线在帧角附近呈现出可见的弯曲。透视校正(Perspective correction)用于消除镜头未垂直对准场景时产生的梯形效应——这种梯形扭曲会把现实世界中的已知矩形变成图像中非矩形的色块。这两种校正都是在拍摄完成之后,去除那些源于光学因素的影响。
5.22.1. 径向镜头畸变¶
真实镜头效应 一节描述了廉价广角镜头引入的桶形(barrel)畸变。靠近帧中心的像素大致位于针孔模型所预测的位置;靠近边缘的像素则向外弯曲,弯曲量随到光轴径向距离的平方增长。场景中沿帧边缘附近延伸的直线在拍摄图像中会明显弯曲,任何假定直线保持笔直的经典机器视觉算法——AprilTag 角点检测、边缘跟踪、循线导航——在帧角附近都会得出错误结果。
lens_corr() 用于消除该畸变。该方法执行逆映射:每个输出像素都从输入中镜头本应将其向外弯曲的位置进行采样,得到的结果是一幅几何上笔直的图像。
img.lens_corr(strength=1.8)
strength 参数是校正的核心。它是一个描述镜头弯曲强度的单一数值;接近 1.0 的值适用于中等广角镜头的轻度校正,最高约 2.0 的值则适合强烈的鱼眼镜头。默认值 1.8 对于 OpenMV Cam 原装镜头是一个合理的起点;对任何特定镜头而言,合适的值都需要多试几次并观察图像来确定。
另外两个辅助参数通常保持默认即可。zoom(默认 1.0)用于缩放输出——大于一的值会向外裁剪,以补偿镜头校正将帧角进一步外推的效果;较小的值则保留更多校正后的场景,但代价是图像边缘会包含空白像素。x_corr 和 y_corr 用于将校正中心从图像几何中心偏移开,这在镜头光学上未对准传感器中心时很有用(这种情况不常见,但值得了解)。
典型流程为:拍摄、运行一次 lens_corr() 来矫正几何形状,然后再对结果执行应用程序真正需要做的处理。
5.22.2. 三维旋转校正¶
另一类几何畸变是传感器平面与场景平面不平行时产生的透视(perspective)扭曲。典型情形是从下方观看标牌或车牌:标牌顶部比底部离镜头更远,因此投影更小,拍摄图像中该矩形便呈现为顶边短于底边的梯形。
解决办法是对拍摄的帧施加三维旋转,从而虚拟地重新调整传感器平面,使其与场景平面平行。其数学原理与 AprilTag 检测从标签四角恢复其姿态所用的透视映射相同,只是反向运行:给定一个旋转,该操作将每个输出像素映射回该旋转本应使其来自的输入位置。
rotation_corr() 执行该校正:
img.rotation_corr(x_rotation=10.0, y_rotation=0.0, z_rotation=0.0)
三个旋转参数以度为单位,描述围绕以图像为中心的虚拟摄像头 x、y、z 轴的旋转。x_rotation 使摄像头上仰或下俯(用于校正在地面拍摄墙面的自然情形);y_rotation 使摄像头左右平移;z_rotation 使摄像头围绕其光轴旋转(用于校正安装不水平的自然情形)。
x_translation 和 y_translation 在不旋转的情况下横向移动虚拟摄像头。zoom(默认 1.0)用于缩放输出。fov(默认 60.0)描述摄像头的垂直视场角,用于计算投影——该值应与实际镜头匹配,以保持几何一致。
对于任意的俯仰与平移组合,可在一次调用中复合多个非零旋转。运算顺序在实现内部是固定的;应用程序只需提供角度,结果便会输出。
5.22.3. 对已知矩形进行校正¶
rotation_corr() 最常用的形式是 corners= 关键字,它接收一个由四个 (x, y) 元组组成的列表,描述输入图像中某个已知矩形的四个角。该方法会计算出本应将真实矩形映射到这四个特定点的三维旋转,然后对整幅图像施加该旋转的逆变换,并返回一个使该已知矩形重新变为矩形的结果:
plate_corners = [(45, 80), (300, 60), (310, 180), (40, 200)]
img.rotation_corr(corners=plate_corners)
经典用途正如其名所示:从倾斜角度拍摄的车牌(或任何其他矩形特征)。上游环节检测到车牌并报告其在拍摄图像中的四个角位置;将这些角传给 rotation_corr() 即可生成一幅车牌呈现为真正矩形的图像,可供随后的字符识别或模板匹配环节使用。
当四角形式能解决应用程序要解决的问题时,它远比六参数形式更有用。应用程序无需估计任何旋转角度;它只需将四个点交给该方法,由方法算出其余部分。六参数形式则适用于场景中没有可识别矩形、必须根据外部知识(例如标定好的安装角度)手动调整旋转的情况。