Добавить градиент RGBA к изображению RGB в OpenCV - PullRequest
0 голосов
/ 04 апреля 2020

Я хочу добавить / объединить градиент RGBA к черно-белому (ч / б) изображению RGB, чтобы можно было регулировать «яркость» ч / б изображения по одной оси.

градиентное изображение должно быть градиентом от белого к прозрачному вдоль горизонтальных осей. «Белизна» контролируется value, в то время как value_min предполагается минимальным достигнутым значением «белизны». edge - это значение x, которое линейный градиент должен достичь 0 или value_min (в этом случае значение value_min было достигнуто ранее).

А вот пример входного изображения, градиента и выходного изображения.

example_inputgradientexample_output

Выполнено как show_pre_pic(value=255, value_min=0, edge=100)

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

Я уже Проработал некоторый код, но он не работает, а просто завершает работу приложения PyQt, в котором он реализован (и ядра Spyder). Приложение PyQt работало до введения альфа-канала градиента и преобразования image в RGBA. Изображение преобразуется в RGBA, поскольку для cv.addWeighted() необходимо, чтобы оба изображения имели одинаковый размер и количество каналов (gradient будет иметь 4 канала, image имеет 3).

Для моего первого подхода я следовал этот ответ в качестве руководства, но он не работал.

Вот последняя рабочая версия кода, без введения альфа-канала и прозрачности:

import cv2 as cv
import numpy as np

def show_pre_pic(value, value_min, edge):
    #load image
    image = cv.imread("example.jpg")
    #create gradient
    gradient = create_gradient(image.shape[1], image.shape[0], value, value_min, edge)

    #merge image with gradient
    image = cv.addWeighted(image, 0.5, gradient, 0.5, 0)

    #save gradient and image
    cv.imwrite("example_output.png", image)
    cv.imwrite("gradient.png", gradient)

def create_gradient(width, height, value, value_min, edge):

    # Create blank image
    gradient = np.zeros((height, width, 3), np.uint8)

    #go through all lines of pixels horizontally
    for x in range(0, width):
        #if value is smaller than value_min make all pixels value_min
        if value <= value_min:
            gradient[0:height,x] = (value_min,value_min,value_min)
        #make all lines of pixels = value    
        else:
            gradient[0:height,x] = (value, value, value)
            #decrease value so that it reaches 0 by x = edge
            value = value - (255/edge)

    return gradient

if __name__ == "__main__":
    show_pre_pic(255, 0, 100)

В приложении значения: value, value_min и edge можно настроить с помощью ползунков с немедленным предварительным просмотром. Производительность не была проблемой (пока), потому что фактически используемые изображения имеют небольшой размер (8 КБ) и все загружаются в память (не загружаются напрямую с помощью cv.imread(), как показано здесь).

...