Вот два способа сделать это в Python / OpenCV. Оба основаны на соотношении журнала (средний серый) / log (среднего). Часто результаты приемлемы, особенно для темного изображения, но не во всех случаях. Для яркого изображения инвертируйте серое или цветное изображение, обработайте так же, как и для темных изображений, затем снова инвертируйте и рекомбинируйте, если вы используете стандартное изображение. Значение HSV
Вычислить логарифм отношения (средний серый) / лог (средний) на сером или канале значений Увеличьте ввод или значение до степени отношения При использовании канала значений объедините канал нового значения с каналами оттенка и насыщенности и преобразуйте обратно в RGB
Ввод:
import cv2
import numpy as np
import math
# read image
img = cv2.imread('lioncuddle1.jpg')
# METHOD 1: RGB
# convert img to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# compute gamma = log(mid*255)/log(mean)
mid = 0.5
mean = np.mean(gray)
gamma = math.log(mid*255)/math.log(mean)
print(gamma)
# do gamma correction
img_gamma1 = np.power(img, gamma).clip(0,255).astype(np.uint8)
# METHOD 2: HSV (or other color spaces)
# convert img to HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
hue, sat, val = cv2.split(hsv)
# compute gamma = log(mid*255)/log(mean)
mid = 0.5
mean = np.mean(val)
gamma = math.log(mid*255)/math.log(mean)
print(gamma)
# do gamma correction on value channel
val_gamma = np.power(val, gamma).clip(0,255).astype(np.uint8)
# combine new value channel with original hue and sat channels
hsv_gamma = cv2.merge([hue, sat, val_gamma])
img_gamma2 = cv2.cvtColor(hsv_gamma, cv2.COLOR_HSV2BGR)
# show results
cv2.imshow('input', img)
cv2.imshow('result1', img_gamma1)
cv2.imshow('result2', img_gamma2)
cv2.waitKey(0)
cv2.destroyAllWindows()
# save results
cv2.imwrite('lioncuddle1_gamma1.jpg', img_gamma1)
cv2.imwrite('lioncuddle1_gamma2.jpg', img_gamma2)
Результат метода 1:
Результат метода 2: