ISP Pipeline(3):Lens Shading Correction 镜头阴影校正

发布于:2025-07-02 ⋅ 阅读:(26) ⋅ 点赞:(0)

上一篇文章讲的是:ISP Pipeline(2): Black Level Compensation:ISP Pipeline(2):Black Level Compensation 黑电平补偿-CSDN博客

视频:(4) Lens Shading Correction | Image Signal Processing Pipeline Tutorial Series

源码:AI_Plays/ISP/Fast_ISP_Progress.ipynb at main · ameengee/AI_Plays · GitHub

Lens Shading Correction(LSC) 是 ISP(图像信号处理)中的一个重要步骤,用来校正由于镜头和图像传感器组合所导致的图像亮度和颜色在空间分布上的不均匀性问题。这个问题在 广角镜头、低光照环境或者大光圈 情况下尤为明显。

为什么需要 LSC?

拍摄的原始图像中,常见问题如下:

  • 中心亮,边缘暗(vignetting);

  • 颜色偏差(不同通道光线衰减不一样,比如边缘区域红色多,绿色少);

  • 会影响白平衡、颜色还原、图像质量。

成因

主要包括:

  • 镜头透镜结构:光线穿过镜头时,边缘光线容易损失。

  • 光线入射角不同:边缘像素光线入射角更大,灵敏度降低。

  • 传感器非线性响应:传感器各位置像素响应不一致。

校正原理(LSC基本思路)

  1. 预先标定(Calibration)

    • 使用均匀光源(integrating sphere)拍摄参考图,获得理想图像亮度/颜色分布。

    • 得到一个 增益表(Gain Table),通常按 RGB 分别生成。

  2. 应用校正(Correction)

    • 实际图像中每个像素按其位置(通常是离中心距离)查表得到对应增益值。

    • 对每个像素进行乘法修正:

      I' =I \times G(x,y)

      其中 G(x,y)G(x,y) 为增益因子,I 是原像素值,I′ 是校正后的像素值。

 代码实现:

  • 计算图像中心(+1 是为了防止出现 division by zero 或让中心处不为0,实际可调)。
  • 构造每个像素到图像中心的径向距离图,这就是光照衰减的模拟基准。
  • 限制中心区域的最小半径为 1300,意味着只有距离中心大于1300像素的区域才会被增强,中心区域保持不变(增强倍数为 k * 1300 + 1)。
  • lsc_img = (blc_img * (k * radial_dist + 1) - offset).astype(np.uint16)这个公式可以理解为:

     
    • k * r + 1:让中心附近是 1,远离中心增益越来越大;

    • offset 是全局亮度调整,防止变得太亮。

    • 转为 uint16,保留高位数据。


def LSC(blc_img, k, offset):
  """
  inputs:
    blc_img = bayer domain image after black level compensation
    k = correction factor to control strength of the correction
    offset = offset in case the final image is too bright

  outputs:
    lsc_img = bayer domain image adjusted for lens shading
  """

  rows, cols = blc_img.shape
  center_x = (cols // 2) + 1 # identify center if the image
  center_y = (rows // 2) + 1
  x, y = np.meshgrid(np.arange(cols), np.arange(rows)) # create an array where each index is the radial distance from the center
  radial_dist = np.sqrt((x - center_x)**2 + (y - center_y)**2)
  radial_dist = np.where(radial_dist <= 1300, 1300, radial_dist) # ensure correction only applies on the outer edges

  lsc_img = (blc_img * (k * radial_dist + 1) - offset).astype(np.uint16) # apply correction

  return lsc_img
     


网站公告

今日签到

点亮在社区的每一天
去签到