Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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 far uses this code (where np is the numpy import) to multiply and add as suggested in the original C-based cv1 docs:

    if (self.array_alpha is None):
        self.array_alpha = np.array([1.25])
        self.array_beta = np.array([-100.0])

    # add a beta value to every pixel 
    cv2.add(new_img, self.array_beta, new_img)                    

    # multiply every pixel value by alpha
    cv2.multiply(new_img, self.array_alpha, new_img)  

Is there a faster way to do this in Python? I've tried using numpy's scalar multiply instead, but the performance is actually worse. I also tried using cv2.convertScaleAbs (the OpenCV docs suggested using convertTo, but cv2 seems to lack an interface to this function) but again the performance was worse in testing.

like image 482
Todd Stellanova Avatar asked Oct 14 '13 15:10

Todd Stellanova


People also ask

How do I increase contrast on my cv2?

To increase the contrast levels of the image, simply multiply a constant positive value to each and every image pixel. Similarly if one wishes to decrease the contrast level of the image, then multiply a constant positive value less than 1 for each and every image pixel.

How do I change contrast on OpenCV?

To change the contrast, multiply the pixel values with some constant. For example, if multiply all the pixel values of an image by 2, then the pixel's value will be doubled, and the image will look sharper.


1 Answers

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.

like image 199
samkhan13 Avatar answered Oct 16 '22 23:10

samkhan13