LSC(镜头阴影矫正)——每日挑战第二天

LSC(Lens Shading Correction)是ISP算法中的一个重要组成部分,用于校正镜头遮挡(lens shading)现象。镜头遮挡是由于镜头和图像传感器的光学特性导致的图像亮度不均匀的现象。通常,图像的中心部分较亮,而边缘部分较暗。LSC算法的目标是通过校正这种亮度不均匀,使得图像在整个视场中具有相同的亮度水平。

网格矫正法的基本步骤:

  1. 图像划分:将原始图像划分为多个小的网格区域。每个网格的大小由用户指定,这样可以根据具体需求调整网格的密度。
  2. 计算网格均值:对每个网格区域的像素值进行平均计算,得到每个网格的平均亮度值。
  3. 计算增益矩阵:选取某个基准网格(通常是中心网格)的平均亮度值,计算其他网格相对于基准网格的亮度增益值。
  4. 插值计算:对于网格之间的像素点,使用插值法计算其增益值,以保证校正后的图像平滑过渡。
  5. 应用增益:将计算得到的增益矩阵应用于原始图像,对每个像素的亮度进行调整,得到光照均衡校正后的图像。

通过以上步骤,网格矫正法能够有效地校正图像的光照不均匀性,提高图像的整体质量。接下来,我们将通过 Python 代码演示如何实现这一方法。

import cv2
import numpy as np
import matplotlib.pyplot as plt


def calculate_lsc_gain(image, side_num):
    height, width, _ = image.shape
    side_y = height // side_num
    side_x = width // side_num

    # Separate color channels
    image_r = image[:, :, 0]
    image_g = image[:, :, 1]
    image_b = image[:, :, 2]

    # Initialize matrices to store block means
    image_point_r = np.zeros((side_num + 1, side_num + 1))
    image_point_g = np.zeros((side_num + 1, side_num + 1))
    image_point_b = np.zeros((side_num + 1, side_num + 1))

    # Calculate block means
    for i in range(side_num + 1):
        for j in range(side_num + 1):
            x_start = max(0, j * side_x - side_x // 2)
            x_end = min(width, j * side_x + side_x // 2)
            y_start = max(0, i * side_y - side_y // 2)
            y_end = min(height, i * side_y + side_y // 2)

            data_r = image_r[y_start:y_end, x_start:x_end]
            data_g = image_g[y_start:y_end, x_start:x_end]
            data_b = image_b[y_start:y_end, x_start:x_end]

            image_point_r[i, j] = np.mean(data_r)
            image_point_g[i, j] = np.mean(data_g)
            image_point_b[i, j] = np.mean(data_b)

    # Initialize gain matrices
    rGain = np.zeros((side_num + 1, side_num + 1))
    gGain = np.zeros((side_num + 1, side_num + 1))
    bGain = np.zeros((side_num + 1, side_num + 1))

    # Calculate LSC gain
    center_i = side_num // 2
    center_j = side_num // 2
    for i in range(side_num + 1):
        for j in range(side_num + 1):
            rGain[i, j] = image_point_r[center_i, center_j] / image_point_r[i, j]
            gGain[i, j] = image_point_g[center_i, center_j] / image_point_g[i, j]
            bGain[i, j] = image_point_b[center_i, center_j] / image_point_b[i, j]

    return rGain, gGain, bGain


def apply_lsc_correction(image, rGain, gGain, bGain, side_num):
    height, width, _ = image.shape
    side_y = height // side_num
    side_x = width // side_num

    corrected_image = np.zeros_like(image, dtype=np.float32)

    for i in range(height):
        for j in range(width):
            gainStepX = min(side_num - 1, i // side_y)
            gainStepY = min(side_num - 1, j // side_x)

            # Bilinear interpolation
            rGainTmp = (rGain[gainStepX + 1, gainStepY] - rGain[gainStepX, gainStepY]) * (i % side_y) / side_y + \
                       (rGain[gainStepX, gainStepY + 1] - rGain[gainStepX, gainStepY]) * (j % side_x) / side_x + \
                       (rGain[gainStepX + 1, gainStepY + 1] + rGain[gainStepX, gainStepY] - rGain[
                           gainStepX + 1, gainStepY] - rGain[gainStepX, gainStepY + 1]) * \
                       (i % side_y) / side_y * (j % side_x) / side_x + rGain[gainStepX, gainStepY]

            gGainTmp = (gGain[gainStepX + 1, gainStepY] - gGain[gainStepX, gainStepY]) * (i % side_y) / side_y + \
                       (gGain[gainStepX, gainStepY + 1] - gGain[gainStepX, gainStepY]) * (j % side_x) / side_x + \
                       (gGain[gainStepX + 1, gainStepY + 1] + gGain[gainStepX, gainStepY] - gGain[
                           gainStepX + 1, gainStepY] - gGain[gainStepX, gainStepY + 1]) * \
                       (i % side_y) / side_y * (j % side_x) / side_x + gGain[gainStepX, gainStepY]

            bGainTmp = (bGain[gainStepX + 1, gainStepY] - bGain[gainStepX, gainStepY]) * (i % side_y) / side_y + \
                       (bGain[gainStepX, gainStepY + 1] - bGain[gainStepX, gainStepY]) * (j % side_x) / side_x + \
                       (bGain[gainStepX + 1, gainStepY + 1] + bGain[gainStepX, gainStepY] - bGain[
                           gainStepX + 1, gainStepY] - bGain[gainStepX, gainStepY + 1]) * \
                       (i % side_y) / side_y * (j % side_x) / side_x + bGain[gainStepX, gainStepY]

            corrected_image[i, j, 0] = image[i, j, 0] * rGainTmp
            corrected_image[i, j, 1] = image[i, j, 1] * gGainTmp
            corrected_image[i, j, 2] = image[i, j, 2] * bGainTmp

    return np.clip(corrected_image, 0, 255).astype(np.uint8)


if __name__ == "__main__":
    filePath = '../images/LSC.png'
    side_num = 16
    meshON = True

    # Load image
    image = cv2.imread(filePath)

    # Calculate LSC gain
    rGain, gGain, bGain = calculate_lsc_gain(image, side_num)

    # Apply LSC correction
    corrected_image = apply_lsc_correction(image, rGain, gGain, bGain, side_num)

    # Display images
    plt.figure(figsize=(12, 6))
    plt.subplot(121)
    plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
    plt.title('Original Image')

    plt.subplot(122)
    plt.imshow(cv2.cvtColor(corrected_image, cv2.COLOR_BGR2RGB))
    plt.title('Corrected Image')
    plt.show()

原文链接:https://blog.csdn.net/wtzhu_13/article/details/118460646?spm=1001.2014.3001.5502

  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值