pythonopencvimage-processingcomputer-visionbrightness

Auto selection of Gamma value for image brightness


I have a sequence of images or live video and I want to check if the image is darker or brighter, then adjust the brightness using gamma correction i.e. Image ^ gamma. gamma = 1 do nothing and smaller than 1 value of gamma, bright the image and greater than 1 makes it dark. I have to give the gamma value manual for different types of images or videos.

Code is as follow

lookUpTable = np.empty((1,256), np.uint8)
for i in range(256):
    lookUpTable[0,i] = np.clip(pow(i / 255.0, gamma) * 255.0, 0, 255)
res = cv2.LUT(image, lookUpTable)

I want to find gamma value automatically checking the image. I tried to find gamma value to brightness using histogram but it seems not good.

Whole Code is as follow

        histr = cv2.calcHist([image],[0],None,[256],[0,256]) 
            
    totalPixels = image.shape[0]*image.shape[1]

    maxInd = np.argmax(histr) 
    maxVal = histr[maxInd]
    indP= int(0 if maxInd-5 < 0 else maxInd-5)
    indexN = int(maxVal+5)
    percentAtDark = (maxVal / totalPixels )*100
    darkSum = np.sum(histr[indP:indexN])
    percentDark = (darkSum / totalPixels )*100
    
    if (percentDark > dartThreshold) and (maxInd < 127): 
        gammaList = np.arange(0.01,0.9,0.02)
        gamma=gammaList[maxInd]
    else:
        gamma = 1
   
    lookUpTable = np.empty((1,256), np.uint8)
    for i in range(256):
        lookUpTable[0,i] = np.clip(pow(i / 255.0, gamma) * 255.0, 0, 255)
    res = cv2.LUT(image, lookUpTable)

dartThreshold can be set 60 or 70.

For gamma correction you can look at the end of this page

Can anyone suggest any better method or improvement in this code? Any suggestions are more than welcome.


Solution

  • After getting no answer, I tried and find something to share. May be I was not able to ask question clearly. I computed the gamma in the following way

    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    hue, sat, val = cv2.split(hsv)
    
    mid = 0.5
    mean = np.mean(val)
    meanLog = math.log(mean)
    midLog = math.log(mid*255)
    gamma =midLog/meanLog
    gamma = 1 / gamma
    

    and applied it to the original BGR image

    lookUpTable = np.empty((1,256), np.uint8)
    for i in range(256):
        lookUpTable[0,i] = np.clip(pow(i / 255.0, gamma) * 255.0, 0, 255)
    res = cv2.LUT(image, lookUpTable)
    

    If we change the from mid = 0.5 to mid = 1, gamma value changes by 0.1 i.e. for mid = 0.5 if we get 0.69 then for mid = 1, we will get gamma = 0.59.

    Comments are most welcome.