Преобразование RGB в HSV с использованием PIL - PullRequest
8 голосов
/ 29 декабря 2010

Я пытаюсь автоматизировать улучшение некоторых изображений, которые должны быть перенесены в цифровой кадр. У меня есть код, который изменяет размеры, добавляет дату / время к наименее значимому (наименее подробному) углу изображения и вставляет пары портретных изображений, чтобы избежать отображения одного портрета на экране с низким разрешением кадра 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 голос
/ 30 декабря 2010

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

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

Надеюсь, это поможет.[1]: Преобразования цветового пространства <<a href="http://www.poynton.com/PDFs/coloureq.pdf" rel="nofollow">http://www.poynton.com/PDFs/coloureq.pdf>:

2.7.3 HSL (насыщенность оттенка и яркость)

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

0 голосов
/ 03 октября 2014

Формула для преобразования значения 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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...