web-dev-qa-db-ja.com

可視スペクトルのRGB値

可視スペクトル範囲の各波長を同等のRGB値にマッピングするアルゴリズムまたは機能が必要です。 RGBシステムと光の波長の間に構造的な関係はありますか?この画像のように: alt text
(ソース: kms at www1.appstate.ed

これが関係ない場合はご容赦ください:-]

39
sorush-r

周波数と色相として知られているものの間には関係がありますが、知覚、色域の監視、およびキャリブレーションの複雑な理由により、高価なラボ機器の外で達成できる最善の方法は大まかな近似です。

数学については http://en.wikipedia.org/wiki/HSL_and_HSV を参照してください。Hue⇔Frequencyマッピングの最良の推測を考え出す必要があることに注意してください。私はこの経験的なマッピングが線形以外のものになると期待しています。

8
msw

最近、私のスペクトル色は非線形でシフトされたデータに基づいているため、適切に機能しないことがわかりました。それで、私はほとんど研究とデータ編集をしませんでした、そして、そこにあるほとんどのスペクトル画像が間違っていることがわかりました。また、色の範囲が互いに一致しないため、この時点から線形化された実際の分光データのみを使用しました like this

ここに私の修正された出力があります:

spectral colors

  • 最初のスペクトルは、私が見つけた最高のレンダリングされたスペクトルですが、それでも本物から外れています
  • 2番目は地球から取られた太陽の線形化されたスペクトルです
  • 最後は私の現在のカラー出力です

以下は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); }
    }
//--------------------------------------------------------------------------

どこ

  • ll = < 400.0 , 700.0 >と同様に使用可能な値[nm]の波長です
  • r,g,bは範囲< 0.0 , 1.0 >の色成分を返します
37
Spektre

部分的な「可視波長の近似RGB値」

クレジット:Dan Bruton-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
10
Andrey

私は答えが実際の質問の問題に対処できないと思います。

RGB値は通常、標準的な人間の観察者機能、照明、および〜360〜830の範囲の各波長でのサンプルの相対出力の組み合わせであるXYZ色空間から導出されます。

ここで何を達成しようとしているのかはわかりませんが、10 nmなどのスペクトルの各離散帯域が完全に飽和しているサンプルの比較的「正確な」RGB値を計算することは可能です。変換は、このスペクトル->XYZ->RGBのようになります。数学については、Bruce Lindbloomのサイトをご覧ください。 XYZから、L*a*b*などのhuechroma、またはcolorimetricの値も簡単に計算できます。

5
Mussi

完全一致が必要な場合は、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
Patapom

これは、ほとんどの カラープロファイル が扱うものです。基本的に、特定のデバイス(スキャナー、カメラ、モニター、プリンターなど)について、カラープロファイルは、特定の入力セットによって生成される実際の光の色を示します。

また、ほとんどの実際のデバイスでは、少数の離散波長の光のみを処理し、その波長を直接生成することで中間色が生成されることに注意してくださいnotさまざまな量の利用可能な2つの隣接する波長を混合します。私たちが同じように色を知覚することを考えると、それは実際には問題ではありませんが、気にする理由によっては、とにかく知る価値があるかもしれません。

カラープロファイル(または同等の情報)がなければ、RGB値を色にマッピングするために必要な情報が不足しています。純粋な赤のRGB値は、通常、デバイスが生成/検知できる最も赤い色(および同様に、純粋な青が最も青い色)にマッピングされますが、「最も赤く」または「最も青い」色は(広く)変化する可能性がありますデバイスに基づきます。

4
Jerry Coffin

波長をRGBカラーに変換するには

まず、 CIE 1964 Supplementary Standard Colorimetric Observer chartarchiveを参照します

https://imgur.com/a/JDatZNm

目的の波長のCIEカラーマッチング関数値を検索します。

たとえば、455 nmの光の色を取得したい:

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

2つの異なる色空間を使用して、455 nmの光を指定します。

  • XYZ:(0.342957、0.106256、1.900700)
  • xyz:(0.145945、0.045217、0.808838)

3番目の色空間を追加することもできます:xyY

x = x = 0.145945
y = y = 0.045217
Y = y = 0.045217

これで、455 nmの光が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は、絶対物理学を使用して色を記述する絶対色空間です。

一方、人々が使用するすべての実用的な色空間:

  • ラボ
  • マブラヴ
  • HSV
  • HSL
  • RGB

いくつかのホワイトポイントに依存します。色は、その白色点に相対的であると説明されます。

例えば、

  • RGB白(255,255,255)は、「白」を意味します
  • ラボホワイト(100、0、0)は、「ホワイト」を意味します
  • LCH白(100、0、309)は、「白」を意味します
  • HSL白(240、0、100)は、「白」を意味します
  • HSV白(240、0、100)は、「白」を意味します

しかし、白のような色はありません。白をどう定義しますか?日光の色?

  • 何時に?
  • どれくらいの雲量で?
  • どの緯度で?
  • 地球上で?

一部の人々は、白を意味するために(恐ろしくオレンジ色の)白熱電球の白を使用します。蛍光灯の色を使用する人もいます。白の絶対的な物理的定義はありません-白は私たちの脳の中にあります。

だから私たちは白を選ぶ必要があります

私たちは白をpickしなければなりません。 (本当にyouは白を選ぶ必要があります。)たくさんの白を選択できます:

私はあなたのために白を選びます。 sRGBが使用するものと同じ白:

  • D65-北ヨーロッパの晴れた夏の日の昼光照明

D65(6504Kに近い色ですが、地球の大気のせいではありません)の色は次のとおりです。

  • XYZ_D65:(0.95047、1.00000、1.08883)

これにより、XYZLab(またはLuv)に変換できます。これは、理論上のすべての色を同等に表現できる色空間です。これで、445 nmの単色発光の4番目の色空間表現ができました。

  • XYZ:(0.342957、0.106256、1.900700)
  • xyz:(0.145945、0.045217、0.808838)
  • xyY:(0.145945、0.045217、0.045217)
  • Lab:(38.94259、119.14058、-146.08508)(d65を想定)

しかし、あなたはRGBが欲しい

Lab(およびLuv)は、some白色点に相対的な色空間です。任意のホワイトポイントを選択するように強制された場合でも、可能なすべての色を表すことができます。

RGBはそうではありません。 RGBの場合:

  • ある白色点に対する色だけでなく
  • ただし、3つの原色(赤、緑、青)にも関連しています

(255、0、0)のRGBカラーを指定した場合、「ちょうど赤」が欲しいと言っていることになります。しかし、赤の定義はありません。 「赤」、「緑」、「青」などはありません。虹は連続的であり、次のような矢印は付いていません。

これは赤です

繰り返しますが、これは、pick3原色を選択する必要があることを意味します。 「赤」、「緑」、「青」が何であるかを言うには、3つの原色を選択する必要があります。繰り返しますが、赤、緑、青のさまざまな定義から選択できます。

  • CIE 1931
  • ROMM RGB
  • Adobe Wide Gamut RGB
  • DCI-P3
  • NTSC(1953)
  • Apple RGB
  • sRGB
  • 日本語NTSC
  • PAL/SECAM
  • Adobe RGB 98
  • scRGB

あなたのために選びます。 これらの3色: を選択します

  • :xyY =(0.6400、0.3300、0.2126)
  • :xyY =(0.3000、0.6000、0.7152)
  • 青:xyY =(0.1500、0.0600、0.0722)

これらは、1996年に国際委員会によって選ばれた予備選挙でもありました。

彼らは誰もが使うべきだと言う標準を作成しました:

  • ホワイトポイント: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値にはいくつかの問題があります。

  • モニターはnegativegreen(-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)

これで、波長455 nmの光に最も近いsRGBが得られました。

enter image description here

3
Ian Boyd

Patapomはほぼ正しい:各波長についてCIE XYZ値を計算し、標準の式を使用して(たとえば)sRGBに変換します(運がよければ、この変換に使用できるコードが見つかるでしょう)。そのため、重要なステップはXYZ値を取得することです。幸いなことに、単一波長の光の場合、これは簡単です。XYZカラーマッチング関数は、特定の波長のXYZ値をリストした単なるテーブルです。調べてみてください。より複雑なスペクトル(おそらく黒体)の光がある場合は、XYZ応答と光の各波長の量を平均する必要があります。

1
Anne

VBAコードは、Dan Bruton([email protected])による「可視波長のRGB値」から得られます。オリジナルのFortranコードへのリンク: http://www.physics.sfasu.edu/astro/color/spectra.html スペクトルプログラム: 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
0
BzKnt