Search code examples
pythonopencvimage-processingbrightnesscontrast

I want to increase brightness and contrast of images in dynamic way so that the program is applicable for any new images


I have few images where I need to increase or decrease the contrast and brightness of the image in a dynamic way so that it is visible clearly. And the program needs to be dynamic so that it even works for new images also. I also want character should be dark.

I was able to increase brightness and contrast but it is not working properly for each image.

import cv2

import numpy as np

img = cv2.imread('D:\Bright.png')

image = cv2.GaussianBlur(img, (5, 5), 0)

#image = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY)[1]

#kernel = np.ones((2,1),np.uint8)

#dilation = cv2.dilate(img,kernel)

cv2.imshow('test', image)

cv2.waitKey(0)

cv2.destroyAllWindows()

imghsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)


imghsv[:,:,2] = [[max(pixel - 25, 0) if pixel < 190 else min(pixel + 25, 255) for pixel in row] for row in imghsv[:,:,2]]

cv2.imshow('contrast', cv2.cvtColor(imghsv, cv2.COLOR_HSV2BGR))

#cv2.imwrite('D:\\112.png',cv2.cvtColor(imghsv, cv2.COLOR_HSV2BGR))

cv2.waitKey(0)

cv2.destroyAllWindows()

#raw_input()

I want a program which works fine for every image and words are a little darker so that they are easily visible.

image 1

image 2

image 3


Solution

  • As Tilarion suggested, you could try "Auto Brightness And Contrast" to see if it works well. The theory behind this is explained well here in the solution section. The solution is in C++. I've written a version of it in python which you can directly use, works only on 1 channel at a time for colour images:

    def auto_brightandcontrast(input_img, channel, clip_percent=1):
        histSize=180
        alpha=0
        beta=0
        minGray=0
        maxGray=0
        accumulator=[]
    
        if(clip_percent==0):
            #min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(hist)
            return input_img
    
        else:
            hist = cv2.calcHist([input_img],[channel],None,[256],[0, 256])
            accumulator.insert(0,hist[0])    
    
            for i in range(1,histSize):
                accumulator.insert(i,accumulator[i-1]+hist[i])
    
            maxx=accumulator[histSize-1]
            minGray=0
    
            clip_percent=clip_percent*(maxx/100.0)
            clip_percent=clip_percent/2.0
    
            while(accumulator[minGray]<clip_percent[0]):
                minGray=minGray+1
    
            maxGray=histSize-1
            while(accumulator[maxGray]>=(maxx-clip_percent[0])):
                maxGray=maxGray-1
    
            inputRange=maxGray-minGray
    
            alpha=(histSize-1)/inputRange
            beta=-minGray*alpha
    
            out_img=input_img.copy()
    
            cv2.convertScaleAbs(input_img,out_img,alpha,beta)
    
            return out_img