Значения RGB видимого спектра

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

Вопрос:

Мне нужен алгоритм или функция для сопоставления каждой длины волны видимого диапазона спектра с его эквивалентными значениями RGB.
Есть ли структурная связь между системой RGB и длиной волны света?
как это изображение:

(источник: км на www1.appstate.edu)

извините, если это не имеет значения: -]

Лучший ответ:

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

См. http://en.wikipedia.org/wiki/HSL_and_HSV для математики, и обратите внимание, что вам придётся придумать ваше лучшее предположение для Hue ⇔ Отображение частоты, Я ожидаю, что это эмпирическое отображение будет чем угодно, но линейным.

Ответ №1Недавно я узнал, что мои спектральные цвета не работают должным образом, потому что они основаны на нелинейных и сдвинутых данных. Поэтому я сделал небольшое исследование и сбор данных и выяснил, что большинство изображений спектра там неверны. Кроме того, диапазоны цветов не совпадают друг с другом, поэтому я использовал с этой точки только данные линеаризованной реальной спектроскопии как это

Вот выпрямленный вывод моей:

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

Ниже приведены графики 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 – длина волны в [nm] полезной величине a l = < 400.0 , 700.0 >
  • r,g,b возвращают цветовые компоненты в диапазоне < 0.0 , 1.0 >

Ответ №2

Частичное “Приблизительные значения RGB для видимых длин волн”

Предоставлено: Дэн Брутон – Color Science

Оригинальный код 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 Ответ №3

Я думаю, что ответы не могут решить проблему с фактическим вопросом.

Значения RGB обычно выводятся из цветового пространства XYZ, которое представляет собой комбинацию стандартной функции человеческого наблюдателя, освещенности и относительной мощности образца на каждой длине волны в диапазоне ~ 360-830.

Я не уверен, чего вы пытаетесь достичь здесь, но можно было бы вычислить относительно “точное” значение RGB для образца, где каждая дискретная полоса спектра @говорит, что 10 нм полностью насыщена. Преобразование выглядит как этот Spectrum ->XYZ->RGB. Посмотрите на сайт Брюса Линдблома для математики. Из XYZ вы также можете легко вычислить значения hue, chroma или colorimetric, такие как L*a*b*.

Ответ №4

Если вы хотите точное совпадение, единственным решением является выполнение свертки функций согласования цвета 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

Ответ №5

Это больше всего связано с цветными профилями. В основном, для данного устройства (сканера, камеры, монитора, принтера и т.д.) Цветовой профиль сообщает, какие фактические цвета света будут производиться с помощью определенного набора входов.

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

Без цветового профиля (или эквивалентной информации) вам не хватает информации, необходимой для сопоставления значения RGB с цветами. Значение RGB чистого красного цвета обычно будет отображаться на самый красный цвет, который устройство может производить/воспринимать (а также чисто синим до самого синего цвета), но что “красноватый” или “голубой” может и будет меняться (широко) на основе устройства.

Ответ №6Содержание

  1. Чтобы преобразовать длину волны в цвет RGB
  2. Как конвертировать XYZ в RGB?
  3. Таким образом, мы должны выбрать белый
  4. Но вы хотите RGB
  5. Финальный толчок

Чтобы преобразовать длину волны в цвет RGB

Сначала вы обратитесь к диаграмме Дополнительного стандартного колориметрического наблюдателя CIE 1964 (архив)

https://imgur.com/a/JDatZNm

и найдите значения функции соответствия цвета 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,145945, 0,045217, 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,145945, 0,045217, 0,808838)
  • xyY: (0,145945, 0,045217, 0,045217)

Итак, мы преобразовали длину волны чистого монохроматического излучаемого света в цвет XYZ. Теперь мы хотим преобразовать это в RGB.

Как конвертировать XYZ в RGB?

XYZ, xyz и xyY – это абсолютные цветовые пространства, которые описывают цвета с использованием абсолютной физики.

Между тем, каждое практическое цветовое пространство, которое используют люди:

  • Lab
  • Luv
  • HSV
  • HSL
  • RGB

зависит какая-то белая точка. Затем цвета описываются как относящиеся к этой белой точке.

Например,

  • RGB белый (255,255,255) означает “белый”
  • Lab white (100, 0, 0) означает “белый”
  • LCH белый (100, 0, 309) означает “белый”
  • HSL белый (240, 0, 100) означает “белый”
  • HSV белый (240, 0, 100) означает “белый”

Но нет такого цвета, как белый. Как вы определяете белый? Цвет солнечного света?

  • в какое время суток?
  • сколько облачного покрова?
  • на какой широте?
  • на Земле?

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

Таким образом, мы должны выбрать белый

Мы должны выбрать белый. (На самом деле вы должны выбрать белый.) И есть из чего выбрать:

Я выберу белый для вас. Тот же самый белый, который использует sRGB:

  • D65 – дневное освещение ясного летнего дня в северной Европе

D65 (цвет которого близок к 6504K, но не совсем из-за атмосферы Земли) имеет цвет:

  • XYZ_D65: (0,95047, 1,00000, 1,08883)

При этом вы можете преобразовать свой XYZ в Lab (или Luv) – цветовое пространство, в равной степени способное выразить все теоретические цвета. И теперь у нас есть 4-е представление цветового пространства нашего 445 нм монохроматического излучения света:

  • XYZ: (0,342957, 0,106256, 1,900700)
  • xyz: (0,145945, 0,045217, 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), вы говорите, что хотите “просто красный”. Но нет определения красного. Нет такой вещи как “красный”, “зеленый” или “синий”. Радуга непрерывна и не имеет стрелки, гласящей:

Это красный

И снова это означает, что мы должны выбрать три выбрать три основных цвета. Вы должны выбрать три основных цвета, чтобы сказать, что такое “красный”, “зеленый” и “синий”. И снова у вас есть много разных определений красного, зеленого и синего цветов:

  • 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,145945, 0,045217, 0,808838)
  • xyY: (0,145945, 0,045217, 0,045217)
  • Лаборатория: (38,94259, 119,14058, -146.08508) (d65)
  • RGB: (1, 0, 255) (sRGB)

И теперь мы имеем ближайшее приближение sRGB длины волны 455 нм света:

Ответ №7

Patapom имеет почти право: для каждой длины волны вы вычисляете значения CIE XYZ, а затем конвертируете их в (скажем) sRGB с использованием стандартных формул (если вам повезет, вы найдете код, который вы можете использовать для этого преобразования), Таким образом, ключевым шагом является получение значений XYZ. К счастью, для одноволнового света это легко: функции согласования цвета XYZ – это просто таблицы, в которых перечислены значения XYZ для заданной длины волны. Так что просто посмотри. Если бы у вас был свет с более сложным спектром, может быть, с черным телом, тогда вам пришлось бы усреднять время ответа XYZ на количество каждой длины волны в свете.

Ответ №8

Код VBA получен из приблизительных “значений RGB для видимых длин волн” Дэн Брутон (astro@tamu.edu).
Ссылка на его исходный код Fortran:
Программа 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 Ответ №9

Работоспособный пример, основанный на популярном ответе:

function spectrogram() { var svgns = ‘http://www.w3.org/2000/svg’; var svg = document.createElementNS(svgns, ‘svg’); var defs = document.createElementNS(svgns, ‘defs’); var gradient = document.createElementNS(svgns, ‘linearGradient’); var rect = document.createElementNS(svgns, ‘rect’); var stops = spectral_gradient( 400, 700, 3 ); for( var i = 0, length = stops.length; i < length; i++ ) { var stop = document.createElementNS(svgns, ‘stop’); stop.setAttribute(‘offset’, stops[i].offset); stop.setAttribute(‘stop-color’, stops[i].color); gradient.appendChild(stop); } // Apply the <lineargradient> to <defs> gradient.id = ‘Gradient’; gradient.setAttribute(‘x1’, ‘0’); gradient.setAttribute(‘x2’, ‘1’); gradient.setAttribute(‘y1’, ‘0’); gradient.setAttribute(‘y2’, ‘0’); defs.appendChild(gradient); // Setup the <rect> element. rect.setAttribute(‘fill’, ‘url(#Gradient)’); rect.setAttribute(‘width’, ‘100%’); rect.setAttribute(‘height’, ‘100%’); // Assign an id, classname, width and height svg.setAttribute(‘width’, ‘100%’); svg.setAttribute(‘height’, ‘100%’) svg.setAttribute(‘version’, ‘1.1’); svg.setAttribute(‘xmlns’, svgns); // Add the <defs> and <rect> elements to <svg> svg.appendChild(defs); svg.appendChild(rect); // Add the <svg> element to <body> document.body.appendChild(svg); } function spectral_gradient( wl1, wl2, steps ) { var stops = []; var delta = Math.abs( wl2 — wl1 ); for( var wl = wl1; wl <= wl2; wl += steps ) { var offset = Math.round( (1 — Math.abs( wl2 — wl ) / delta) * 100 ); stops.push({ «color»: wavelength2hex( wl ), «offset»: offset + «%» }); } return stops; } function wavelength2hex( l ) { var wl = wavelength2rgb( l ); var rgb = { «r»: Math.round( wl.r * 255 ), «g»: Math.round( wl.g * 255 ), «b»: Math.round( wl.b * 255 ) }; return rgb2hex( rgb.r, rgb.g, rgb.b ); } function wavelength2rgb( l ) { var t; var r = 0.0; var g = 0.0; var 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); } return {«r»: r, «g»: g, «b»: b}; } function rgb2hex( r, g, b ) { return «#» + hex( r ) + hex( g ) + hex( b ); } function hex( v ) { return v.toString( 16 ).padStart( 2, «0» ); }<!DOCTYPE html> <html lang=»en»> <head> <meta charset=»utf-8″ /> <script src=»js/spectrum.js»></script> </head> <body onload=»spectrogram();»> </body> </html>

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