前言
这是使用 python 和 OpenCv 实现的 Photoshop 中色彩平衡功能的代码,可以设置阴影,高光和中间调的色调参数来调整图片的色彩平衡。
参考文章二也有 python 版本的代码实现,虽然中间调的部分貌似没有实现,但是理论部分讲解还是不错的。
我的代码是基于参考文章一中的 Matlab 代码转写实现的。
代码
python
import cv2
import numpy as np
def normalize_coeffs(coeffs):
median_val = sorted(coeffs)[1]
return np.array([coef - median_val for coef in coeffs])
def highlight_handle(img, highlight_coeffs):
highlights_alpha = 0.003923 * normalize_coeffs(highlight_coeffs)
a = np.diag(np.maximum(highlights_alpha, 0)) * np.eye(3)
b = np.diag(-np.minimum(highlights_alpha, 0)) * (1 - np.eye(3))
highlights_alpha = np.sum(a + b, axis=0)
img = img / (1 - highlights_alpha.reshape(1, 1, 3))
return img
def shadow_handle(img, shadows_coef):
shadows_alpha = 0.003923 * normalize_coeffs(shadows_coef)
a = np.diag(-np.minimum(shadows_alpha, 0)) * np.eye(3)
b = np.diag(np.maximum(shadows_alpha, 0)) * (1 - np.eye(3))
shadows_alpha = np.sum(a + b, axis=0)
img = (img - shadows_alpha.reshape(1, 1, 3)) / (1 - shadows_alpha.reshape(1, 1, 3))
return img
def mid_tone_handle(img, mid_tone_coeffs):
mid_tone_alpha = -0.0033944 * normalize_coeffs(mid_tone_coeffs)
f = np.diag(mid_tone_alpha) * (2 * np.eye(3) - 1)
mid_tone_gamma = np.exp(np.sum(f, axis=0))
img = np.power(img, mid_tone_gamma.reshape(1, 1, 3))
return img
def img_bgr2rgb(img):
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = img.astype(np.float32) / 255.0
img = img.copy()
return img
def img_rgb2bgr(img):
img = cv2.normalize(img, None, 0, 255, cv2.NORM_MINMAX)
img = img.astype(np.uint8)
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
return img
def display(image):
cv2.namedWindow("img", cv2.WINDOW_NORMAL)
cv2.imshow("img", image)
cv2.waitKey()
def main(
image_path,
shadow_coefficients,
mid_tone_coefficients,
highlight_coefficients
):
image = cv2.imread(image_path)
image = img_bgr2rgb(image)
image = highlight_handle(image, highlight_coefficients)
image = shadow_handle(image, shadow_coefficients)
image = mid_tone_handle(image, mid_tone_coefficients)
image = np.clip(image, 0, 1)
image = img_rgb2bgr(image)
display(image)
if __name__ == '__main__':
main(
image_path=r"C:\Users\XXXX\Desktop\capture.png",
shadow_coefficients=[0, 0, 0],
mid_tone_coefficients=[0, 0, 0],
highlight_coefficients=[0, 0, 0],
)