Necesito un algoritmo o función para mapear cada longitud de onda del rango visible del espectro a sus valores RGB equivalentes. ¿Existe alguna relación estructural entre el sistema RGB y la longitud de onda de una luz? como esta imagen: alt text http://www1.appstate.edu/~kms/classes/psy3203/Color/spectrum5.gif lo siento si esto era irrelevante: -]Valores RGB del espectro visible
Respuesta
Existe una relación entre la frecuencia y lo que se conoce como Hue, pero para complicada Por razones de percepción, la gama de monitores y la calibración, lo mejor que puede lograr fuera del costoso equipo de laboratorio es una aproximación aproximada.
Consulte http://en.wikipedia.org/wiki/HSL_and_HSV para las matemáticas, y tenga en cuenta que tendrá que llegar a su mejor estimación para el mapeo de Hue ⇔ Frequency. Espero que este mapeo empírico sea cualquier cosa menos lineal.
toda la matemática para Matiz -> La asignación de RGB es aproximada (lineal). Hue -> freq se puede mapear como mapas de longitud de onda de 390 a 750 nm a hue [0, 1]. freq = c/wavelength – Andrey
Note mi uso de la palabra "empírico" y luego pruébelo usted mismo mientras recuerda que nuestra percepción es tricromática y distintivamente no lineal y que los monitores son un tricromático diferente y también extremadamente no lineales. Existe una industria de calibración completa construida alrededor de estos efectos. – msw
"valores RGB aproximados de longitudes de onda visibles" parcial
Crédito: Dan Bruton - tecnología de color
original FORTRAN @ (http://www.physics.sfasu.edu/astro/color/spectra.html)
Devolverá el espectro suave (continuo), pesado en el lado rojo.
W - longitud de onda, R, G y B - de color componentes
Haciendo caso omiso de gamma y de intensidad hojas simples:
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
Esto daría 6 valores RGB discretos. ¿Algo para los colores intermedios? – FrustratedWithFormsDesigner
@FrustratedWithFormsDesigner no, es degradado. w está dentro de las expresiones, entonces son f (w) – Andrey
¿No son los bits 'R = - (w - 440.)/(440. - 350.)' los valores intermedios? R, G, B son puntos flotantes aquí, no enteros. – Rup
Esto es más de lo que se relaciona con color profiles. Básicamente, para un dispositivo determinado (escáner, cámara, monitor, impresora, etc.), un perfil de color indica qué colores reales de luz generará un conjunto específico de entradas.
También tenga en cuenta que para la mayoría de los dispositivos reales, que sólo se ocupan de unas pocas longitudes de onda discretas de luz y colores intermedios se producen no mediante la producción de esa longitud de onda directamente, sino mediante la mezcla de cantidades variables de las dos longitudes de onda vecinos que están disponibles . Dado que percibimos el color de la misma manera, eso no es realmente un problema, pero dependiendo de por qué te importa, puede valer la pena saberlo de todos modos.
Sin un perfil de color (o información equivalente), no tiene la información necesaria para asignar el valor RGB a los colores. Un valor RGB de rojo puro normalmente se asignará al color más rojo que el dispositivo sea capaz de producir/detectar (y del mismo modo, azul puro al color azul), pero que "rojo" o "azul" puede variar (ampliamente) basado en el dispositivo.
Creo que las respuestas no solucionan un problema con la pregunta real.
Los valores RGB se derivan generalmente del espacio de color XYZ que es la combinación de una función de observador humano estándar, una iluminación y la potencia relativa de la muestra en cada longitud de onda en el rango de ~ 360-830.
No estoy seguro de lo que está tratando de lograr aquí, pero sería posible calcular un valor RGB relativamente "preciso" para una muestra donde cada banda discreta del espectro @ digamos 10nm estaba completamente saturada. La transformación se parece a este Spectrum ->XYZ->RGB
. Visite el sitio de Bruce Lindbloom para las matemáticas. Desde el XYZ también puede calcular fácilmente hue
, chroma
o colorimetric
valores como L*a*b*
.
Si desea una coincidencia exacta, entonces la única solución es realizar una convolución de las funciones de coincidencia de color x, y, z con sus valores espectrales para que finalmente obtenga una representación en color XYZ (independiente del dispositivo) que pueda convertir en RGB (dependiente del dispositivo).
Esto se describe aquí: http://www.cs.rit.edu/~ncs/color/t_spectr.html
Usted puede encontrar la x, y, la función z coincidencia de color de convolución aquí: http://cvrl.ioo.ucl.ac.uk/cmfs.htm
Patapom lo tiene casi justo: para cada longitud de onda se calcula el CIE Valores XYZ, luego conviértalos a (digamos) sRGB usando fórmulas estándar (si tienes suerte, encontrarás el código que puedes usar para hacer esta conversión). Entonces, el paso clave es obtener los valores XYZ. Afortunadamente, para la luz de longitud de onda única esto es fácil: las funciones de coincidencia de color XYZ son simplemente tablas que enumeran los valores XYZ para una longitud de onda dada. Así que solo búscalo. Si tuvieras luz con un espectro más complicado, tal vez un cuerpo negro, entonces tendrías que promediar las respuestas XYZ por la cantidad de cada longitud de onda en la luz.
Recientemente descubrí que mis colores espectrales no funcionan correctamente porque se basaban en datos no lineales y desplazados. Así que investigué poco y recopilé datos y descubrí que la mayoría de las imágenes de espectro que existen son incorrectas. Además, las gamas de colores no coinciden entre sí, por lo que utilizar desde este punto de datos de espectroscopia real sólo linealizadas like this
Aquí está la salida rectificada mío:
- la el primer espectro es el mejor espectro procesado que encontré, pero aún está lejos del real
- el segundo es espectro linealizado de nuestro Sol tomado de la Tierra
- el último es mi corriente de salida de color
A continuación se presentan los gráficos RGB:
Ésta es la fusión de ambos gráficos:
Ahora el código:
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); }
}
//--------------------------------------------------------------------------
Dónde
l
es la longitud de onda en [nm] valueas utilizables sonl = < 400.0 , 700.0 >
r,g,b
están regresando componentes de color en el rango de< 0.0 , 1.0 >
@tivus no, no es un error tipográfico, debería ser 5.82, ya que está en el código. de lo contrario, el extremo verde de la pendiente se desbordará a valores negativos alrededor de 639 nm creando picos de color no válidos. – Spektre
¿No podría simplificarse este código si usa funciones para aproximar las curvas de cada banda de color? Una función que viene a la mente que podría ser buena es 1/sqrt (x^2 + 1), con cada banda obteniendo los cambios apropiados. – Broseph
@Broseph cambiar el polinomio simple de orden bajo con 1/sqrt no suena bien para mí (velocidad, precisión) si quiere velocidad o simplicidad de código, use tabla + interpolación. – Spektre
código VBA se deriva de "valores RGB para longitudes de onda visibles" aproximados por Dan Bruton ([email protected]). enlace a su código original de Fortran: http://www.physics.sfasu.edu/astro/color/spectra.html programa 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
- 1. Ordenar System.Media.Colors según la posición en el espectro visible
- 2. Generación de paletas de colores de espectro
- 3. Convertir valores RGB a Entero
- 4. Convertir valores RGB al nombre de color
- 5. rgb valores a 0 a 1 escala
- 6. RGB Int a RGB - Python
- 7. ¿Cómo remuestrear/rebinar un espectro?
- 8. Cómo normalizar el valor RGB con los valores RGB de referencia
- 9. Extraer valores RGB de un marco AVFrame (FFMPEG) en C++
- 10. ¿Cómo se realiza la interpolación bilineal en los valores RGB?
- 11. ¿Cómo inicializar UIColor de los valores RGB correctamente?
- 12. Algoritmo para conmutar entre RGB y HSB valores de color
- 13. Expresión regular de Javascript para valores de rgb
- 14. ¿Cómo ingreso valores RGB en el Interface Builder?
- 15. UILabel parte visible del texto
- 16. El color RGB o html del papel
- 17. Fórmula para determinar el brillo del color RGB
- 18. ¿Hay alguna buena razón para usar valores hexadecimales sobre los valores de color RGB en CSS?
- 19. RGB a HSB Algoritmo
- 20. puedo apagar SASS RGB -> Nombre del color
- 21. Detección de ritmo a través del análisis del espectro de audio
- 22. iOS SDK Interfaz Slider RGB del generador que produce un color diferente a UIColor con RGB
- 23. Conversión de RGB a monocromo
- 24. RGB a HSV en PHP
- 25. Java; Obtener inserciones antes del marco es visible
- 26. HBRUSH al valor RGB
- 27. ¿Cómo pintar un buen mapa de colores RGB?
- 28. Clojure/Java: bibliotecas de Java para el análisis de espectro del sonido?
- 29. Detección de velocidad de bits de MP3 a través del análisis de espectro de frecuencia
- 30. PHP - obtiene el nombre del color de RGB
esta pregunta, puede dar una idea. http://stackoverflow.com/questions/1472514/convert-light-frequency-to-rgb – GWW
Los colores espectrales y los colores RGB tienen una relación inf-a-1, por lo que no existe una relación única. Un color RGB se asigna a infinitos colores espectrales. –
mira aquí: http://stackoverflow.com/a/22149027/2521214 y sí, esto solo se puede usar para la longitud de onda -> conversión RGB, no al revés ... (la longitud de onda tiene color pero el color no es la longitud de onda ...) – Spektre