4、镜头阴影校正(LSC):亮度均匀性、阴影成因、LSC校正表生成、参数调试

镜头阴影校正,英文叫 Lens Shading Correction,简称 LSC。说白了,就是解决画面四周比中心暗的问题。你拿手机拍一张白墙,如果四角发暗,那就是镜头阴影。

这个问题在工业相机里尤其要命。检测的时候,同一个物体放在画面中心和边缘,亮度不一样,算法很容易误判。我刚开始调 ISP 时,就吃过这个亏——一个看似均匀的照明环境,拍出来边缘比中心暗了 15%,客户直接退货。

4.1 亮度均匀性:到底要均匀到什么程度?

先给个量化概念。工业相机通常要求全画面亮度均匀性在 5% 以内。什么意思?就是最亮处和最暗处的灰度差,不能超过最大灰度的 5%。

举个例子:8 位图像,最大灰度 255。那么最亮和最暗的差值不能超过 12.75。如果你测出来中心 240,四角 200,差了 40,那肯定不行。

应用场景 均匀性要求 典型容忍度
外观检测 高 ≤ 3%
尺寸测量 中 ≤ 5%
条码识别 低 ≤ 10%
医疗影像 极高 ≤ 1%

我个人习惯,在调试前先用均匀性测试图卡拍一张,然后用软件分析每个区域的灰度值。这样心里有底,知道要补多少。

4.2 阴影成因:为什么四角会暗?

镜头阴影主要有两个原因。一个是物理的,一个是光学的。

物理原因:余弦四次方定律

光线从中心到边缘,入射角度越来越大。传感器接收到的光强,跟入射角余弦的四次方成正比。角度一大,光强就急剧下降。这是硬件决定的,谁也改不了。

光学原因:镜头遮挡

镜头筒本身会遮挡一部分边缘光线。尤其是长焦镜头、小光圈的时候,这种遮挡更明显。我遇到过一款工业镜头,光圈收到 F8 以上,四角直接黑掉一半。

还有一点,传感器本身的微透镜阵列也会影响。微透镜把光线汇聚到感光区,但边缘光线角度太大,汇聚效果变差。嗯,这里要注意,不同传感器的微透镜设计不一样,阴影表现也不同。

核心结论:镜头阴影是系统性问题,不是单一因素造成的。校正时不能只靠 LSC,还要考虑光源均匀性和镜头选型。

4.3 LSC 校正表生成:怎么算补偿系数?

LSC 校正的原理很简单:给每个像素乘一个增益系数。中心区域系数接近 1.0,边缘区域系数大于 1.0。系数怎么来?靠标定。

标定流程分三步:

  1. 拍一张均匀白场图像——用积分球或者均匀光源板,保证整个画面亮度一致。
  2. 计算每个像素的增益——用目标亮度除以实际亮度。比如目标亮度 200,某个像素实际只有 160,那增益就是 200/160 = 1.25。
  3. 生成校正表——把增益系数存成一张表,通常是网格形式,比如 17x13 个网格点。运行时插值计算每个像素的增益。

我给你们看一段生成校正表的伪代码:

// 伪代码:生成 LSC 校正表
// 输入:raw_image(均匀白场图像), target_luminance(目标亮度)
// 输出:gain_table(增益系数表)

function generate_lsc_table(raw_image, target_luminance, grid_rows, grid_cols):
    height, width = raw_image.shape
    row_step = height / grid_rows
    col_step = width / grid_cols
    
    gain_table = zeros(grid_rows, grid_cols)
    
    for r in range(grid_rows):
        for c in range(grid_cols):
            // 取网格中心区域的平均亮度
            y_start = int(r * row_step + row_step/4)
            y_end   = int(r * row_step + row_step*3/4)
            x_start = int(c * col_step + col_step/4)
            x_end   = int(c * col_step + col_step*3/4)
            
            avg_lum = mean(raw_image[y_start:y_end, x_start:x_end])
            
            // 计算增益,限制最大增益防止噪声放大
            gain = target_luminance / avg_lum
            gain = clamp(gain, 1.0, 2.5)
            
            gain_table[r][c] = gain
    
    return gain_table

经验之谈:网格密度不是越密越好。太密了,校正表会跟着传感器的固定噪声走,反而引入新的不均匀。我一般用 17x13 或者 33x25,具体看传感器分辨率。

4.4 参数调试:怎么调出好效果?

LSC 参数调试,核心就三个参数:增益上限、插值方式、平滑度。

增益上限

增益不能无限大。边缘增益太大,会把暗电流噪声一起放大。我一般限制在 2.0 到 3.0 之间。如果超过 3.0 才能补平,说明镜头或者光源有问题,不是 LSC 能解决的。

插值方式

校正表是离散的网格点,运行时需要插值。常用的有双线性插值和双三次插值。双线性快,但边缘可能有块状感。双三次平滑,但计算量大。工业相机一般用双线性就够了。

平滑度

校正表本身也需要平滑。如果某个网格点的增益突然跳变,校正后会出现亮斑。我习惯在生成表之后,做一次高斯平滑,核大小 3x3 或 5x5。

参数 推荐范围 调试要点
增益上限 1.5 ~ 3.0 超过 3.0 检查镜头
网格密度 17x13 ~ 33x25 分辨率越高网格越密
插值方式 双线性 / 双三次 工业场景用双线性
平滑核 3x3 ~ 7x7 太大损失细节

我曾经踩过的坑:有一次为了追求极致均匀性,把增益上限设到 4.0。结果边缘噪声爆炸,图像完全没法用。后来发现是镜头本身质量问题,换了镜头,增益上限降到 1.8 就搞定了。所以,LSC 不是万能的,硬件底子不好,软件再调也白搭。

4.5 LSC 校正流程总览

下面这张图,是我自己总结的 LSC 调试流程。从标定到验证,每一步都不能省。

LSC 校正流程总览 LSC 校正流程总览 均匀光源标定 采集白场图像 计算增益系数 生成校正表 验证均匀性 不合格则重新标定 关键注意事项 • 光源均匀性需优于目标 2 倍 • 白场图像取多帧平均降噪 • 增益上限不超过 3.0 验证方法 • 拍摄均匀灰卡 • 分析 9 点或 25 点亮度 • 最大偏差 < 5%

你看这个流程,标定→采集→计算→生成→验证,是个闭环。验证不合格,就得回去重新标定。我一般会验证三次,确保校正表稳定可靠。

小技巧:验证的时候,别只看中心点和四个角。我习惯看 9 个点(中心、四角、四边中点),有时候还要看 25 个点。这样才能全面评估均匀性。

好了,LSC 的内容就这些。记住一句话:镜头阴影校正,补的是硬件缺陷,不是万能药。硬件选型、光源设计、镜头匹配,这些前期工作做好了,LSC 只是锦上添花。前期没做好,LSC 就是拆东墙补西墙。