Каков самый быстрый способ увеличить контрастность цветного изображения с OpenCV в python (cv2)?

Я использую OpenCV для обработки некоторых изображений, и одним из первых шагов, которые мне нужно выполнить, является увеличение контрастности изображения на цветном изображении. Самый быстрый метод, который я нашел до сих пор, использует этот код (где np-импорт numpy) для умножения и добавления, как предложено в оригинальные 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)  

есть ли быстрый способ сделать это в Python? Я попытался использовать скалярное умножение numpy, но производительность на самом деле хуже. Я также попытался использовать cv2.convertScaleAbs (документы OpenCV предложили использовать convertTo, но cv2, похоже, не имеет интерфейса к этой функции), но снова производительность была хуже при тестировании.

2 ответов


простая арифметика в массивах numpy является самой быстрой,как прокомментировал Абид Рахаман К.

использовать эту например: http://i.imgur.com/Yjo276D.png

вот немного обработки изображений, которая напоминает манипуляцию яркостью / контрастностью:

'''
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()

исходное изображение в оттенках серого:

enter image description here

яркое изображение, которое, кажется, расширяется:

enter image description here

затемненное изображение, которое появляется быть размытым, заостренным, с лучшим контрастом:

enter image description here

как преобразуются интенсивности пикселей:

enter image description here

Если вы играете со значениями phi и theta вы можете получить очень интересные результаты. Вы также можете реализовать этот трюк для многоканальных данных изображения.

--- редактировать ---

посмотрите на понятия "уровни" и "кривые" на этот youtube видео отображение редактирования изображений в photoshop. Уравнение для линейного преобразования создает одинаковое количество, т. е. "уровень" изменения на каждом пикселе. Если вы пишете уравнение, которое может различать типы пикселей (например, те, которые уже имеют определенное значение), вы можете изменить пиксели на основе "кривой", описанной этим уравнением.


попробуйте этот код:

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()

закат перед: enter image description here Закат после увеличения контрастности: enter image description here