RGB значения видимого спектра - PullRequest
38 голосов
/ 04 августа 2010

Мне нужен алгоритм или функция для сопоставления каждой длины волны видимого диапазона спектра с ее эквивалентными значениями RGB. Есть ли структурная связь между системой RGB и длиной волны света? как это изображение: альтернативный текст http://www1.appstate.edu/~kms/classes/psy3203/Color/spectrum5.gif извините, если это не имеет значения: -]

Ответы [ 9 ]

35 голосов
/ 27 марта 2014

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

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

spectral colors

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

Ниже приведены графики RGB:

Это слияние обоих графиков:

graph merge

Теперь код:

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 >
10 голосов
/ 04 августа 2010

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

Кредит: Дэн Брутон - Color Science

Оригинальный код ФОРТРАНА @ (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
8 голосов
/ 04 августа 2010

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

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

5 голосов
/ 30 ноября 2012

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

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

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

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

4 голосов
/ 04 августа 2010

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

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

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

3 голосов
/ 01 августа 2018

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

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

https://imgur.com/a/JDatZNm

и найдите значения функции соответствия цветов CIE для нужной длины волны.

Например, я хочу получить цвет света 455 нм:

enter image description here

Для нашей желаемой длины волны:

| 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

LabLuv) были относительными цветовыми пространствамидо немного белая точка.Даже если вы были вынуждены выбрать произвольную белую точку, вы все равно можете представить все возможные цвета.

RGB не такой.С RGB:

  • не только цвет относительно некоторой белой точки
  • , но также и относительно трех основных цветов: красный, зеленый, синий

Если вы указываете цвет RGB (255, 0, 0), вы говорите, что хотите «просто красный».Но нет определения красного.Нет такой вещи как «красный», «зеленый» или «синий».Радуга непрерывна и не идет со стрелкой, говорящей:

Это красный

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

  • CIE 1931
  • ROMM RGB
  • Adobe Wide Gamut RGB
  • DCI-P3
  • 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.

Окончательный толчок

Теперь, когда мы выбрали

  • white-point
  • три основных цвета

теперь мы можем преобразовать ваш цвет 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 нм света:

enter image description here

1 голос
/ 10 мая 2013

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

0 голосов
/ 15 октября 2015

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