广角镜头拍摄棋盘格时,原本笔直的边线常向外鼓起;长焦或某些校正组合则可能让线条向内收。传感器没有把直线“拍错”,而是镜头把不同视场角的光线投到了偏离理想模型的位置。
LDC(Lens Distortion Correction,镜头畸变校正)做的事情,是用标定得到的几何模型重新安排像素坐标。它不创造新的视场,也不能无代价恢复边缘细节:坐标被拉伸后必须插值,空白区域最终还要裁切。
从径向畸变开始
以光心为原点,把理想坐标记为 ,半径平方为 。常用的径向模型写成:
当 ,边缘通常向中心收缩,表现为桶形畸变;当 ,边缘向外扩张,常呈枕形。高阶项控制靠近画面边缘时的曲线形状。
网格怎样暴露径向畸变
调节径向系数,观察直线怎样在画面边缘弯曲。灰色虚线是理想网格。
这是以光心为原点的归一化径向模型。真实镜头还可能需要切向项和非对称模型。
实验只包含两个径向项。真实标定还会估计光心、焦距、切向畸变,鱼眼镜头则常使用等距、等立体角或 Kannala–Brandt 等模型。模型必须与镜头投影规律和目标视场匹配。
校正不是把公式反过来写
已知理想点可以直接算出畸变点;但 LDC 输出需要回答相反问题:输出画面中的每个理想像素,应当从输入畸变图的哪里取值?高阶模型通常没有方便、稳定的解析逆函数,因此会迭代求解,或离线生成查找网格。
正向映射为什么容易留下空洞
正向映射把输入像素推向输出;逆向映射从每个输出位置反查输入,因此能保证输出网格被逐点访问。
点阵只示意坐标访问方式;真正的逆向映射会对反查到的非整数坐标执行双线性、双三次等插值。
正向映射把每个输入像素投向输出。多个输入可能落在同一输出像素,也可能没有任何点落到某些位置,形成空洞。逆向映射遍历每个输出像素,再反查连续的输入坐标,因此输出覆盖完整;代价是必须对亚像素位置插值。
一个简化的迭代反解可以写成:
def inverse_radial(target, k1, k2, iterations=8): source = target.copy() for _ in range(iterations): r2 = source[0] ** 2 + source[1] ** 2 scale = 1 + k1 * r2 + k2 * r2 ** 2 mapped = source * scale source += target - mapped return source工业实现会检查收敛范围,并使用标定网格、定点近似或硬件 warp engine 控制吞吐和带宽。
为什么校正后必须裁切
桶形图像的角落信息被压向中心。把它重新拉开时,目标矩形的某些区域可能落到原图之外。可以保留黑边、降低输出视场,或者放大并裁掉无效区域;三者无法同时避免。
校正强度、黑边与视场怎样交换
校正拉伸边缘后,输出矩形可能没有源像素覆盖;放大裁切能去掉黑边,却会损失视场。
面积是教学估算。工程实现会由完整镜头模型、目标宽高比、安全边界和电子防抖余量共同决定裁切。
电子防抖还需要额外的移动余量,因此 LDC、EIS 和输出裁切常联合设计。若只按静态单帧把视场用满,视频稳定时很容易在边角露出无效区域。
一次坐标变换,一次重采样
逆向映射通常得到 这样的坐标。最近邻速度快但会产生锯齿;双线性稳健却会降低高频;双三次或更宽的核保留更多锐度,也可能引入 ringing。
几何校正为什么离不开重采样
逆向映射通常落在亚像素坐标。插值核决定边缘平滑度,也决定计算量、混叠与 ringing 风险。
LDC 与缩放若连续执行,最好合并坐标变换,只重采样一次;反复插值会累积模糊或振铃。
LDC、缩放、旋转和防抖若分四次执行,就会反复重建像素。更好的做法是合并坐标变换,从最终输出位置一次反查原图,只做一次高质量重采样。
LDC 放在 ISP 的哪里
在 Bayer 域直接做几何 warp,会让 CFA 颜色采样位置不再落在规则棋盘上,后续 Debayer 复杂度明显增加。因此常见路径是先完成 Debayer,再在 RGB 或 YUV 域执行 LDC。也有硬件为了带宽,把 Debayer、LDC、缩放融合成专用流水线。
锐化通常放在主要几何重采样之后,否则已经增强的高频会被再次插值,halo 和 ringing 也可能被拉伸。降噪顺序需要权衡:先降噪可避免插值扩散噪声,后降噪则面对空间变化后的噪声统计。
标定比公式更重要
标定常用不同姿态的棋盘格或圆点板,联合估计内参和畸变参数。需要覆盖完整视场、多个对焦距离和温度状态。变焦、对焦、OIS 位置都会改变模型,只存一组参数往往不够。
验证不应只看中心区域:
- 检查画面四边和四角的直线残差;
- 检查光心附近是否被错误扭曲;
- 检查不同焦距、对焦距离与温度;
- 检查裁切后视场和电子防抖余量;
- 检查细线、文字和周期纹理的混叠;
- 视频中检查模型切换是否跳变。
最容易踩的坑
- 混淆“从理想到畸变”和“从输出反查输入”的参数方向;
- 忽略归一化坐标、焦距和光心定义,直接复制系数;
- 正向映射后用简单填洞掩盖覆盖问题;
- 多次独立 warp,累积模糊和 ringing;
- 只在中心棋盘格上标定,边缘残差失控;
- 把裁切损失误认为算法缺陷,而没有记录目标视场;
- 镜头状态变化后仍使用固定标定表。
LDC 的核心不是“把弯线拉直”,而是建立从输出坐标到输入采样位置的可靠映射。模型决定几何准确度,逆向映射保证覆盖,插值决定细节代价,裁切决定最终视场。四件事必须一起评估。