How to manipulate the brightness of an image using L*a*b* color space?

Question:

I am trying to change the L* values of an image in L*a*b* color space. But the resultant image is not what I expected. How should I change brightness of the image using the L*a*b* values?

My Code:

imd = np.asarray(ibuffer).copy()
imgb = cv2.cvtColor(imd, cv2.COLOR_BGR2Lab)
value = 255 * (int(bvalue)/100)
imgb[:,:,0] += int(value)
imgb = cv2.cvtColor(imgb,cv2.COLOR_LAB2BGR)
photo = Image.fromarray(imgb)
photo = resize(photo)
photo = ImageTk.PhotoImage(photo)
canvas.photo = photo
canvas.create_image(0,0,anchor="nw",image = photo) 

Original image:

Original Picture

Edited image:

Edited Picture

Asked By: Krishna Krish

||

Answers:

You’re adding some value to the already existing L* value, which will cause integer overflows, thus unexpected behaviour. What you actually want – at least, to my understanding – is to have a scaling between 0 % – 100 % of the original L* value, so something like this:

Output

Therefore, just multiply the original L* value with the percentage you input (full code to reproduce the above output):

import cv2
import matplotlib.pyplot as plt
import numpy as np

img = cv2.imread('path/to/your/image.png')
img_lab = cv2.cvtColor(img, cv2.COLOR_BGR2Lab)

plt.figure(0, figsize=(18, 9))
for i, a in enumerate([0, 20, 40, 60, 80, 100]):
    img_mod = img_lab.copy()
    img_mod[:, :, 0] = (a/100 * img_mod[:, :, 0]).astype(np.uint8)
    img_mod = cv2.cvtColor(img_mod, cv2.COLOR_Lab2BGR)
    plt.subplot(2, 3, i+1)
    plt.imshow(img_mod[:, :, [2, 1, 0]])
    plt.title('L = {}'.format(a))
plt.tight_layout()
plt.show()
----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.8.5
Matplotlib:    3.3.3
NumPy:         1.19.5
OpenCV:        4.5.1
----------------------------------------
Answered By: HansHirse