Какой самый быстрый способ увеличить контрастность цветного изображения с 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 ответа:
Простая арифметика в массивах 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()