Как увеличить контрастность изображения в Python OpenCV
Я новичок в Python OpenCV. Я прочитал несколько документов и ответов здесь, но я не могу понять, что означает следующий код:
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)
Я узнал, что Basically, every pixel can be transformed as X = aY + b where a and b are scalars.
. В принципе, я это понял. Однако я не понял код и как увеличить контраст с этим.
До сих пор мне удалось просто прочитать изображение, используя img = cv2.imread('image.jpg',0)
Спасибо за помощь
Ответы
Ответ 1
Я хотел бы предложить метод, использующий цветной канал LAB. В Википедии достаточно информации о том, что такое цветной канал LAB.
Я сделал следующее, используя OpenCV 3.0.0 и python:
import cv2
#-----Reading the image-----------------------------------------------------
img = cv2.imread('Dog.jpg', 1)
cv2.imshow("img",img)
#-----Converting image to LAB Color model-----------------------------------
lab= cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
cv2.imshow("lab",lab)
#-----Splitting the LAB image to different channels-------------------------
l, a, b = cv2.split(lab)
cv2.imshow('l_channel', l)
cv2.imshow('a_channel', a)
cv2.imshow('b_channel', b)
#-----Applying CLAHE to L-channel-------------------------------------------
clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8))
cl = clahe.apply(l)
cv2.imshow('CLAHE output', cl)
#-----Merge the CLAHE enhanced L-channel with the a and b channel-----------
limg = cv2.merge((cl,a,b))
cv2.imshow('limg', limg)
#-----Converting image from LAB Color model to RGB model--------------------
final = cv2.cvtColor(limg, cv2.COLOR_LAB2BGR)
cv2.imshow('final', final)
#_____END_____#
Вы можете запустить код так, как есть.
Чтобы узнать, что такое CLAHE (Contrast Limited Adaptive Histogram Equalization), вы можете снова проверить Википедию.
Ответ 2
\\это сообщение было сильно отредактировано от оригинала. ядро исходного ответа сохраняется в примечании ниже \\
Для Python я не нашел функцию OpenCV, которая обеспечивает контраст. Как и предполагали другие, есть некоторые методы для автоматического увеличения контраста.
В официальных документах OpenCV предлагается использовать это уравнение для одновременного применения контрастности и яркости:
new_img = alpha * old_img + beta
где альфа соответствует контрасту, а бета - яркости. Разные случаи
alpha 1 beta 0 --> no change
0 < alpha < 1 --> lower contrast
alpha > 1 --> higher contrast
-127 < beta < +127 --> good range for brightness values
В C/C++ вы можете реализовать это уравнение, используя cv :: Mat :: convertTo, но у нас нет доступа к этой части библиотеки из Python. Чтобы сделать это в Python, я бы порекомендовал использовать функцию cv :: addWeighted, потому что она быстра и автоматически вынуждает выходной сигнал находиться в диапазоне от 0 до 255 (например, для 24-битного цветного изображения, 8 бит на канал).
import cv2
img = cv2.imread('input.png')
# call addWeighted function. use beta = 0 to effectively only operate one one image
out = cv2.addWeighted( img, contrast, img, 0, brightness)
output = cv2.addWeighted
>>>>> Начать заметку <<<<<
В первоначальном виде я ссылался на эту формулу из этой онлайновой книги GIMP] (http://pippin.gimp.org/image_processing/chap_point.html)
new_image = (old_image - 0.5) × контрастность + 0.5
и эта измененная формула для изменения шкалы контраста для перехода от -127 к +127:
new_image = (old_image) × (контраст/127 + 1) - контраст
Эти формулы приведут к изменениям яркости и контрастности, но у них есть недостатки:
- вторая формула не является строго полученной из первой
- они не соответствуют яркости и контрастности, наблюдаемым в других программах (например, PhotoShop, GIMP и т.д.)
>>>>> Конец заметки <<<<<
С этого момента я постараюсь воспроизвести поведение, обычно наблюдаемое в программах для редактирования фотографий, и, в частности, поведение в GIMP.
контрастировать
В GIMP уровни контрастности изменяются от -127 до +127. Я адаптировал формулы отсюда, чтобы соответствовать этому диапазону.
f = 131 * (контраст + 127)/(127 * (131-контраст))
new_image = f * (old_image - 127) + 127 = f * (old_image) + 127 * (1-f)
Чтобы выяснить яркость, я выяснил соотношение между яркостью и уровнями и использовал информацию в этом посте уровней, чтобы прийти к решению.
#pseudo code
if brightness > 0
shadow = brightness
highlight = 255
else:
shadow = 0
highlight = 255 + brightness
new_img = ((highlight - shadow)/255)*old_img + shadow
яркость и контрастность в Python и OpenCV
Собираем все вместе и добавляем, используя эталонное изображение "mandrill" из USC SIPI:
import cv2
import numpy as np
# Open a typical 24 bit color image. For this kind of image there are
# 8 bits (0 to 255) per color channel
img = cv2.imread('mandrill.png') # mandrill reference image from USC SIPI
s = 128
img = cv2.resize(img, (s,s), 0, 0, cv2.INTER_AREA)
def apply_brightness_contrast(input_img, brightness = 0, contrast = 0):
if brightness != 0:
if brightness > 0:
shadow = brightness
highlight = 255
else:
shadow = 0
highlight = 255 + brightness
alpha_b = (highlight - shadow)/255
gamma_b = shadow
buf = cv2.addWeighted(input_img, alpha_b, input_img, 0, gamma_b)
else:
buf = input_img.copy()
if contrast != 0:
f = 131*(contrast + 127)/(127*(131-contrast))
alpha_c = f
gamma_c = 127*(1-f)
buf = cv2.addWeighted(buf, alpha_c, buf, 0, gamma_c)
return buf
font = cv2.FONT_HERSHEY_SIMPLEX
fcolor = (0,0,0)
blist = [0, -127, 127, 0, 0, 64] # list of brightness values
clist = [0, 0, 0, -64, 64, 64] # list of contrast values
out = np.zeros((s*2, s*3, 3), dtype = np.uint8)
for i, b in enumerate(blist):
c = clist[i]
print('b, c: ', b,', ',c)
row = s*int(i/3)
col = s*(i%3)
print('row, col: ', row, ', ', col)
out[row:row+s, col:col+s] = apply_brightness_contrast(img, b, c)
msg = 'b %d' % b
cv2.putText(out,msg,(col,row+s-22), font, .7, fcolor,1,cv2.LINE_AA)
msg = 'c %d' % c
cv2.putText(out,msg,(col,row+s-4), font, .7, fcolor,1,cv2.LINE_AA)
cv2.putText(out, 'OpenCV',(260,30), font, 1.0, fcolor,2,cv2.LINE_AA)
cv2.imwrite('out.png', out)
![enter image description here]()
Я вручную обработал изображения в GIMP и добавил текстовые теги в Python/OpenCV:
![enter image description here]()
Примечание: @UtkarshBhardwaj предложил пользователям Python 2.x преобразовать код вычисления коррекции контрастности в float для получения плавающего результата, например так:
...
if contrast != 0:
f = float(131*(contrast + 127))/(127*(131-contrast))
...
Ответ 3
Лучшее объяснение для X = aY + b
(на самом деле это f(x) = ax + b
)) предоставляется https://math.stackexchange.com/a/906280/357701
Упрощенный, просто регулируя яркость/яркость/яркость для контраста, как показано ниже:
import cv2
img = cv2.imread('test.jpg')
cv2.imshow('test', img)
cv2.waitKey(1000)
imghsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
imghsv[:,:,2] = [[max(pixel - 25, 0) if pixel < 190 else min(pixel + 25, 255) for pixel in row] for row in imghsv[:,:,2]]
cv2.imshow('contrast', cv2.cvtColor(imghsv, cv2.COLOR_HSV2BGR))
cv2.waitKey(1000)
raw_input()
Ответ 4
Яркость и контраст можно регулировать с помощью альфа (α) и бета (β) соответственно. Выражение можно записать как
![enter image description here]()
OpenCV уже реализует это как cv2.convertScaleAbs()
, просто предоставьте пользовательские значения alpha
и beta
import cv2
image = cv2.imread('1.jpg')
alpha = 1.5 # Contrast control (1.0-3.0)
beta = 0 # Brightness control (0-100)
adjusted = cv2.convertScaleAbs(image, alpha=alpha, beta=beta)
cv2.imshow('original', image)
cv2.imshow('adjusted', adjusted)
cv2.waitKey()
До (слева), После (справа)
![enter image description here]()
Для автоматической регулировки контрастности взгляните на этот пост