Значения RGB видимого спектра
Мне нужен алгоритм или функция для сопоставления каждой длины волны видимого спектра спектра с эквивалентными значениями RGB. Существует ли структурная связь между системой RGB и длиной волны света? как это изображение: alt text http://sofru.miximages.com/algorithm/spectrum5.gif извините, если это не имело значения: -]
- Алгоритмы заполнения паводков
- Big-oh vs big-theta
- Уникальные случайные числа в целочисленном массиве на языке программирования C
- Отображение N-мерного значения в точку на кривой Гильберта
- Каковы различия между деревьями сегментов, деревьями интервалов, двоичными индексированными деревьями и деревьями диапазона?
- Какой хороший алгоритм определить, является ли вход идеальным квадратом?
- Храните самые большие 5000 номеров из streamа чисел.
- Плавный спектр для создания Мандельброта
Существует связь между частотой и тем, что известно как Hue, но по сложным причинам восприятия, гамма-диаграммы и калибровки лучше всего добиться за пределами дорогого лабораторного оборудования – это грубое приближение.
См. http://en.wikipedia.org/wiki/HSL_and_HSV для математики, и обратите внимание, что вам придётся придумать ваше лучшее предположение для Hue ⇔ Frequency mapping. Я ожидаю, что это эмпирическое отображение будет чем угодно, кроме линейного.
Недавно я узнал, что мои спектральные цвета работают неправильно, потому что они основаны на нелинейных и сдвинутых данных. Поэтому я сделал небольшое исследование и сбор данных и выяснил, что большинство изображений спектра там неверны. Кроме того, диапазоны цветов не совпадают друг с другом, поэтому я использовал с этой точки только данные линеаризованной реальной спектроскопии, подобные этому
Вот выпрямленный вывод шахты:
- первый спектр – лучший отображаемый спектр, который я нашел, но все еще далеко от реальной вещи
- второй линеаризован Спектр нашего Солнца, взятый с Земли
- последний – мой текущий цветной вывод
Ниже приведены графики RGB:
Это слияние обоих графиков:
Теперь код:
void spectral_color(double &r,double &g,double &b,double l) // RGB <0,1> <- lambda l <400,700> [nm] { double t; r=0.0; g=0.0; b=0.0; if ((l>=400.0)&&(l<410.0)) { t=(l-400.0)/(410.0-400.0); r= +(0.33*t)-(0.20*t*t); } else if ((l>=410.0)&&(l<475.0)) { t=(l-410.0)/(475.0-410.0); r=0.14 -(0.13*t*t); } else if ((l>=545.0)&&(l<595.0)) { t=(l-545.0)/(595.0-545.0); r= +(1.98*t)-( t*t); } else if ((l>=595.0)&&(l<650.0)) { t=(l-595.0)/(650.0-595.0); r=0.98+(0.06*t)-(0.40*t*t); } else if ((l>=650.0)&&(l<700.0)) { t=(l-650.0)/(700.0-650.0); r=0.65-(0.84*t)+(0.20*t*t); } if ((l>=415.0)&&(l<475.0)) { t=(l-415.0)/(475.0-415.0); g= +(0.80*t*t); } else if ((l>=475.0)&&(l<590.0)) { t=(l-475.0)/(590.0-475.0); g=0.8 +(0.76*t)-(0.80*t*t); } else if ((l>=585.0)&&(l<639.0)) { t=(l-585.0)/(639.0-585.0); g=0.84-(0.84*t) ; } if ((l>=400.0)&&(l<475.0)) { t=(l-400.0)/(475.0-400.0); b= +(2.20*t)-(1.50*t*t); } else if ((l>=475.0)&&(l<560.0)) { t=(l-475.0)/(560.0-475.0); b=0.7 -( t)+(0.30*t*t); } } //--------------------------------------------------------------------------
где
-
l
- длина волны в [нм] используемом значенииl = < 400.0 , 700.0 >
-
r,g,b
возвращают цветовые компоненты в диапазоне< 0.0 , 1.0 >
Частичные «Приблизительные значения RGB для видимых длин волн»
Кредит: Дэн Брутон – Цветная наука
Оригинальный код FORTRAN @ ( http://www.physics.sfasu.edu/astro/color/spectra.html )
Вернет гладкий (непрерывный) спектр, тяжелый на красной стороне.
w – длина волны, R, G и B – цветовые компоненты
Игнорирование гаммы и интенсивности простых листьев:
if w >= 380 and w < 440: R = -(w - 440.) / (440. - 380.) G = 0.0 B = 1.0 elif w >= 440 and w < 490: R = 0.0 G = (w - 440.) / (490. - 440.) B = 1.0 elif w >= 490 and w < 510: R = 0.0 G = 1.0 B = -(w - 510.) / (510. - 490.) elif w >= 510 and w < 580: R = (w - 510.) / (580. - 510.) G = 1.0 B = 0.0 elif w >= 580 and w < 645: R = 1.0 G = -(w - 645.) / (645. - 580.) B = 0.0 elif w >= 645 and w <= 780: R = 1.0 G = 0.0 B = 0.0 else: R = 0.0 G = 0.0 B = 0.0
Я думаю, что ответы не позволяют решить проблему с фактическим вопросом.
Значения RGB обычно выводятся из цветового пространства XYZ, которое представляет собой комбинацию стандартной функции человеческого наблюдателя, освещаемой и относительной мощности образца на каждой длине волны в диапазоне ~ 360-830.
Я не уверен в том, чего вы пытаетесь достичь здесь, но можно было бы вычислить относительно «точное» значение RGB для образца, где каждая дискретная полоса спектра @ говорит, что 10 нм полностью насыщена. Трансформат выглядит как этот Spectrum ->XYZ->RGB
. Посмотрите на сайт Брюса Линдброма для математики. Из XYZ вы также можете легко рассчитать chroma
, chroma
или colorimetric
значения, такие как L*a*b*
.
Если вы хотите получить точное соответствие, единственное решение – выполнить свертку функций согласования цвета x, y, z со своими спектральными значениями, чтобы вы, наконец, получили (не зависящее от устройства) представление цвета XYZ, которое впоследствии можно преобразовать (устройство -зависимый) RGB.
Это описано здесь: http://www.cs.rit.edu/~ncs/color/t_spectr.html
Вы можете найти функцию согласования цвета x, y, z для свертки здесь: http://cvrl.ioo.ucl.ac.uk/cmfs.htm
Это большая часть того, с чем справляются цветовые профили . В основном, для данного устройства (сканера, камеры, монитора, принтера и т. Д.) Цветовой профиль указывает, какие фактические цвета света будут производиться с помощью определенного набора входов.
Также обратите внимание, что для большинства реальных устройств вы имеете дело только с несколькими дискретными длинами волн света, а промежуточные цвета производятся не путем создания этой длины волны напрямую, а путем смешивания различных количеств двух соседних длин волн, которые доступны. Учитывая, что мы воспринимаем цвет таким же образом, это не проблема, но в зависимости от того, почему вы заботитесь, в любом случае, возможно, стоит знать.
Без цветового профиля (или эквивалентной информации) вам не хватает информации, необходимой для сопоставления значения RGB с цветами. Значение RGB чистого красного цвета обычно будет отображаться на самый красный цвет, который устройство может производить / воспринимать (а также чисто синим до самого синего цвета), но что «красноватый» или «голубой» может и будет меняться (широко) на основе устройства.
Patapom имеет почти правду: для каждой длины волны вы вычисляете значения CIE XYZ, а затем конвертируете их в (скажем) sRGB с использованием стандартных формул (если вам повезет, вы найдете код, который вы можете использовать для этого преобразования). Таким образом, ключевым шагом является получение значений XYZ. К счастью, для одноволнового света это легко: функции согласования цвета XYZ – это просто таблицы, в которых перечислены значения XYZ для заданной длины волны. Так что просто посмотри. Если бы у вас был свет с более сложным спектром, возможно, с черным телом, тогда вам пришлось бы усреднять время ответа XYZ на количество каждой длины волны в свете.
Код VBA получен из приблизительных «значений RGB для видимых длин волн» Дэн Брутон ([email protected]). Ссылка на его исходный код Fortran: http://www.physics.sfasu.edu/astro/color/spectra.html Программа Spectra: http://www.efg2.com/Lab/ScienceAndEngineering/Spectra.htm
Sub Wavelength_To_RGB() 'Purpose: Loop thru the wavelengths in the visible spectrum of light ' and output the RGB values and colors to a worksheet. ' Wavelength range: 380nm and 780nm Dim j As Long, CellRow As Long Dim R As Double, G As Double, B As Double Dim iR As Integer, iG As Integer, iB As Integer Dim WL As Double Dim Gamma As Double Dim SSS As Double Gamma = 0.8 CellRow = 1 For j = 380 To 780 WL = j Select Case WL Case 380 To 440 R = -(WL - 440#) / (440# - 380#) G = 0# B = 1# Case 440 To 490 R = 0# G = ((WL - 440#) / (490# - 440#)) B = 1# Case 490 To 510 R = 0# G = 1# B = (-(WL - 510#) / (510# - 490#)) Case 510 To 580 R = ((WL - 510#) / (580# - 510#)) G = 1# B = 0# Case 580 To 645 R = 1# G = (-(WL - 645#) / (645# - 580#)) B = 0# Case 645 To 780 R = 1# G = 0# B = 0# Case Else R = 0# G = 0# B = 0# End Select 'LET THE INTENSITY SSS FALL OFF NEAR THE VISION LIMITS If WL > 700 Then SSS = 0.3 + 0.7 * (780# - WL) / (780# - 700#) ElseIf WL < 420 Then SSS = 0.3 + 0.7 * (WL - 380#) / (420# - 380#) Else SSS = 1# End If 'GAMMA ADJUST R = (SSS * R) ^ Gamma G = (SSS * G) ^ Gamma B = (SSS * B) ^ Gamma 'Multiply by 255 R = R * 255 G = G * 255 B = B * 255 'Change RGB data type from Double to Integer. iR = CInt(R) iG = CInt(G) iB = CInt(B) 'Output to worksheet Cells(CellRow, 1).Interior.Color = RGB(iR, iG, iB) Cells(CellRow, 2) = WL Cells(CellRow, 3) = "(" & iR & "," & iG & "," & iB & ")" CellRow = CellRow + 1 Next j End Sub
Чтобы преобразовать длину волны в цвет RGB
Сначала вы проконсультируетесь с диаграммой дополнительного колориметрического наблюдателя CIE 1964 и посмотрите значения функции соответствия цвета CIE для требуемой длины волны.
Например, я хочу получить цвет 455 нм света:
Для желаемой длины волны:
| nm | CIE color matching functions | Chromacity coordinates | | nm | X | Y | Z | x | y | z | |-----|----------|----------|---------|---------|---------|---------| | 455 | 0.342957 | 0.106256 | 1.90070 | 0.14594 | 0.04522 | 0.80884 |
Примечание. Координаты четкости просто вычисляются из функций согласования цветов CIE:
x = X / (X+Y+Z) y = Y / (X+Y+Z) z = Z / (Z+Y+Z)
При условии:
X+Y+Z = 0.342257+0.106256+1.90070 = 2.349913
мы вычисляем:
x = 0.342257 / 2.349913 = 0.145945 y = 0.106256 / 2.349913 = 0.045217 z = 1.900700 / 2.349913 = 0.808838
У вас есть 455 нм свет, заданный с использованием двух разных цветовых пространств:
- XYZ: (0,342957, 0,106256, 1,900700)
- xyz: (0,1445945, 0,0455217, 0,808838)
Мы также можем добавить третье цветовое пространство: xyY
x = x = 0.145945 y = y = 0.045217 Y = y = 0.045217
Теперь у нас есть свет 455 нм, указанный в 3 разных цветовых пространствах:
- XYZ: (0,342957, 0,106256, 1,900700)
- xyz: (0,1445945, 0,0455217, 0,808838)
- xyY: (0.145945, 0.045217, 0.045217)
Таким образом, мы преобразовали длину волны чистого monoхроматического излучаемого света в цвет XYZ . Теперь мы хотим преобразовать это в RGB.
Как преобразовать XYZ в RGB?
XYZ , xyz и xyY – это абсолютные цветовые пространства, описывающие цвета с использованием абсолютной физики.
Между тем, все практические цветовые пространства, которые люди используют:
- лаборатория
- Luv
- HSV
- HSL
- RGB
зависит от некоторой точки. Затем цвета описываются как относящиеся к этой точке белого.
Например,
- RGB белый (255,255,255) означает «белый»
- Lab white (100, 0, 0) означает «белый»
- LCH white (100, 0, 309) означает «белый»
- HSL white (240, 0, 100) означает «белый»
- HSV white (240, 0, 100) означает «белый»
Но нет такого цвета, как белый. Как вы определяете белый? Цвет солнечного света?
- в какое время суток?
- с каким облачным покровом?
- на какой широте?
- на земле?
Некоторые люди используют белый цвет своих (ужасно оранжевых) ламп накаливания, чтобы они означали белый. Некоторые люди используют цвет своих флуоресцентных ламп. В нашем мозгу нет абсолютного физического определения бело-белого.
Поэтому нам нужно выбрать белый
Мы должны выбрать белый. (Действительно, вам нужно выбрать белый.) И есть много белых на выбор:
- Осветитель A : подобный вольфрамовой лампе
- Illuminant B & C : пытается подделать солнечный свет в полдень, поставив фильтры перед лампой накаливания
- Освещенность D50 : естественный дневной свет 5000K
- Освещенность D55 : естественный дневной свет 5500K
- Освещенность D65 : естественный дневной свет 6504K
- Освещенность D75 : естественный дневной свет 7500K
- Иллюминатор E : теоретический из всех цветов, одинаково присутствующих
- Освещенность F : флуоресцентные лампы
(FL8)
- Освещенность L : светодиодное освещение
Я возьму за тебя белый цвет. Тот же белый цвет, что и sRGB, использует:
- D65 – дневное освещение ясного летнего дня в северной Европе
D65 (который имеет цвет, близкий к 6504K, но не совсем из-за земной атмосферы), имеет цвет:
- XYZ_D65: (0,95047, 1,00000, 1.08883)
Благодаря этому вы можете преобразовать свой XYZ
в Lab
(или Luv
) – цветовое пространство, в равной степени способное выражать все теоретические цвета. И теперь у нас есть 4-х цветовое пространство нашего monoхроматического излучения света на 445 нм:
- XYZ: (0,342957, 0,106256, 1,900700)
- xyz: (0,1445945, 0,0455217, 0,808838)
- xyY: (0.145945, 0.045217, 0.045217)
- Лаборатория: (38.94259, 119.14058, -146.08508) (при условии, что d65)
Но вы хотите RGB
Lab
(и Luv
) – это цветовые пространства, которые относятся к некоторой точке белого. Несмотря на то, что вы были вынуждены выбрать произвольную точку белого, вы все равно можете представлять все возможные цвета.
RGB это не так. С RGB:
- не только цвет относительно некоторой точки белого цвета
- но также относится к трем основным цветам: красный, зеленый, синий
Если вы укажете цвет RGB (255, 0, 0), вы говорите, что хотите «просто красный». Но нет определения красного. Нет такой вещи, как «красный», «зеленый» или «синий». Радуга непрерывна и не имеет стрелки, говорящей:
Это красное
И снова это означает, что мы должны выбрать три выбора трех основных цветов. Вы должны выбрать три основных цвета, чтобы сказать, что такое «красный», «зеленый» и «синий». И снова у вас есть много разных определений Red, Green, Blue на выбор:
- CIE 1931
- ROMM RGB
- Adobe Wide Gamut RGB
- DCI-Р3
- NTSC (1953)
- Apple RGB
- SRGB
- Японский NTSC
- PAL / SECAM
- Adobe RGB 98
- scRGB
Я заберу тебя. Я выберу эти три цвета:
- Красный : xyY = (0,6400, 0,3300, 0,2126)
- Зеленый : xyY = (0,3000, 0,6000, 0,7152)
- Синий: xyY = (0,1500, 0,0600, 0,0722)
Это были также праймериз, выбранный международным комитетом в 1996 году.
Они создали стандарт, в котором говорится, что каждый должен использовать:
- Whitepoint : D65 дневной свет
- Красный : (0,6400, 0,3300, 0,2126)
- Зеленый : (0,3000, 0,6000, 0,7152)
- Синий: (0,1500, 0,0600, 0,0722)
И они назвали этот стандартный sRGB
.
Окончательный толчок
Теперь, когда мы выбрали
- бело-точка
- три праймериза
теперь мы можем преобразовать цвет XYZ в RGB:
- RGB = (1.47450, -178.21694, 345.59392)
К сожалению, есть некоторые проблемы с этим значением RGB:
- ваш монитор не может отображать отрицательный зеленый (-178.21694); это означает, что это цвет вне того, что может отображать ваш монитор.
- ваш монитор не может отображать больше синего, чем 255 (345.59392); монитор будет только синим, как синий – он не может получить никакого синего. Это означает, что это цвет вне того, что может отображать ваш монитор.
Поэтому мы должны округлить:
- XYZ: (0,342957, 0,106256, 1,900700)
- xyz: (0,1445945, 0,0455217, 0,808838)
- xyY: (0.145945, 0.045217, 0.045217)
- Лабораторная работа: (38,94259, 119,14058, -146,08508) (d65)
- RGB: (1, 0, 255) (sRGB)
И теперь мы имеем самое близкое приближение sRGB длины волны 455 нм света: