Home > OS >  How to do "Color Cast Removal" or "Color Coverage" in Python
How to do "Color Cast Removal" or "Color Coverage" in Python

Time:01-28

I'm using photo.kako website to do image process for "Color Coverage"

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

enter image description here

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()

Result:

enter image description here

CodePudding user response:

You can overlay a solid color (or a gradient if you're feeling fancy) over the image.

I'm using multiplication and blending here, but you could use a less linear method too.

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

With this simple example, the output isn't exactly the same, but you can tweak it as you wish:

enter image description here

  •  Tags:  
  • Related