OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

How to implement the exposure adjustment like Adobe Lightroom using OpenCV?

  • Thread starter Thread starter Kevin Liem
  • Start date Start date
K

Kevin Liem

Guest
I try to create a image editor features like what are provided by Adobe Lightroom with Python and OpenCV. One of them is Exposure Adjustment on the image. The issue I always have is after increase the exposure, it caused the adjusted image has yellowish or orangish tint. I look up what is the cause of this yellowish / orangish tint. It because the non-uniform adjustment of the RGB channels. May I know what is the real caused and how I can solve this issue?

So, to adjust exposure I have tried several approach. I am expecting to adjust the image exposure of the input as close as possible to adjustment with adobe lightroom.

This is the image I am using as input and This the expected image result from adobe lightroom with 3.67 exposure value

  1. Using gamma correction, because I read the case of RAW image taken from camera usually will be adjusted when display to monitor. I think one of the root cause is because our human eyes not perceived the light in linear way. And this is the result of gamma adjustment with this code implementation.

Code:
def adjust_gamma_original(image, gamma=1.0):
    inv_gamma = 1.0 / gamma
    table = np.array([((i / 255.0) ** inv_gamma) * 255 for i in np.arange(0, 256)]).astype("uint8")
    adjusted_image = cv2.LUT(image, table)
    return adjusted_image

This is the result of gamma correction

  1. I am trying to increase the exposure by applying power of 2 to every pixel. But even though the light brightness is increase, it causes yellowish/orange-ish tint show up the the faces. Which is not ideal because the exposure increment in adobe lightroom didn't cause this issue.

Code:
def apply_exposure_compensation(image, exposure_factor):
    """
    Apply exposure compensation to an image.
    
    :param image: Input image.
    :param exposure_factor: Factor to adjust exposure. Positive values increase exposure, negative values decrease exposure.
    :return: Image with adjusted exposure.
    """
    # Convert the image to float for precision
    image_float = img_as_float(image)
    
    # Adjust exposure by multiplying the image with the exposure factor
    adjusted_image = image_float * (2 ** exposure_factor)
    
    # Clip values to stay within valid range [0, 1] and convert back to uint8
    adjusted_image = np.clip(adjusted_image, 0, 1)
    adjusted_image = img_as_ubyte(adjusted_image)
    return adjusted_image

Output result exposure power of 2

  1. I try to using HSV to because I read if I only want to focus on the brightness without affecting the color tint, then I can adjust the V in HSV. But after I increase it, it makes the output result become further to what I want like adobe lightroom.

Code:
def apply_exposure_compensation_hsv(image, exposure_factor):
    """
    Apply exposure compensation to an image by adjusting the brightness in the HSV color space.
    
    :param image: Input image.
    :param exposure_factor: Factor to adjust exposure. Positive values increase exposure, negative values decrease exposure.
    :return: Image with adjusted exposure.
    """
    # Convert the image to HSV color space
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV).astype(np.float32)
    
    # Adjust the V (brightness) channel
    h, s, v = cv2.split(hsv)
    v = v * (2 ** exposure_factor)
    v = np.clip(v, 0, 255)
    
    # Merge the channels back
    hsv_adjusted = cv2.merge([h, s, v]).astype(np.uint8)
    
    # Convert back to BGR color space
    adjusted_image = cv2.cvtColor(hsv_adjusted, cv2.COLOR_HSV2BGR)
    return adjusted_image

Exposure increment power of 2 on HSV color channel
<p>I try to create a image editor features like what are provided by Adobe Lightroom with Python and OpenCV. One of them is Exposure Adjustment on the image. The issue I always have is after increase the exposure, it caused the adjusted image has yellowish or orangish tint. I look up what is the cause of this yellowish / orangish tint. It because the non-uniform adjustment of the RGB channels. May I know what is the real caused and how I can solve this issue?</p>
<p>So, to adjust exposure I have tried several approach. I am expecting to adjust the image exposure of the input as close as possible to adjustment with adobe lightroom.</p>
<p><a href="https://i.sstatic.net/513Qf2XH.jpg" rel="nofollow noreferrer">This is the image I am using as input</a> and <a href="https://i.sstatic.net/m9NsUcDs.png" rel="nofollow noreferrer">This the expected image result from adobe lightroom with 3.67 exposure value</a></p>
<ol>
<li>Using gamma correction, because I read the case of RAW image taken from camera usually will be adjusted when display to monitor. I think one of the root cause is because our human eyes not perceived the light in linear way. And this is the result of gamma adjustment with this code implementation.</li>
</ol>
<pre><code>def adjust_gamma_original(image, gamma=1.0):
inv_gamma = 1.0 / gamma
table = np.array([((i / 255.0) ** inv_gamma) * 255 for i in np.arange(0, 256)]).astype("uint8")
adjusted_image = cv2.LUT(image, table)
return adjusted_image
</code></pre>
<p><a href="https://i.sstatic.net/felKCY6t.jpg" rel="nofollow noreferrer">This is the result of gamma correction</a></p>
<ol start="2">
<li>I am trying to increase the exposure by applying power of 2 to every pixel. But even though the light brightness is increase, it causes yellowish/orange-ish tint show up the the faces. Which is not ideal because the exposure increment in adobe lightroom didn't cause this issue.</li>
</ol>
<pre><code>def apply_exposure_compensation(image, exposure_factor):
"""
Apply exposure compensation to an image.

:param image: Input image.
:param exposure_factor: Factor to adjust exposure. Positive values increase exposure, negative values decrease exposure.
:return: Image with adjusted exposure.
"""
# Convert the image to float for precision
image_float = img_as_float(image)

# Adjust exposure by multiplying the image with the exposure factor
adjusted_image = image_float * (2 ** exposure_factor)

# Clip values to stay within valid range [0, 1] and convert back to uint8
adjusted_image = np.clip(adjusted_image, 0, 1)
adjusted_image = img_as_ubyte(adjusted_image)
return adjusted_image
</code></pre>
<p><a href="https://i.sstatic.net/VCkKaqWt.jpg" rel="nofollow noreferrer">Output result exposure power of 2</a></p>
<ol start="3">
<li>I try to using HSV to because I read if I only want to focus on the brightness without affecting the color tint, then I can adjust the V in HSV. But after I increase it, it makes the output result become further to what I want like adobe lightroom.</li>
</ol>
<pre><code>def apply_exposure_compensation_hsv(image, exposure_factor):
"""
Apply exposure compensation to an image by adjusting the brightness in the HSV color space.

:param image: Input image.
:param exposure_factor: Factor to adjust exposure. Positive values increase exposure, negative values decrease exposure.
:return: Image with adjusted exposure.
"""
# Convert the image to HSV color space
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV).astype(np.float32)

# Adjust the V (brightness) channel
h, s, v = cv2.split(hsv)
v = v * (2 ** exposure_factor)
v = np.clip(v, 0, 255)

# Merge the channels back
hsv_adjusted = cv2.merge([h, s, v]).astype(np.uint8)

# Convert back to BGR color space
adjusted_image = cv2.cvtColor(hsv_adjusted, cv2.COLOR_HSV2BGR)
return adjusted_image
</code></pre>
<p><a href="https://i.sstatic.net/gwuuT93I.jpg" rel="nofollow noreferrer">Exposure increment power of 2 on HSV color channel</a></p>
 

Latest posts

Top