Как увеличить контрастность изображения в 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) - контраст

Эти формулы приведут к изменениям яркости и контрастности, но у них есть недостатки:

  1. вторая формула не является строго полученной из первой
  2. они не соответствуют яркости и контрастности, наблюдаемым в других программах (например, 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 enter image description here

Для автоматической регулировки контрастности взгляните на этот пост