Search code examples
pythonopencvhsv

Dark pieces in brightened HSV image


I have an image that I want to make brighter. So I just converted it to HSV and multiplied the V value by the coefficient I need. But there are dark pieces in the out image.
Original image:
original img
Out image:
out image
Code:

import cv2
import numpy as np


real_4 = cv2.imread('data/data_4_real_cut.jpg')
k = 5

cv2.imshow('orig 4', real_4)
hsv_4 = cv2.cvtColor(real_4, cv2.COLOR_BGR2HSV)
hsv_4[:, :, 2] *= k
bgr_again = cv2.cvtColor(hsv_4, cv2.COLOR_HSV2BGR)
cv2.imshow('orig 4 high', bgr_again)

cv2.waitKey(0)

And as I understood when I multiply V value by needed coefficient it could out of 0 - 255 range. But I'm not sure about it and I didn't find any information about it. And of course the question is - why there are dark pieces in the image? Thanks!


Solution

  • The values in the image are stored as datatype np.uint8, which can only store unsigned 8-bit integers (0-255). When the result of the multiplication exceeds 255, the values will overflow into actual_result % 256, for example: np.uint8(266) == (266 % 256) == 10. To prevent overflow, the result needs to be clipped to a maximum value of 255, for which you could use the cv2.multiply method:

    import cv2
    
    from skimage.io import imread
    
    rgb = imread("https://i.sstatic.net/2tcDv.jpg")
    bgr = cv2.cvtColor(rgb, cv2.COLOR_RGB2BGR)
    
    k = 5
    
    hsv = cv2.cvtColor(bgr, cv2.COLOR_BGR2HSV)
    # safe multiplication without overflow
    hsv[..., 2] = cv2.multiply(hsv[..., 2], k)
    
    bgr_again = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
    cv2.imshow("orig 4 high", bgr_again)
    
    cv2.waitKey(0)
    

    This will give the correct output result:

    output