Самый быстрый способ раскрасить пиксель другим пикселем
Предмет. Я хочу добиться раскраски одного пикселя другим пикселем, как в режиме наложения "Цвет" в Photoshop (с непрозрачностью 100%). Что я делаю сейчас:
- получить оттенок маски пикселя;
- преобразовать исходный пиксель из RGB в HSL;
- заменить оттенок и преобразовать обратно в RGB;
Если вы заинтересованы в формуле - проверьте это: Пожалуйста, объясните эту формулу режима смешивания цветов, чтобы я мог повторить ее в PHP/ImageMagick
Но для этой задачи преобразование back'n'forth из / в HSL/RGB кажется слишком чрезмерным.
Поэтому я ищу более быстрый подход. Я предполагаю, что должен быть способ как-то рассчитать коэффициенты RGB-умножения, а затем для исходного пикселя просто сделать что-то вроде этого:
src_R *= mult_R;
src_G *= mult_G;
src_B *= mult_B;
UPD: На самом деле мне не нужно, чтобы это было точно так же, как в Photoshop. Я упомянул режим смешивания PS только для примера. Я использую его в своей обычной процедуре свертки, поэтому хочу, чтобы она была быстрой, но точность не важна, поэтому даже если она может быть приближена к нескольким процентам. Просто я хочу найти подход, чтобы изменить тон пикселя без этих сложных преобразований HSL/RGB...
UPD2: После некоторых тестов я понял, что мой подход (замена оттенка) на самом деле довольно далек от того, что я хотел. Также после некоторых копаний я обнаружил, что режим наложения "Цвет" в PS заменяет не только оттенок, но и насыщенность. И удивительно, что делает алгоритм не более сложным, а, наоборот, немного проще (быстрее):
- нам нужно получить не только оттенок, но и насыщенность маски-пикселя
- но теперь нам не нужно преобразовывать src-pixel из RGB в HSL, потому что все, что нам нужно, это светимость, которая вычисляется намного быстрее, чем полная процедура RGB->HSL...
- с src-светимостью, маской-оттенком и сб. мы конвертируем его в RGB...
Это все еще довольно сложно, и я все еще верю, что это можно упростить.
1 ответ
Вы можете сделать Photoshop-подобное смешивание в ImageMagick, используя -compose colorize или -compose luminize. Что делается, так это передать либо канал интенсивности (яркости) между изображениями (luminize), либо комбинацию каналов Hue и Saturation (colorize) между изображениями через цветовое пространство RGB->HCL->RGB.
Обратите внимание, что обычно легче добавить цвет, чем удалить его. Но я пытаюсь сделать последнее здесь.
Входные изображения:
Вы можете сделать первое изображение более похожим на второе, используя -compose luminize или -compose colorize. Это зависит только от порядка двух входных изображений.
convert zelda1.jpg zelda1_tint.jpg -compose colorize -composite result.jpg
convert zelda1_tint.jpg zelda1.jpg -compose luminize -composite result.jpg
Если вы измените заказ, вы получите:
convert zelda1_tint.jpg zelda1.jpg -compose colorize -composite result2.jpg
convert zelda1.jpg zelda1_tint.jpg -compose luminize -composite result1.jpg
Я не уверен, по какому пути ты хочешь пойти.
Если вы возьмете последнее и добавите немного яркости и контрастности, тогда вы сможете приблизиться к первому изображению.
convert zelda1.jpg zelda1_tint.jpg -compose luminize -composite -brightness-contrast 15,-5 result1.jpg
Другой подход заключается в подборе яркости (среднего значения) и контрастности (стандартного отклонения) между двумя изображениями. Я использую один из моих сценариев оболочки Unix для этого.
При сопоставлении используются среднее и стандартное отклонения от каждого изображения в соответствии с уравнением: (I2-Mean2)/Std2 = (I1-Mean1)/Std1
, Это уравнение представляет нормированную интенсивность, такую, что оно имеет нулевое среднее значение и приблизительно тот же диапазон значений из-за деления на стандартные отклонения. Мы решаем это уравнение для формирования линейного преобразования между I1 и I2 в соответствии с I2=A*I1+B
, где A=(Std2/Std1)
это наклон или усиление и B=(Mean2-A*Mean1)
это перехват предвзятости. Сопоставление может быть сделано в разных цветовых пространствах. Здесь я использую LAB, но это также может быть сделано в RGB или YCbCr.
См. Также https://www.pyimagesearch.com/2014/06/30/super-fast-color-transfer-images/ и http://im.snibgo.com/gainbias.htm
matchimage -c lab zelda1_tint.jpg zelda1.jpg result.jpg
Наконец, другой способ - использовать сопоставление гистограммы между двумя изображениями. Я использую один из моих сценариев, чтобы сделать это. Это также может сделать это в различных цветовых пространствах. Здесь я использую RGB. Смотрите https://en.wikipedia.org/wiki/Histogram_matching
histmatch -c rgb zelda1.jpg zelda1_tint.jpg result3.jpg
Как видите, в данном случае это лучший подход.
Для всех, кто заинтересован, мои сценарии можно найти по адресу http://www.fmwconcepts.com/imagemagick/index.html