Каков наилучший способ усреднения двух цветов, определяющих линейный градиент?
Вопрос
Если у меня есть два цвета, определенные по их значениям RGB, могу ли я усреднить значения красного, зеленого и синего, а затем объединить, чтобы определить третий цвет, который выглядит как визуальное среднее из двух?
т.е. newColor = (R1+ R2)/2, (G1+ G2)/2, (B1+ B2)/2
РЕДАКТИРОВАТЬ 1:Спасибо за все ответы.Для моих текущих нужд я имею дело только с цветовыми парами, которые являются оттенками одного цвета, поэтому я думаю, что их усреднение сработает.Тем не менее, я попробую преобразовать в лабораторное пространство, чтобы убедиться, что это предположение верно и методика окажется полезной в будущем.
РЕДАКТИРОВАТЬ 2:Вот мои результаты FWIW.Color1 и Color2 - это мои два цвета, а два средних столбца - результаты усреднения в Lab пробел и усреднение RGB соответственно.В этом случае между двумя цветами нет большой разницы, и поэтому различия в выходных данных, полученных с помощью методов усреднения, незначительны.
Решение
Посмотрите ответы на этот вопрос . р>
Как правило, вы хотите преобразовать цвета в нечто, называемое лабораторное пространство , и найти их средний в этом пространстве.
Лабораторное пространство - это способ представления цветов, когда точки, близкие друг к другу, являются точками, которые похожи друг на друга для людей.
Другие советы
В нескольких ответах предлагается преобразовать в цветовое пространство Lab - это, вероятно, хороший подход для более сложных манипуляций с цветом.
Но если вам просто нужен быстрый способ получить среднее из двух цветов, это можно сделать в пространстве RGB. Вы просто должны иметь в виду предостережение: вы должны возвести в квадрат значения RGB перед их усреднением, а затем взять корень результата. (Если вы просто возьмете среднее значение, результат будет слишком темным.)
Вот так:
NewColor = sqrt((R1^2+R2^2)/2),sqrt((G1^2+G2^2)/2),sqrt((B1^2+B2^2)/2)
Вот хороший видеоролик, объясняющий, почему этот метод эффективен: https://www.youtube.com/watch?v = LKnqECcg6Gw р>
Усреднение в цветовом пространстве HSL может привести к лучшим результатам.
Я не знаю, является ли взятие простого среднего из компонентов " best " с точки зрения восприятия (это звучит как вопрос для психолога), но вот пара примеров, использующих простое усреднение компонентов.
Красный - горчично-зеленый - некрасив, но интерполяция кажется достаточно разумной.
ДА.Таким образом, вы можете усреднить два цвета вместе.Это подход, используемый OpenGL для смешивания цветов (например, при создании mip-карт для рендеринга удаленных объектов или рендеринга 50% прозрачной текстуры).Это быстро, просто и "достаточно хорошо" для многих ситуаций.Однако это не совсем реалистично и, вероятно, не будет использоваться на изображениях фотографического качества.
Это сложно. Во-первых, набор значений RGB не определяет цвет. Их необходимо интерпретировать в свете основных цветов, к которым они относятся (цветовое пространство), таких как sRGB, Rec.709, Rec.2020, Adobe RGB (1998) и т. Д.
Кроме того, значения RGB, с которыми мы обычно сталкиваемся, не пропорциональны линейному свету: они " закодированы " используя нелинейную функцию (гамма). И иногда (в основном в видеоприложениях) значение & Quot; black & Quot; не ноль, но смещение от нуля, обычно 16 для 8-битных значений. И & Quot; белый & Quot; не 255, а 235. sRGB и Rec.709 совместно используют основные цвета RGB, но их гамма-функции различны.
Преобразование цветового пространства начинается с удаления любого черного смещения, так что черный становится нулевым. Если гамма-функция имеет точку останова (как это делают sRGB и Rec.709), вам нужно будет тщательно масштабировать значения RGB, чтобы & Quot; white & Quot; это 1,0. Р>
Затем " раскодировать " гамма, делая обратное исходной гамма-функции. (В одном ответе предлагалось возвести в квадрат значения, что является приближением гамма-декодирования.) Теперь у вас есть линейные значения RGB в некотором цветовом пространстве. На данный момент вы можете конвертировать из этого цветового пространства в пространство Lab. Большинство преобразований из RGB в Lab проходит через промежуточное цветовое пространство, называемое XYZ. Р>
Шаги как вызовы вложенных функций:
Lab = XYZ2Lab (RGB2XYZ (gamma_decode (offset_and_scale (RGB), gammaFunction ), цветовое пространство RGB ))
(Лабораторное пространство было разработано в 1976 году как попытка создать перцептуально-равномерную деформацию стандартного пространства CIE XYZ. (Luv была еще одной попыткой.) Идея заключается в том, что евклидово (прямолинейное) расстояние между двумя цветами только что заметно отличающиеся (1 " JND ") будут одинаковыми расстояниями для любых двух цветов. Расстояние между двумя цветами в Lab известно как «delta-E». Простая дельта-евклидова формула расстояния теперь называется dE76. См. https://en.wikipedia.org/wiki/Color_difference) р>
В вашем случае вы можете усреднить два цвета Lab, чтобы получить новый цвет Lab, а затем отменить все преобразования, чтобы вернуться к RGB в выбранном вами цветовом пространстве.
Это приблизит вас, но это не гарантировано, просто потому что " color " является человеческим восприятием, а не физической величиной, и его, как известно, трудно надежно охарактеризовать. Лаборатория на самом деле не работала так хорошо, чтобы быть одинаково воспринимаемой. Поэтому вместо исправления Lab они предложили новую, более сложную функцию delta-E с еще одной встроенной функцией деформации: DE94. Это было лучше, но не идеально, поэтому в 2000 году появилось еще одно предложение: DE2000. Также лучше, но не идеально. Смотрите эту страницу вики выше для получения дополнительной информации. Р>
Если DE2000 недостаточно хорош (или слишком сложен!), вы можете взглянуть на альтернативу Lab под названием ICtCp , который, как утверждается, является более восприимчивым, чем Lab.
Я думаю, что ответ от arntjw идет в правильном направлении и распознает логарифмическую подложку, как упомянуто Дэном В. Однако правильное среднее геометрическое значение не является sqrt ((C1 ^ 2 + C2 ^ 2) / 2) , но sqrt (C1 * C2). Таким образом, средний цвет будет:
NewColor = sqrt(R1*R2),sqrt(G1*G2),sqrt(B1*B2)
Получающиеся цвета ближе к тому, что мы ожидаем. Вы можете обобщить большее количество цветов, используя корни более высокого порядка, и взвесить каждый цвет, добавив экспоненту к его компонентам. Р>
На самом деле есть гораздо более простой способ.
Уменьшите изображение до размера 1 на 1 пиксель.
Цвет 1px - это средний цвет всего, что вы масштабировали