Преобразование RGB в HSV с использованием PIL

Я пытаюсь автоматизировать улучшение некоторых изображений, которые должны быть перенесены в цифровой кадр. У меня есть код, который изменяет размеры, добавляет дату / время к наименее значимому (наименее подробному) углу изображения и вставляет вместе пары портретных изображений, чтобы избежать отображения одного портрета на экране с низким разрешением кадра 41:20.

Я реализовал фильтр растяжения яркости для тех изображений, где освещение было не очень хорошим, используя colorsys.rgb_to_hsv функция для вычисления диапазонов H, S, V, работающая на полосе V и затем преобразующая обратно в RGB перед сохранением JPEG в цифровом кадре. Очевидно, что преобразование занимает много времени, даже используя itertools трюки; Мне удалось улучшить вещи, используя psyco,

Тем не менее, я заметил пример для PIL Image.convert где RGB можно преобразовать в цветовое пространство XYZ с использованием матрицы 4×4 в качестве второго аргумента convert метод, и я должен задаться вопросом:

Как я могу преобразовать RGB в HSV (а затем HSV обратно в RGB), используя пользовательскую матрицу в convert вызов метода? (Незначительные ошибки округления в данном случае не важны, поэтому я не против, чтобы каждая полоса была выражена в виде серии от 0 до 255 целых чисел)

Заранее спасибо.

2 ответа

Решение

Хотя я видел ссылки [1], в которых утверждается, что цветовое пространство HSV является линейным преобразованием из RGB, что, по-видимому, подразумевает, что это может быть сделано с помощью матрицы, я не смог найти или определить для себя, что такое матрица. будет выглядеть так. В некотором смысле это меня не удивляет, основываясь на всех [похожих] нематричных процедурных реализациях, которые я также видел, - то, как они работают, не выглядит линейным.

В любом случае, глядя на это, я наткнулся на [несколько устаревшую] статью в онлайновой записной книжке по компьютерной графике бывшего исследователя SGI под названием " Матричные операции для обработки изображений", в которой описывается, как выполнять ряд различных преобразований цвета с использованием матриц 4x4, которые могут помочь тебе. Все приведенные примеры работают непосредственно с цветными изображениями RGB и, подобно преобразованиям геометрических матриц, любая их последовательность может быть объединена в одну матрицу с использованием конкатенации.

Надеюсь это поможет.


[1]:преобразования цветового пространства< http://www.poynton.com/PDFs/coloureq.pdf>:

2.7.3 HSL (насыщенность оттенка и легкость)

Это представляет множество сходных цветовых пространств, альтернативные названия включают HSI (интенсивность), HSV (значение), HCI (цветность / цветность), HVC, TSD (насыщенность оттенка и темнота) и т. Д. Большинство из этих цветовых пространств являются линейными преобразованиями из RGB. и поэтому зависят от устройства и нелинейны. Их преимущество заключается в чрезвычайно интуитивной манере определения цвета. Очень легко выбрать желаемый оттенок и затем слегка изменить его, отрегулировав его насыщенность и интенсивность.

Формулу для преобразования значения RGB в значение HSV можно найти здесь: http://www.rapidtables.com/convert/color/rgb-to-hsv.htm. Когда-то я нуждался в этом, и сделал для него следующую функцию.

def hsb2rgb(hsb):
    '''
    Transforms a hsb array to the corresponding rgb tuple
    In: hsb = array of three ints (h between 0 and 360, s and v between 0 and 100)
    Out: rgb = array of three ints (between 0 and 255)
    '''
    H = float(hsb[0] / 360.0)
    S = float(hsb[1] / 100.0)
    B = float(hsb[2] / 100.0)

    if (S == 0):
        R = int(round(B * 255))
        G = int(round(B * 255))
        B = int(round(B * 255))
    else:
        var_h = H * 6
        if (var_h == 6):
            var_h = 0  # H must be < 1
        var_i = int(var_h)
        var_1 = B * (1 - S)
        var_2 = B * (1 - S * (var_h - var_i))
        var_3 = B * (1 - S * (1 - (var_h - var_i)))

        if      (var_i == 0):
            var_r = B     ; var_g = var_3 ; var_b = var_1
        elif (var_i == 1):
            var_r = var_2 ; var_g = B     ; var_b = var_1
        elif (var_i == 2):
            var_r = var_1 ; var_g = B     ; var_b = var_3
        elif (var_i == 3):
            var_r = var_1 ; var_g = var_2 ; var_b = B
        elif (var_i == 4):
            var_r = var_3 ; var_g = var_1 ; var_b = B
        else:
            var_r = B     ; var_g = var_1 ; var_b = var_2

        R = int(round(var_r * 255))
        G = int(round(var_g * 255))
        B = int(round(var_b * 255))

    return [R, G, B]
Другие вопросы по тегам