LSC(Lens Shading Correction)是ISP算法中的一个重要组成部分,用于校正镜头遮挡(lens shading)现象。镜头遮挡是由于镜头和图像传感器的光学特性导致的图像亮度不均匀的现象。通常,图像的中心部分较亮,而边缘部分较暗。LSC算法的目标是通过校正这种亮度不均匀,使得图像在整个视场中具有相同的亮度水平。
网格矫正法的基本步骤:
- 图像划分:将原始图像划分为多个小的网格区域。每个网格的大小由用户指定,这样可以根据具体需求调整网格的密度。
- 计算网格均值:对每个网格区域的像素值进行平均计算,得到每个网格的平均亮度值。
- 计算增益矩阵:选取某个基准网格(通常是中心网格)的平均亮度值,计算其他网格相对于基准网格的亮度增益值。
- 插值计算:对于网格之间的像素点,使用插值法计算其增益值,以保证校正后的图像平滑过渡。
- 应用增益:将计算得到的增益矩阵应用于原始图像,对每个像素的亮度进行调整,得到光照均衡校正后的图像。
通过以上步骤,网格矫正法能够有效地校正图像的光照不均匀性,提高图像的整体质量。接下来,我们将通过 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