Я ищу какую-то формулу или алгоритм для определения яркости цвета с учетом значений RGB. Я знаю, что это не может быть так просто, как сложение значений RGB и получение более высоких сумм, чтобы быть ярче, но я не знаю, с чего начать.
387
Ответы:
Вы имеете в виду яркость? Воспринимаемая яркость? Светимость?
(0.2126*R + 0.7152*G + 0.0722*B)
[1](0.299*R + 0.587*G + 0.114*B)
[2]→sqrt( 0.241*R^2 + 0.691*G^2 + 0.068*B^2 )
sqrt( 0.299*R^2 + 0.587*G^2 + 0.114*B^2 )
(благодаря @MatthewHerbst ) [3]источник
0.299*(R^2)
(потому что возведение в степень идет до умножения)Я думаю, что вы ищете формулу преобразования RGB -> Luma .
Фотометрический / цифровой ITU BT.709 :
Цифровой ITU BT.601 (придает больший вес компонентам R и B):
Если вы хотите обменять точность на производительность, для этого есть две формулы аппроксимации:
Их можно быстро рассчитать как
источник
Blue
+ 3 * Зеленый) / 6, 2-й (3 * Красный +Blue
+ 4 * Зеленый) >> 3. Разумеется, в обоих быстрых приближениях синий имеет наименьший вес, но он все еще там.Y = (R<<1+R+G<<2+B)>>3
(это всего лишь 3-4 такта процессора в ARM), но я думаю, хороший компилятор сделает эту оптимизацию за вас.Я сделал сравнение трех алгоритмов в принятом ответе. Я генерировал цвета в цикле, где использовался только каждый 400-й цвет. Каждый цвет представлен 2x2 пикселя, цвета сортируются от самых темных к самым светлым (слева направо, сверху вниз).
1-е изображение - Яркость (относительная)
2-я картинка - http://www.w3.org/TR/AERT#color-contrast
3-я картина - HSP Color Model
4-е изображение - формула относительной яркости и контрастности WCAG 2.0 SC 1.4.3 (см . Ответ @ Synchro здесь )
На 1-м и 2-м снимках иногда можно увидеть рисунок в зависимости от количества цветов в одном ряду. Я никогда не замечал никаких паттернов на картинке из 3-го или 4-го алгоритма
Если бы мне пришлось выбирать, я бы пошел с алгоритмом № 3, так как его гораздо проще реализовать и он примерно на 33% быстрее, чем 4-й.
источник
^2
и,sqrt
включенные в третью формулу, являются более быстрым способом приближения линейного RGB от нелинейного RGB вместо,^2.2
и^(1/2.2)
это было бы более правильным. Использование нелинейных входов вместо линейных, к сожалению, чрезвычайно распространено.Ниже приведен единственный ПРАВИЛЬНЫЙ алгоритм для преобразования изображений sRGB, используемых в браузерах и т. Д., В оттенки серого.
Необходимо применить обратную гамма-функцию для цветового пространства, прежде чем вычислять внутреннее произведение. Затем вы применяете гамма-функцию к уменьшенному значению. Невыполнение гамма-функции может привести к ошибкам до 20%.
Для типичных компьютерных вещей цветовое пространство sRGB. Правильные цифры для sRGB - ок. 0,21, 0,72, 0,07. Гамма для sRGB является сложной функцией, которая приближает возведение в степень на 1 / (2.2). Здесь все это в C ++.
источник
«Принятый» ответ является неправильным и неполным
Единственные точные ответы - это @ jive-dadson и @EddingtonsMonkey , а также support @ nils-pipenbrinck . Другие ответы (в том числе принятые) связаны или ссылаются на источники, которые являются либо неправильными, нерелевантными, устаревшими или сломанными.
Кратко:
Далее следует правильный и полный ответ:
Поскольку эта тема высоко ценится в поисковых системах, я добавляю этот ответ, чтобы прояснить различные неправильные представления по этому вопросу.
Яркость - это атрибут восприятия, он не имеет прямого измерения.
Воспринимаемая легкость измеряется некоторыми моделями зрения, такими как CIELAB, здесь L * (Lstar) является мерой воспринимаемой легкости и нелинейна для аппроксимации кривой нелинейного отклика человеческого зрения.
Яркость - это линейная мера света, спектрально взвешенная для нормального зрения, но не отрегулированная для нелинейного восприятия яркости.
Luma ( Y´ prime) - это гамма-кодированный, взвешенный сигнал, используемый в некоторых кодировках видео. Это не следует путать с линейной яркостью.
Гамма- кривая или кривая передачи (TRC) - это кривая, которая часто похожа на кривую восприятия и обычно применяется к данным изображения для хранения или широковещательной передачи, чтобы уменьшить воспринимаемый шум и / или улучшить использование данных (и связанные с этим причины).
Чтобы определить воспринимаемую яркость , сначала преобразуйте значения изображения R´G´B´ в гамма-коде в линейную яркость (
L
илиY
), а затем в нелинейную воспринимаемую яркость (L*
)НАЙТИ ЛЮМИНАНС:
... Потому что, видимо, это было где-то потеряно ...
Шаг первый:
Преобразовать все 8-битные целочисленные значения sRGB в десятичные 0.0-1.0
Шаг второй:
Преобразовать гамма-кодированный RGB в линейное значение. Например, sRGB (компьютерный стандарт) требует кривой мощности приблизительно V ^ 2.2, хотя «точное» преобразование:
Где V´ - канал R, G или B с гамма-кодированием sRGB.
псевдокод:
Шаг третий:
Чтобы найти яркость (Y), примените стандартные коэффициенты для sRGB:
Псевдокод с использованием вышеуказанных функций:
НАЙТИ ПЕРСПЕКТИВНОЕ МОЛНИЕ:
Шаг четвертый:
Возьмите яркость Y сверху и преобразуйте в L *
псевдокод:
L * - это значение от 0 (черный) до 100 (белый), где 50 - перцептуальный «средний серый». L * = 50 является эквивалентом Y = 18,4 или, другими словами, 18% серая карта, представляющая середину фотографической экспозиции (зона V Анселя Адамса).
Ссылки:
IEC 61966-2-1:1999 Standard
Wikipedia sRGB
Wikipedia CIELAB
Wikipedia CIEXYZ
Часто задаваемые вопросы о гамме Чарльза Пойнтона
источник
Luma=rgb2gray(RGB);LAB=rgb2lab(RGB);LAB(:,:,2:3)=0;PerceptualGray=lab2rgb(LAB);
L*a*b*
не учитывает ряд психофизических признаков. Эффект Гельмгольца-Кольрауша один, но есть много других. CIELAB - это не «полная» модель оценки изображений. В своем посте я пытался как можно полнее охватить основные понятия, не углубляясь в очень глубокие подробности. Модель Ханта, модели Фэйрчайлда и другие делают более полную работу, но они также значительно сложнее.Я нашел этот код (написанный на C #), который отлично справляется с расчетом «яркости» цвета. В этом сценарии код пытается определить, нужно ли поместить белый или черный текст поверх цвета.
источник
Интересно, что эта формулировка для RGB => HSV просто использует v = MAX3 (r, g, b). Другими словами, вы можете использовать максимум (r, g, b) как V в HSV.
Я проверил, и на странице 575 в Hearn & Baker они так же вычисляют «ценность».
источник
Вместо того, чтобы заблудиться среди случайного выбора формул, упомянутых здесь, я предлагаю вам перейти на формулу, рекомендованную стандартами W3C.
Вот прямая, но точная реализация PHP формул относительной яркости и контрастности WCAG 2.0 SC 1.4.3 . Он выдает значения, которые подходят для оценки соотношений, необходимых для соответствия WCAG, как на этой странице , и как таковые подходят и подходят для любого веб-приложения. Это тривиально портировать на другие языки.
источник
Чтобы добавить то, что сказали все остальные:
Все эти уравнения работают довольно хорошо на практике, но если вам нужно быть очень точным, вам нужно сначала преобразовать цвет в линейное цветовое пространство (применить обратную гамму изображения), сделать средневзвешенное значение основных цветов и - если вы хотите, чтобы отобразить цвет - вернуть яркость обратно в гамму монитора.
Разница в яркости между поглощением гаммы и выполнением правильной гаммы составляет до 20% в темных серых тонах.
источник
Я решал аналогичную задачу сегодня в JavaScript. Я остановился на этой
getPerceivedLightness(rgb)
функции для цвета HEX RGB. Он имеет дело с эффектом Гельмгольца-Кольрауша с помощью формул Фэрчайлда и Перротты для коррекции яркости.источник
Цветовое пространство HSV должно помочь, см. Статью в Википедии зависимости от языка, на котором вы работаете, вы можете получить преобразование библиотеки.
H является оттенком, который является числовым значением для цвета (то есть красный, зеленый ...)
S - насыщенность цвета, т. Е. Насколько он интенсивный
V - это «яркость» цвета.
источник
Значение яркости RGB = 0,3 R + 0,59 G + 0,11 B
http://www.scantips.com/lumin.html
Я думаю, что цветовое пространство RGB заметно неоднородно по отношению к евклидову расстоянию L2. Унифицированные пространства включают CIE LAB и LUV.
источник
Формула обратной гаммы Джайва Дадсона должна быть удалена с половиной корректировки при реализации в Javascript, то есть возвращение функции gam_sRGB должно возвращать int (v * 255); не вернуть int (v * 255 + .5); Полу-корректировка округляется, и это может привести к значению, слишком высокому для R = G = B, то есть для триады серого цвета. Преобразование в оттенки серого в триаде R = G = B должно давать значение, равное R; это одно из доказательств того, что формула верна. См. Nine Shades of Greyscale для формулы в действии (без половинной корректировки).
источник
Интересно, как эти коэффициенты RGB были определены. Я сам провел эксперимент и в итоге получил следующее:
Близко, но очевидно отличается от давно установленных коэффициентов МСЭ. Интересно, могут ли эти коэффициенты быть разными для каждого наблюдателя, потому что у всех нас может быть разное количество колбочек и палочек на сетчатке в наших глазах, и особенно соотношение между разными колбочками может отличаться.
Для справки:
МСЭ BT.709:
МСЭ BT.601:
Я выполнил тест, быстро переместив маленькую серую полоску на ярко-красный, ярко-зеленый и ярко-синий фон, и отрегулировал серый, пока он не смешался настолько, насколько это было возможно. Я также повторил этот тест с другими оттенками. Я повторил тест на разных дисплеях, даже с фиксированным гамма-фактором 3,0, но для меня все выглядит одинаково. Более того, коэффициенты МСЭ буквально не соответствуют моим глазам.
И да, у меня, видимо, нормальное цветовое зрение.
источник
Вот немного кода C, который должен правильно рассчитать воспринимаемую яркость.
источник
Пожалуйста, определите яркость. Если вы ищете, насколько близок белый цвет, вы можете использовать Евклидово расстояние от (255, 255, 255)
источник
«V» HSV, вероятно, то, что вы ищете. MATLAB имеет функцию rgb2hsv, а ранее цитированная статья в Википедии полна псевдокода. Если преобразование RGB2HSV невозможно, менее точной моделью будет версия изображения в градациях серого.
источник
Эта ссылка подробно объясняет все, в том числе, почему эти константы множителя существуют до значений R, G и B.
Изменить: Здесь также есть объяснение одному из ответов (0,299 * R + 0,587 * G + 0,114 * B).
источник
Чтобы определить яркость цвета с помощью R, я конвертирую системный цвет RGB в системный цвет HSV.
В моем сценарии я использую системный код HEX и раньше по другой причине, но вы также можете начать с системного кода RGB с помощью
rgb2hsv {grDevices}
. Документация здесь .Вот эта часть моего кода:
источник
Для ясности формулы, использующие квадратный корень, должны быть
sqrt(coefficient * (colour_value^2))
не
sqrt((coefficient * colour_value))^2
Доказательством этого является преобразование триады R = G = B в шкалу серого R. Это будет верно только в том случае, если вы возводите в квадрат значение цвета, а не коэффициент времени, равный временному значению. См Девять оттенков серого
источник