上一篇文章讲的是: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基本思路)
预先标定(Calibration):
使用均匀光源(integrating sphere)拍摄参考图,获得理想图像亮度/颜色分布。
得到一个 增益表(Gain Table),通常按 RGB 分别生成。
应用校正(Correction):
实际图像中每个像素按其位置(通常是离中心距离)查表得到对应增益值。
对每个像素进行乘法修正:
其中 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