RGB values of visible spectrum

后端 未结 11 1609
难免孤独
难免孤独 2020-11-22 10:37

I need an algorithm or function to map each wavelength of visible range of spectrum to its equivalent RGB values. Is there any structural relation between the RGB System an

相关标签:
11条回答
  • VBA code is derived from Approximate "RGB values for Visible Wavelengths" by Dan Bruton (astro@tamu.edu). Link to his original Fortran code: http://www.physics.sfasu.edu/astro/color/spectra.html Spectra program: 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 讨论(0)
  • 2020-11-22 11:15

    I think the answers fail to address a problem with the actual question.

    RGB values are generally derived from the XYZ color space which is the combination of a standard human observer function, an illuminate and the relative power of the sample at each wavelength over the range of ~360-830.

    I'm not sure of what you are trying to achieve here but it would be possible to calculate a relatively "accurate" RGB value for a sample where each discrete band of the spectrum @ say 10nm was fully saturated. The transform looks like this Spectrum ->XYZ->RGB. Check out Bruce Lindbloom's site for the math. From the XYZ you can also easily calculate hue, chroma or colorimetric values such as L*a*b*.

    0 讨论(0)
  • 2020-11-22 11:15

    This is most of what color profiles deal with. Basically, for a given device (scanner, camera, monitor, printer, etc.) a color profile tells what actual colors of light will be produced by a specific set of inputs.

    Also note that for most real devices, you only deal with a few discrete wavelengths of light, and intermediate colors are produced not by producing that wavelength directly, but by mixing varying amounts of the two neighboring wavelengths that are available. Given that we perceive color in the same way, that's not really a problem, but depending on why you care, it may be worth knowing anyway.

    Without a color profile (or equivalent information) you lack the information necessary to map RGB value to colors. An RGB value of pure red will normally map to the reddest color that device is capable of producing/sensing (and likewise, pure blue to the bluest color, etc.) -- but that reddest or bluest can and will vary (widely) based on the device (and in some cases not just the device itself either--e.g., switching inks in a printer can change the characteristics).

    0 讨论(0)
  • 2020-11-22 11:19

    If you want an exact match then the only solution is to perform a convolution of the x,y,z color matching functions with your spectral values so you finally get a (device-independent) XYZ color representation that you can later convert into (device-dependent) RGB.

    This is described here: http://www.cs.rit.edu/~ncs/color/t_spectr.html

    You can find the x,y,z color matching function for convolution here: http://cvrl.ioo.ucl.ac.uk/cmfs.htm

    0 讨论(0)
  • 2020-11-22 11:26

    Partial "Approximate RGB values for Visible Wavelengths"

    Credit: Dan Bruton - Color Science

    Original FORTRAN code @ (http://www.physics.sfasu.edu/astro/color/spectra.html)

    Will return smooth(continuous) spectrum, heavy on the red side.

    w - wavelength, R, G and B - color components

    Ignoring gamma and intensity simple leaves:

    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
    
    0 讨论(0)
提交回复
热议问题