Преобразование 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]