Так вот, два базовых цвета. Синий и оранжевый, или, допустим, коричневый и зелёный. А все остальные цвета приглушаются и приближаются к этим двум цветам.
У меня уже давным-давно лежит самодельная программка для работы с цветами изображения. Она умеет делать то, что ни один микшер каналов делать не умеет — например, может менять значение цвета одного канала при условии, что оно больше значения цвета другого канала, и причём делать его зависимым от этого другого канала.



Разумеется, я сразу бросился эту свою программку переделывать. Каждая точка изображения имеет координаты (R, G, B) в цветовом пространстве (RGB — Red, Green, Blue). Логично было предположить, что «базовые» цвета имеют свои координаты (R₁, G₁, B₁) и (R₂, G₂, B₂), и можно любую другую точку покомпонентно притянуть к этим координатам — к какой ближе. Некоторое время я с этим возился, но ничего у меня не получилось, и я надолго забил. С какой силой будет «притягиваться» цвет к базовому? А что делать, если это вообще чёрный цвет или белый?
Ещё моя программка умела конвертировать RGB в CMY (Cyan, Magenta, Yellow) и обратно для того, чтоб можно было оперировать с отдельными каналами в другом цветовом пространстве. Она это делала, вероятно, довольно странным способом, вычисляя значения для каждой компоненты по теореме Пифагора:
C = sqrt(G² + B²) M = sqrt(B² + R²) Y = sqrt(R² + G²)
Ну и обратно, соответственно,
R = sqrt(Y² + M² - C²) / 1.42 G = sqrt(Y² + C² - M²) / 1.42 B = sqrt(C² + M² - Y²) / 1.42
И совсем недавно мне вдруг пришла в голову идея. Если каждый цвет представлен точкой в трёхмерном пространстве координат (или, если хотите, вектором, начало которого лежит в (0, 0, 0) — в чёрном цвете), то можно перейти к другому базису, получить совершенно иные координаты, и оперировать покомпонентно уже с ними. Матрица перехода в CMY, при небольшом размышлении, оказалась вообще простой (может быть, не такой точной, как переход по теореме Пифагора, но без нормализации для вычислений должно хватать):
[ 0, 1, 1 ] [ 1, 0, 1 ] [ 1, 1, 0 ]
Умножая вектор цвета на такую матрицу, я получаю представление этого цвета в цветовом пространстве CMY. Потом могу что-то сделать с, например, жёлтой компонентой — например, ослабить или усилить, или заменить на среднее между малиновой и голубой в том случае, если значение жёлтой больше одной из них — и полученный вектор вернуть в RGB, умножив на обратную матрицу.
[ -1, 1, 1 ] [ 1, -1, 1 ] [ 1, 1, -1 ]
Можно перейти в любой другой базис, двумя составляющими которого могут быть два любых разных цвета (они дадут пару неколлинеарных векторов). Те же «базовые» цвета, о которых я упоминал вначале. Но нужна третья составляющая… а, пусть это будет просто вектор, перпендикулярный первым двум, пусть даже с отрицательными координатами — для математических вычислений насрать. Потом эту третью координату, допустим, занулить, или разделить на четыре, в зависимости оттого, насколько сильного эффекта я хочу добиться. И вернуть полученный вектор в пространство RGB. А вектор, перпендикулярный двум данным — это их векторное произведение.
Не уверен, что это самый простой способ, но с точки зрения сложности вычислений на каждом независимом шаге — довольно таки примитивный.
Я выбрал два цвета: ярко-голубой #33FAFF и оранжевый #EE9C00. Ну и добился своего. При стопроцентном применении этого, с позволения сказать, фильтра, все остальные цвета превратились в различные комбинации этих двух.


И как это выглядит с реальной фотографией (с нашей прошлогодней прогулки на гору Прадед).

Теперь меня, откровенно говоря, не оставляет ощущение, что я всё равно какое-то говно сделал, и фильтры в «инстаграме» как-то иначе и явно посложнее устроены :) А у меня вон красный цвет пропал, белый превратился в голубоватый… всё не то.
Ниже — прочие примеры работы моего скрипта, как удачные, так и не очень: побочные продукты во время написания и отладки.
















Комментариев нет:
Отправить комментарий
Ублюдочный Гугл поломал форму комментариев. Извините.
Примечание. Отправлять комментарии могут только участники этого блога.