Is there any way to manipulate an image using a color curve in python?

Question:

I have a series of tif images and was wondering if there is a possibility to write something in python (using maybe scikit-image or OpenCV) to apply a color curve. The data I have looks like the following, where we have a list of x, y, x, y… data like so: (0, 0, 32, 22, 64, 56, 128, 128, 192, 196, 255, 255).

enter image description here

Asked By: osterburg

||

Answers:

In the comments, some already gave answers on how to apply a color LUT to an image. However when I read your question, I have the impression that you would like to have in fact a 2D colormap, where the color depends on two parameters. If this is the case, I would recommend to visit this post or this one.
Hope this helps!

Answered By: 87VN0

With the new information you provided I think that the following code should do the trick. lut_in is the vector of input gray levels and lut_out the desired output level. Here it’s applied for all 3 channels (like in photoshop). The only thing you need is the interpolation to have a LUT (look up table) of 256 elements, that fits the 256 gray levels of the input. You can apply the same method for other color resolutions.

import cv2
import numpy as np

image = cv2.imread('apple.jpg')

lut_in = [0, 127, 255]
lut_out = [0, 80, 255]

lut_8u = np.interp(np.arange(0, 256), lut_in, lut_out).astype(np.uint8)
image_contrasted = cv2.LUT(image, lut_8u)

cv2.imwrite('apple_dark.jpg', image_contrasted)

Input:
enter image description here
Output:
enter image description here

Answered By: 87VN0

Here’s a way to do this with python PIL instead of OpenCV just in case anyone stumbles upon this answer as I did and doesn’t want to use OpenCV.

import numpy as np
from PIL import Image

im = Image.open("apple.png").convert("RGBA")                                   
                                                                                                                                                                                                                                                                                                                                          
lut_x = [0, 127, 180, 255]                                                  
lut_y = [5, 80, 90, 255]                                                    
                                                                            
lut_u8 = np.interp(np.arange(0, 256), lut_x, lut_y).astype(np.uint8)        
                                                                            
R, G, B, A = [0, 1, 2, 3]                                                   
source = im.split()                                                         
out = []                                                                    
for band in [R, G, B]:                                                      
    out.append(source[band].point(lut_u8))                                  
out.append(source[A]) # Dont use LUT on the alpha band                      
                                                                            
merged_img = Image.merge('RGBA', out)                                       
merged_img.show()     
Answered By: Anodos
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.