Алгоритм плавного перехода цвета

Я ищу общий алгоритм плавного перехода между двумя цветами.

Например, это изображение взято из Википедии и показывает переход от оранжевого к синему.

Когда я пытаюсь сделать то же самое, используя свой код (C ++), сначала пришла в голову идея использовать цветовое пространство HSV, но появляются раздражающие промежуточные цвета.

Как лучше всего этого добиться? Кажется, это связано с уменьшением контраста или, может быть, с использованием другого цветового пространства?


Я делал множество таких в прошлом. Сглаживание можно выполнять разными способами, но, вероятно, здесь используется простой линейный подход. Это означает, что для каждого компонента R, G и B они просто вычисляют уравнение «y = m * x + b», которое соединяет две точки, и используют это для определения компонентов между ними.

  m [RED] = (ColorRight [RED] - ColorLeft [RED])/PixelsWidthAttemptingToFillInm [GREEN] = (ColorRight [GREEN] - ColorLeft [GREEN])/PixelsWidthAttemptingToFillInm [BLUE] =  (ColorRight [СИНИЙ] - ColorLeft [СИНИЙ])/PixelsWidthAttemptingToFillInb [RED] = ColorLeft [RED] b [GREEN] = ColorLeft [GREEN] b [СИНИЙ] = ColorLeft [СИНИЙ]  

Теперь любой новый цвет между ними:

  NewCol [pixelXFromLeft] [RED] = m [RED] * pixelXFromLeft + ColorLeft [RED] NewCol [pixelXFromLeft] [GREEN]  = m [GREEN] * pixelXFromLeft + ColorLeft [GREEN] NewCol [pixelXFromLeft] [BLUE] = m [BLUE] * pixelXFromLeft + ColorLeft [BLUE]  

Существует множество математических способов создать переход, мы действительно хотим понять, какой переход вы действительно хотите увидеть. Если вы хотите увидеть точный переход от изображения выше, стоит взглянуть на значения цвета этого изображения. Я написал программу еще в прошлом, чтобы смотреть на такие изображения и выводить на них значения графически. Вот результат моей программы для указанной выше шкалы псевдоцветов.

Судя по графику, он ЯВЛЯЕТСЯ более сложным, чем линейный, как я сказал выше. Синий компонент выглядит в основном линейным, красный можно смоделировать до линейного, зеленый, однако, выглядит более округлым. Мы могли бы провести математический анализ грина, чтобы лучше понять его математическую функцию, и использовать его вместо этого. Вы можете обнаружить, что линейная интерполяция с нарастающим наклоном от 0 до ~ 70 пикселей с линейным уменьшением наклона после пикселя 70 достаточно хороша.

Если вы посмотрите на нижнюю часть экрана, эта программа дает некоторые статистические измерения каждого цветового компонента, такие как минимальное, максимальное и среднее значение, а также сколько пикселей в ширину было прочитано изображение.


Простая линейная интерполяция значений R, G, B сделает это.

звук трубы показал, что изображение, которое вы использовали, не является чисто линейной интерполяцией. Но я думаю, что интерполяция дает тот эффект, который вы ищете. Ниже я показываю изображение с линейной интерполяцией вверху и ваше исходное изображение внизу.

И вот код (Python), который его создал:

  для y в диапазоне (высота/2): для x в диапазоне (ширина)  : p = x/float (width - 1) r = int ((1.0-p) * r1 + p * r2 + 0.5) g = int ((1.0-p) * g1 + p * g2 + 0.5) b = int  ((1.0-p) * b1 + p * b2 + 0.5) pix [x, y] = (r, g, b)  

5


Цветовое пространство HSV не очень хорошее цветовое пространство для использования для плавных переходов. Это потому, что значение h , оттенок, просто используется для произвольного определения разных цветов вокруг «цветового круга». Это означает, что если вы перейдете между двумя цветами на большом расстоянии друг от друга на колесе, вам придется окунуться в кучу других цветов. Совершенно не гладко.

Было бы гораздо разумнее использовать RGB (или CMYK). Эти «компонентные» цветовые пространства лучше определить для создания плавных переходов, поскольку они представляют, сколько каждого «компонента» требуется цвету.

Линейный переход (см. Ответ @trumpetlicks) для каждого значения компонента, R, G и B должны выглядеть «неплохо». Для чего-то большего, чем « довольно хорошее », потребуется, чтобы настоящий человек настроил значения, потому что существуют различия и асимметрии в том, как наши глаза воспринимают значения цвета в разных цветовых группах, которые не представлены ни в RBG, ни в CMYK (или в любом стандарте). .

Изображение в Википедии использует алгоритм, который использует Photoshop. К сожалению, этот алгоритм не является общедоступным.

7


Я занимался этим, чтобы создать алгоритм, который принимает на вход изображение в градациях серого и искусственно раскрашивает его в соответствии с цветовой палитрой:

■■ ■■ Ввод в оттенках серого ■■■■ Вывод ■■■■■■■■■■■■■■■

Как и многие другие решения, алгоритм использует линейная интерполяция для перехода между цветами. В вашем примере smooth_color_transition () следует вызывать со следующими аргументами:

  QImage input ("gradient.jpg"); QVector  colors; colors.push_back (QColor (242, 177, 103)); //orangecolors.push_back (QColor (124, 162, 248)); //blue-ishQImage output = smooth_color_transition (input, colors);  output.save ("вывод. jpg ");  

Сравнение исходного изображения VS вывода из алгоритма можно увидеть ниже:

(вывод)

(original)

Визуальные артефакты, которые можно наблюдать на выходе, уже присутствуют на входе (оттенки серого). Входное изображение получило эти артефакты, когда его размер был изменен до 189×51.

Вот еще один пример, который был создается с помощью более сложной цветовой палитры:

■■■■ Ввод в оттенках серого ■■■■ Вывод ■■■■■■■■■■■■■■■


Кажется мне нравится, что было бы проще создать градиент, используя значения RGB. Сначала вы должны вычислить Вычислите изменение цвета для каждого значения в зависимости от ширины градиента. Следующий псевдокод необходимо сделать для значений R, G и B.

  if (redValue1 == redValue2) {redDifference = 0} else {redDifference = absoluteValue (redValue1  - redValue2)/widthOfGradient} if (redValue1> redValue2) {redDifference * = -1}  

Затем вы можете визуализировать каждый пиксель с этими значениями следующим образом:

  for (int i = 0; i  

Я знаю, что вы указали, что используете C ++, но я создал JSFiddle, демонстрирующий, как это работает с вашим первым градиентом в качестве примера: http:// jsfiddle.net/eumf7/



Как добиться плавных переходов между цветами при сохраняя острые края?

Я пытаюсь сгладить изображения цветных волн, сохраняя при этом острые края.

Exa часть исходного изображения:

Я имел некоторый ограниченный успех при использовании размытия поверхности, в то время как переходы между каждым цветом более плавные, я теряю резкость по краям:

Есть ли методика, фильтр эффекта, который я мог бы использовать для получения такого результата?

EDIT

вот результат благодаря @boblet

РЕДАКТИРОВАТЬ 2

Я нашел псевдо-альтернативу, которая отчасти достигает той же цели, хотя и не так хороша.

Дело в том, чтобы нарисовать градиентные линии средним цветом (0,5 ) быть немного темнее.

На самом деле это альтернатива для бедняков, пока я не смогу овладеть алгоритмом размытия поверхности, который не так легко реализовать, как кажется.


Paint.net и GIMP

Ниже приведен подробный пример того, как это сделать в Photoshop. Однако и Gimp, и paint.net имеют одинаковые возможности, хотя инструменты имеют немного разные названия.

GIMP, эквивалентный Photoshops волшебная палочка , — это Нечеткое выделение. Вы должны достичь того же результата.

photoshop.

Выберите белый фон с помощью инструмент "волшебная палочка" . Для этого сначала нажмите на верхнюю часть белого, удерживайте Shift, а затем выберите нижнюю часть.

Щелкните правой кнопкой мыши и выберите в меню выбрать инверсию .

Выберите инструмент размытия,

и смешайте цвета друг с другом, сколько душе угодно.

Оцените статью
clickpad.ru
Добавить комментарий