What's the fastest way to increase color image contrast with OpenCV in python (cv2)?

后端 未结 3 1372
我在风中等你
我在风中等你 2020-12-13 07:50

I\'m using OpenCV to process some images, and one of the first steps I need to perform is increasing the image contrast on a color image. The fastest method I\'ve found so

相关标签:
3条回答
  • 2020-12-13 08:12

    Simple arithmetic in numpy arrays is the fastest, as Abid Rahaman K commented.

    Use this image for example: http://i.imgur.com/Yjo276D.png

    Here is a bit of image processing that resembles brightness/contrast manipulation:

    '''
    Simple and fast image transforms to mimic:
     - brightness
     - contrast
     - erosion 
     - dilation
    '''
    
    import cv2
    from pylab import array, plot, show, axis, arange, figure, uint8 
    
    # Image data
    image = cv2.imread('imgur.png',0) # load as 1-channel 8bit grayscale
    cv2.imshow('image',image)
    maxIntensity = 255.0 # depends on dtype of image data
    x = arange(maxIntensity) 
    
    # Parameters for manipulating image data
    phi = 1
    theta = 1
    
    # Increase intensity such that
    # dark pixels become much brighter, 
    # bright pixels become slightly bright
    newImage0 = (maxIntensity/phi)*(image/(maxIntensity/theta))**0.5
    newImage0 = array(newImage0,dtype=uint8)
    
    cv2.imshow('newImage0',newImage0)
    cv2.imwrite('newImage0.jpg',newImage0)
    
    y = (maxIntensity/phi)*(x/(maxIntensity/theta))**0.5
    
    # Decrease intensity such that
    # dark pixels become much darker, 
    # bright pixels become slightly dark 
    newImage1 = (maxIntensity/phi)*(image/(maxIntensity/theta))**2
    newImage1 = array(newImage1,dtype=uint8)
    
    cv2.imshow('newImage1',newImage1)
    
    z = (maxIntensity/phi)*(x/(maxIntensity/theta))**2
    
    # Plot the figures
    figure()
    plot(x,y,'r-') # Increased brightness
    plot(x,x,'k:') # Original image
    plot(x,z, 'b-') # Decreased brightness
    #axis('off')
    axis('tight')
    show()
    
    # Close figure window and click on other window 
    # Then press any keyboard key to close all windows
    closeWindow = -1
    while closeWindow<0:
        closeWindow = cv2.waitKey(1) 
    cv2.destroyAllWindows()
    

    Original image in grayscale:

    enter image description here

    Brightened image that appears to be dilated:

    enter image description here

    Darkened image that appears to be eroded, sharpened, with better contrast:

    enter image description here

    How the pixel intensities are being transformed:

    enter image description here

    If you play with the values of phi and theta you can get really interesting outcomes. You can also implement this trick for multichannel image data.

    --- EDIT ---

    have a look at the concepts of 'levels' and 'curves' on this youtube video showing image editing in photoshop. The equation for linear transform creates the same amount i.e. 'level' of change on every pixel. If you write an equation which can discriminate between types of pixel (e.g. those which are already of a certain value) then you can change the pixels based on the 'curve' described by that equation.

    0 讨论(0)
  • 2020-12-13 08:20

    Use the cv::addWeighted function. It's design to work on two images

    dst = cv.addWeighted( src1, alpha, src2, beta, gamma[, dst[, dtype]] )

    But if you use the same image twice AND you set beta to zero, you can get the effect you want

    dst = cv.addWeighted( src1, alpha, src1, 0, gamma)

    The big advantage to using this function is that you will not have to worry about what happens when values go below 0 or above 255. In numpy, you have to figure out how to do all of the clipping yourself. Using the OpenCV function, it does all of the clipping for you and it's fast.

    0 讨论(0)
  • 2020-12-13 08:25

    Try this code:

    import cv2
    
    img = cv2.imread('sunset.jpg', 1)
    cv2.imshow("Original image",img)
    
    # CLAHE (Contrast Limited Adaptive Histogram Equalization)
    clahe = cv2.createCLAHE(clipLimit=3., tileGridSize=(8,8))
    
    lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)  # convert from BGR to LAB color space
    l, a, b = cv2.split(lab)  # split on 3 different channels
    
    l2 = clahe.apply(l)  # apply CLAHE to the L-channel
    
    lab = cv2.merge((l2,a,b))  # merge channels
    img2 = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)  # convert from LAB to BGR
    cv2.imshow('Increased contrast', img2)
    #cv2.imwrite('sunset_modified.jpg', img2)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    Sunset before: Sunset after increased contrast:

    0 讨论(0)
提交回复
热议问题