Как лучше всего усреднить два цвета, которые определяют линейный градиент?

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

т.е. NewColor = (R1 + R2) / 2, (G1 + G2) / 2, (B1 + B2) / 2

РЕДАКТИРОВАТЬ1: Спасибо за все ответы. Для моих текущих потребностей я имею дело только с цветными парами, которые представляют собой оттенки одного цвета, поэтому я думаю, что их усреднение будет работать. Тем не менее, я попробую преобразовать в Lab Space, чтобы убедиться, что это предположение верно, и метод будет полезен в будущем.

EDIT2: вот мои результаты FWIW. Color1 и Color2 - это два моих цвета, а два средних столбца - это результаты усреднения в пространстве L a b и усреднения RGB соответственно. В этом случае между двумя цветами нет большой разницы, поэтому различия в выходных данных методов усреднения незначительны.

визуальное сравнение методов усреднения цвета


person eft    schedule 16.03.2009    source источник
comment
Хороший вопрос. Я тоже иногда думал об этом.   -  person tehvan    schedule 16.03.2009


Ответы (8)


Ознакомьтесь с ответами на этот вопрос.

По сути, вы хотите преобразовать цвета в нечто, называемое лабораторное пространство, и найти их среднее значение в этом пространстве. .

Лабораторное пространство - это способ представления цветов, где точки, которые расположены близко друг к другу, похожи друг на друга для людей.

person Blorgbeard    schedule 16.03.2009
comment
Интересный. До сих пор я использовал просто HSL, но похоже, что Lab стоит изучить. - person MattJ; 16.03.2009
comment
Могу ли я использовать это лабораторное пространство для представления линейного диапазона значений для кодирования значений в цвета во всем диапазоне цветов, а не только в виде оттенков серого или другой яркости. stackoverflow.com/questions/7182318/ - person Horst Walter; 25.08.2011
comment
Другими словами, цвета в пространстве Lab распределены более равномерно, чем в большинстве других цветовых пространств, с точки зрения человеческого восприятия. Поэтому усредненный цвет в Lab лучше отображает визуальный центр цветов, особенно при большой разнице цветов (например, Delta E ›4). Когда разница в цвете меньше, можно выполнить усреднение в любом цветовом пространстве. - person Tae-Sung Shin; 26.07.2017

В нескольких ответах предлагается преобразование в цветовое пространство 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 < / а>

person arntjw    schedule 11.04.2015
comment
Ага, ответ, который распознает логарифмическое пространство, которое изображения используют в мире изображений! Для взвешенных смесей (т.е. 75% цвета A и 25% цвета B) используйте NewColor = sqrt(R1^2*w + R2^2*[1 - w]), sqrt(G1^2*w + G2^2*[1 - w]), sqrt(B1^2*w + B2^2*[1 - w]), где w - вес от 0 до 1. - person Dan W; 15.02.2016
comment
Это тот ответ, который на самом деле ищет большинство людей, которые задаются вопросом через Google. - person gd1; 12.04.2016
comment
Как мне обобщить это на произвольное количество цветов? Могу ли я по-прежнему использовать sqrt (сумму квадратов) для каждого канала? - person Prashanth Chandra; 23.01.2017
comment
для 3 цветов вы делите на 3 и, как обычно, используете корень sqrt. Например NewColorR = sqrt((R1^2+R2^2+R3^2)/3). This is just for red component. Do same for green` и blue - person mitjap; 14.09.2017
comment
Кто-нибудь знает, как реализовать эту операцию с помощью opencv? - person gameon67; 27.05.2019
comment
Короче, используйте среднее квадратичное вместо среднего арифметического. - person Ferazhu; 12.09.2020

Усреднение в цветовом пространстве HSL может дать лучшие результаты.

person eugensk    schedule 16.03.2009
comment
Я думаю, он имеет в виду легкость, насыщенность, оттенок. Я считаю, что это то же самое, что и HSV / HSL - попробуйте их в википедии. - person Blorgbeard; 16.03.2009

Я не знаю, является ли простое усреднение компонентов «лучшим» с точки зрения восприятия (это звучит как вопрос для психолога), но вот несколько примеров с использованием простого усреднения компонентов.

alt text

Красно-горчично-зеленый некрасиво, но интерполяция кажется достаточно разумной.

person Community    schedule 16.03.2009
comment
Я знаю, что картинка стоит тысячи слов, но иногда можно использовать и несколько слов - person 1800 INFORMATION; 16.03.2009

да. Таким образом можно усреднить два цвета вместе. Это подход, используемый OpenGL для смешивания цветов (например, при создании MIP-карт для рендеринга удаленных объектов или рендеринга 50% прозрачной текстуры). Это быстро, просто и «достаточно хорошо» для многих ситуаций. Однако это не совсем реалистично и, вероятно, не будет использоваться для изображений фотографического качества.

person Cybis    schedule 16.03.2009
comment
Окружающая среда просмотра и свойства дисплея имеют огромное влияние на восприятие цвета, поэтому я согласен с тем, что простого усреднения достаточно для большинства ситуаций. - person TrayMan; 16.03.2009

Это трудно. Во-первых, набор значений RGB не определяет цвет. Их необходимо интерпретировать в свете основных цветов, к которым они относятся (цветовое пространство), таких как sRGB, Rec.709, Rec.2020, Adobe RGB (1998) и т. Д.

Кроме того, значения RGB, с которыми мы обычно сталкиваемся, не пропорциональны линейному свету: они «кодируются» с помощью нелинейной функции (гамма). И иногда (в основном в видеоприложениях) значение «черного» не равно нулю, а смещено от нуля, обычно 16 для 8-битных значений. А «белый» - это не 255, а 235. sRGB и Rec.709 имеют общие основные цвета RGB, но их гамма-функции различны.

Преобразование цветового пространства начинается с удаления любого смещения черного, чтобы черный был равен нулю. Если гамма-функция имеет точку останова (например, sRGB и Rec.709), вам нужно будет тщательно масштабировать значения RGB, чтобы «белый» был равен 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 известно как «дельта-E». Простая формула дельта-евклидова расстояния теперь называется dE76. См. https://en.wikipedia.org/wiki/Color_difference)

В вашем случае вы можете усреднить два цвета Lab, чтобы получить новый цвет Lab, а затем отменить все преобразования, чтобы вернуться к RGB в выбранном вами цветовом пространстве.

Это приблизит вас, но не гарантируется, просто потому, что «цвет» - это человеческое восприятие, а не физическая величина, и его, как известно, трудно надежно охарактеризовать. Лаборатория на самом деле не очень хорошо справлялась с единообразием восприятия. Поэтому вместо исправления Lab они предложили новую, более сложную функцию дельта-E с еще одним встроенным деформированием: DE94. Это было лучше, но не идеально, поэтому в 2000 году появилось другое предложение: DE2000. Тоже лучше, но не идеально. См. Эту страницу Wiki выше для получения дополнительной информации.

Если DE2000 недостаточно хорош (или слишком сложен!), Вы можете взглянуть на альтернативу Lab под названием ICtCp, который считается более однородным по восприятию, чем Lab.

person user1539094    schedule 28.06.2017

Я думаю, что ответ от arntjw идет в правильном направлении и распознает логарифмическую основу, как упоминал Дэн В. Однако правильное среднее геометрическое не sqrt ((C1 ^ 2 + C2 ^ 2) / 2), а sqrt (С1 * С2). Итак, средний цвет будет:

NewColor = sqrt(R1*R2),sqrt(G1*G2),sqrt(B1*B2)

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

person lenov    schedule 07.09.2017
comment
Будьте осторожны, используя это для цветов, у которых 0 компонентов. Рассмотрим усреднение чистого красного (255, 0, 0) с чистым синим (0, 0, 255). Среднее значение будет черным, когда мы действительно ожидаем пурпурного. - person Jon Hardy; 20.09.2017
comment
Не могли бы вы подробнее объяснить, почему это подходящее средство? Также как бы вы справились с усреднением более двух цветов? Вы бы перемножили их все вместе, а затем извлекли бы корень из того, сколько цветов у вас есть? - person Kevin Workman; 20.11.2018

На самом деле есть способ намного проще.

  • Уменьшите масштаб изображения до 1 на 1 пиксель.

    Цвет 1 пиксель - это средний цвет всего, что вы масштабировали

person jellohead    schedule 14.03.2013
comment
Это странный ответ, поскольку он в основном ужасен (чрезвычайно неэффективен с точки зрения вычислений и не отвечает на вопрос на фундаментальном уровне), но он действительно практичен. Это полностью работает при определенных обстоятельствах. - person Newb; 17.12.2014