如何在 Python 中执行 "Color Cast Removal" 或 "Color Coverage"

How to do "Color Cast Removal" or "Color Coverage" in Python

我正在使用 photo.kako 网站对“颜色覆盖率”进行图像处理

URL: https://www.photo-kako.com/en/color-cast/

As Image, I want to get result "B" image

有没有函数可以通过python

得到这个结果

谢谢

您可以在图像上叠加纯色(如果您喜欢,也可以叠加渐变色)。

我在这里使用乘法和混合,但你也可以使用线性度较低的方法。

import cv2
import colorsys

import numpy as np


def apply_color_cast(original_int, *, hue, sat, val, blend):
    shade = colorsys.hsv_to_rgb(hue, sat, val)  # shade color in RGB (0..1)
    original_float = original_int / 255.0
    height, width = original_int.shape[:2]
    # Generate mask image from shade color ([::-1] to turn RGB to BGR)
    mask = np.tile(np.array(shade[::-1]), width * height).reshape(original_int.shape)
    masked = original_float * mask  # Generate shaded layer
    blended = cv2.addWeighted(masked, blend, original_float, 1 - blend, 0)  # Blend with original
    return (blended * 255).astype(np.uint8)  # Return BGR integers


original_filename = "photokako-example.jpg"
output_filename = original_filename + ".masked.jpg"

original = cv2.imread(original_filename)
processed = apply_color_cast(original, hue=0.1, sat=0.8, val=0.9, blend=0.5)
cv2.imwrite(output_filename, processed)  # Write out

对于这个简单的示例,输出并不完全相同,但您可以根据需要进行调整:

如果您尝试自动去除偏色,那么这是 Python/OpenCV 中的一种方法。

  • 读取输入
  • 转换为 HSV 并分离通道
  • 将色调通道“旋转”到 360 度中的 180 度或 Python 180 度中的 90 度(即模数加法)
  • 将新色调与原始饱和度和明度通道相结合
  • 将其转换回 BGR
  • 获取新 BGR 图像的平均颜色并创建该颜色和输入尺寸的恒定图像
  • 将输入和这个恒定颜色图像进行 50-50 混合
  • 拉伸至全动态范围
  • 保存输出

输入:

import cv2
import numpy as np
import skimage.exposure

# load image
img = cv2.imread("demo-humanc.jpg")

# convert to HSV
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

# separate channels
h,s,v = cv2.split(hsv)

# reverse the hue channel by 180 deg out of 360, so in python add 90 and modulo 180
h_new = (h + 90) % 180

# combine new hue with old sat and value
hsv_new = cv2.merge([h_new,s,v])

# convert back to BGR
bgr_new = cv2.cvtColor(hsv_new,cv2.COLOR_HSV2BGR)

# Get the average color of bgr_new
ave_color = cv2.mean(bgr_new)[0:3]
print(ave_color)

# create a new image with the average color
color_img = np.full_like(img, ave_color)

# make a 50-50 blend of img and color_img
blend = cv2.addWeighted(img, 0.5, color_img, 0.5, 0.0)

# stretch dynamic range
result = skimage.exposure.rescale_intensity(blend, in_range='image', out_range=(0,255)).astype(np.uint8)

# write result to disk
cv2.imwrite("demo-humanc_remove_cast.png", result)

# display it
cv2.imshow("bgr_new", bgr_new)
cv2.imshow("color_img", color_img)
cv2.imshow("blend", blend)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果: