手机影像ISP流程:LSC

目录

    • LSC简介
    • LSC校正的方法
    • LSC代码
    • LSC的影响

LSC简介

      LSC(Lens shading correction),即镜头阴影矫正。
      我们首先了解一下lens shading,lens shading是由于Lens(镜头)的物理结构原因引起的。lens可以简单理解为一个凸透镜,会有一个往中心聚光的作用。这样就会造成打在CIS上中心的光照强度大于四角的,图像表现为中心亮度高四角亮度低,即Lens shading。如下图:
手机影像ISP流程:LSC_第1张图片

      shading又分Y shading和color shading,今天我们主要讨论Y shading的校正,校正的目标是人眼看上去没有明显的暗角。

LSC校正的方法

      目前手机影像主流LSC的做法是拍摄一张亮度适中均匀的图,将图像分成mxn块,计算每一块的平均亮度,然后将这些亮度信息存储在OTP里面,平台ISP处理时会把这些亮度信息读出来,然后计算每一块需要补偿的增益,再通过cos4次方曲线或者其他方式拟合一个补偿的矩阵乘到原图像上。
      因为RGB各通道的响应有差别,所以需要分通道去补偿lens shading。

LSC代码

      1. 先拍摄一张亮度均匀的raw图,如下图。测下来图片的shading只有30%左右。

      2. 将图像分成17 x 13块。(通常sensor出图为 4:3的尺寸,分成17 x 13块可以保证每一块近似于方形)。去除OB后,分通道统计每一块的亮度均值。

    grid_x = 17
    grid_y = 13
    block_x = int(width / 2 / grid_x)
    block_y = int(high / 2 / grid_y)
    R_otpdata = np.zeros((grid_y, grid_x))
    Gr_otpdata = np.zeros((grid_y, grid_x))
    Gb_otpdata = np.zeros((grid_y, grid_x))
    B_otpdata = np.zeros((grid_y, grid_x))
    data_R = data[::2, ::2]
    data_Gr = data[1::2, ::2]
    data_Gb = data[::2, 1::2]
    data_B = data[1::2, 1::2]
    for i in range(grid_x):
        for j in range(grid_y):
            R_otpdata[j][i] = np.mean(data_R[j * block_y:(j + 1) * block_y, i * block_x:(i + 1) * block_x])
            Gr_otpdata[j][i] = np.mean(data_Gr[j * block_y:(j + 1) * block_y, i * block_x:(i + 1) * block_x])
            Gb_otpdata[j][i] = np.mean(data_Gb[j * block_y:(j + 1) * block_y, i * block_x:(i + 1) * block_x])
            B_otpdata[j][i] = np.mean(data_B[j * block_y:(j + 1) * block_y, i * block_x:(i + 1) * block_x])

      如下是Gr通道的亮度统计图(以下的统计图全部以Gr通道为例)。
手机影像ISP流程:LSC_第2张图片
      3. 求出各通道每一块的补偿系数。

    R_otpdata = R_otpdata.max() / R_otpdata
    Gr_otpdata = Gr_otpdata.max() / Gr_otpdata
    Gb_otpdata = Gb_otpdata.max() / Gb_otpdata
    B_otpdata = B_otpdata.max() / B_otpdata

      如下是Gr通道需要补偿的系数矩阵。
手机影像ISP流程:LSC_第3张图片
      4. 将各通道17 x 13的补偿矩阵插值到原本的尺寸,一般来说用cos4次方曲面来拟合插值的效果最好,这里就简单的用双线性插值的方法,最后出来的效果也很好。

    R_otpdata = cv2.resize(R_otpdata,(1296,972),interpolation = cv2.INTER_LINEAR)
    Gr_otpdata = cv2.resize(Gr_otpdata, (1296,972), interpolation=cv2.INTER_LINEAR)
    Gb_otpdata = cv2.resize(Gb_otpdata, (1296,972), interpolation=cv2.INTER_LINEAR)
    B_otpdata = cv2.resize(B_otpdata, (1296,972), interpolation=cv2.INTER_LINEAR)

      如下是插值后的补偿系数矩阵。
手机影像ISP流程:LSC_第4张图片
      5.然后再分通道补偿到原图像中。需要注意不要百分百补偿,原因后面会说到。这里做了一个85%的补偿系数,具体做法感兴趣的同学可以私聊我一起讨论。
      补偿后的raw图如下图,shading可以达到85%左右。

LSC的影响

      对于人眼来说,shading系数大于80%,人眼就不太看得出来暗角。补偿的过高反而会因为四角增益放的过大,导致四角噪声偏大,暗处四角偏红等(偏红原因与BLC模块有关)。目前手机影像ISP流程的LSC补偿一般都放到85%左右,这样可以做到主观上人眼没有感受到明显的暗角,四角的噪声也不至于过大,是一个权衡的选择。
      目前手机平台主流LSC的做法是挑选出一批模组样本中最具有代表性的golden模组,分块统计出golden模组的亮度信息,然后把这些信息填入到效果代码里。每一颗模组的亮度信息也会烧录在自身的OTP里。这样针对每一颗模组来说,都可以通过比较自身的亮度信息和代码里面的golden信息,从而调节自身的补偿系数,达到模组效果一致的目的。
      码字不易,如果感觉这篇文章对您有帮助的话,麻烦点赞、关注一下,谢谢!如果大家有任何问题想要沟通、交流的,欢迎大家关注一下微信公众号“有如念夏”,一起学习进步!

你可能感兴趣的:(python,图像处理,isp,安卓)