Какой метод коррекции яркости изображения с использованием PIL или Opencv? - PullRequest
2 голосов
/ 30 сентября 2019

Я смотрю, как использовать OpenCV или другую библиотеку для коррекции цвета изображения. В идеале я должен иметь возможность выбрать фиксированную область изображения, взять его значения RGB и затем настроить все изображение так, чтобы эти значения RGB соответствовали стандарту. Эта фиксированная область будет коричневой карточкой. Похоже на серые карты в фотографии. Эта карта всегда будет находиться в одной и той же области изображения.

У меня есть несколько камер, которые, кажется, дают немного другую экспозицию или освещают изображение.

Например, RGB должен быть 39,28,26. Если получится 42,28,26, то из канала R для всего изображения будет вычтено 3 и т. Д.

Я рад преобразовать в цветовое пространство LAB для регулировки уровня яркости, если это кажется более простым?

У кого-нибудь есть идеи? Это похоже на то, как работает lightroom для компенсации изображений с серой карты.

До сих пор я пытался углубиться в Opencv и PIL, но не смог найти правильных методов. Мне удалось получить значение каналов RGB карты в изображении. Но не корректируйте эти значения.

img = Image.open("data/sample_image.tif")
pixels = img.load()

#get the R value of the pixel at x=2400, y=2400
pixels[2400, 2400][0]

Ответы [ 2 ]

1 голос
/ 01 октября 2019

Я думаю, что @ fmw42, возможно, ответил на мой вопрос в качестве комментария.

Я перешел по предложенной ссылке: Pyimage Search Color Transfer и отредактировал ее для использования в IDE, Juypter Notebook,Я также изменил его так, чтобы он считывал обрезанную часть моего изображения в качестве источника (изображение с идеальной яркостью), а обрезанную часть - как цель (изображение с неправильной яркостью). Затем я нашел необходимые настройки, используя эти два обрезанных изображения, а затем применил их ко всему изображению.

Исходное изображение макета (идеальная яркость) Source Image Целевое изображение макета (неправильная яркость, чтобыбыть исправлено) Target Image

#import the necessary packages
import numpy as np
import cv2


def color_transfer(source, target):
    source = cv2.cvtColor(source, cv2.COLOR_BGR2LAB).astype("float32")
    source_crop = cv2.cvtColor(source_c, cv2.COLOR_BGR2LAB).astype("float32")
    target = cv2.cvtColor(target, cv2.COLOR_BGR2LAB).astype("float32")
    target_crop = cv2.cvtColor(target_c, cv2.COLOR_BGR2LAB).astype("float32")

#compute color statistics for the source and target images
    (lMeanSrc, lStdSrc, aMeanSrc, aStdSrc, bMeanSrc, bStdSrc) = image_stats(source)
    (lMeanSrc_c, lStdSrc_c, aMeanSrc_c, aStdSrc_c, bMeanSrc_c, bStdSrc_c) = image_stats(source_crop)
    (lMeanTar_c, lStdTar_c, aMeanTar_c, aStdTar_c, bMeanTar_c, bStdTar_c) = image_stats(target_crop)
    (lMeanTar, lStdTar, aMeanTar, aStdTar, bMeanTar, bStdTar) = image_stats(target)

#subtract the means from the target image
    (l, a, b) = cv2.split(target) #Split target image into l,a,b channels. 
    l -= lMeanTar_c #Subtract Mean value of cropped Target image
    #a -= aMeanTar_c
    #b -= bMeanTar_c

    #scale by the standard deviations
    l = (lStdTar / lStdSrc) * l #std deviation of whole target image divided by source image
    #a = (aStdTar / aStdSrc) * a
    #b = (bStdTar / bStdSrc) * b

    #add in the source mean
    l += lMeanSrc_c #Add the mean of the cropped image onto the Lightness. 
    #a += aMeanSrc_c
    #b += bMeanSrc_c

    #clip the pixel intensities to [0, 255] if they fall outside
    #this range
    l = np.clip(l, 0, 255) #ensure Lightness is within 0-255 boundaries. 
    #a = np.clip(a, 0, 255)
    #b = np.clip(b, 0, 255)


    #merge the channels together and convert back to the RGB color
    #space, being sure to utilize the 8-bit unsigned integer data
    #type
    transfer = cv2.merge([l, a, b])
    transfer = cv2.cvtColor(transfer.astype("uint8"), cv2.COLOR_LAB2BGR)

    #return the color transferred image
    return transfer

def image_stats(image):
    """
    Parameters:
    -------
    image: NumPy array
        OpenCV image in L*a*b* color space
    Returns:
    -------
    Tuple of mean and standard deviations for the L*, a*, and b*
    channels, respectively
    """
    #compute the mean and standard deviation of each channel
    (l, a, b) = cv2.split(image)
    (lMean, lStd) = (l.mean(), l.std())
    (aMean, aStd) = (a.mean(), a.std())
    (bMean, bStd) = (b.mean(), b.std())

    # return the color statistics
    return (lMean, lStd, aMean, aStd, bMean, bStd)

Затем прочитайте в изображениях:



target = cv2.imread("data/IssueImage.jpg")
y=2400
x=2400
h=500
w=300

target_c = target[y:y+h, x:x+w]
source = cv2.imread("data/Good_Image.jpg")
source_c = source[y:y+h, x:x+w]

Run Code

def show_image(title, image, width = 1000):
    # resize the image to have a constant width, just to
    # make displaying the images take up less screen real
    # estate
    r = width / float(image.shape[1])
    dim = (width, int(image.shape[0] * r))
    resized = cv2.resize(image, dim, interpolation = cv2.INTER_AREA)

    # show the resized image
    cv2.imshow(title, resized)


# transfer the color distribution from the source image
# to the target image
transfer = color_transfer(source, target)

# check to see if the output image should be saved

# show the images and wait for a key press
show_image("Source", source)
show_image("Target", target)
show_image("Transfer", transfer)
cv2.waitKey(0)

Это похоже на работудостаточно хорошо. Хотя я внес изменения в код, например, используя стандартное отклонение всего изображения, но имею в виду обрезанное изображение ... Это может означать, что я "злоупотребляю" тем, как это должно работать, и не даю точных результатов.

Изображения не выглядят точно так же, когда я делаю это на моих реальных изображениях, но довольно близко.

Я пишу здесь на случай, если у кого-то еще есть подобная проблема. Но также в случае, если кто-то может обнаружить любую явно очевидную проблему в моем коде.

Спасибо

Я также попробовал пример цветочных картинок в этой теме. Я использовал более темное изображение в качестве цели и более светлое в качестве источника (идеальная яркость). Flower Comparison Левое изображение идеально, среднее - это тестовое изображение, справа - тестовое изображение, настроенное так же, как и левое.

Это похоже на работу, но вы заметите, что это многоменее живой.

0 голосов
/ 30 сентября 2019

Яркость и контраст можно отрегулировать с помощью альфа (α) и бета (β) соответственно. Выражение может быть записано как

enter image description here

OpenCV уже реализует это как cv2.convertScaleAbs(), просто предоставьте пользовательский alpha иbeta значения. Я не уверен, как настроить его на основе значений RBG, соответствующих стандарту


До (слева), После (справа)

enter image description here enter image description here

import cv2

image = cv2.imread('1.jpg')

alpha = 1.95 # Contrast control (1.0-3.0)
beta = 25 # Brightness control (0-100)

adjusted = cv2.convertScaleAbs(image, alpha=alpha, beta=beta)

cv2.imshow('original', image)
cv2.imshow('adjusted', adjusted)
cv2.waitKey()
...