Какой самый быстрый способ увеличить контрастность цветного изображения с 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 docs предложил использовать convertTo, но cv2, похоже, не имеет интерфейса к этой функции), но опять же производительность была хуже в тестировании.

2 9

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

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

Введите описание изображения здесь

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

Введите описание изображения здесь

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

Введите описание изображения здесь

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

Введите описание изображения здесь

Если вы играете со значениями 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()

Закат перед: Введите описание изображения здесь Закат после усиления контраста: Введите описание изображения здесь