¿Cuál es la mejor manera de promediar dos colores que definen un degradado lineal?

StackOverflow https://stackoverflow.com/questions/649454

  •  19-08-2019
  •  | 
  •  

Pregunta

Si tengo dos colores definidos por sus valores RGB, ¿puedo promediar los valores Rojo, Verde y Azul y luego combinarlos para definir un tercer color que se vea como un promedio visual de los dos?

es decir, NewColor = (R1 + R2) / 2, (G1 + G2) / 2, (B1 + B2) / 2

EDIT1: Gracias por todas las respuestas. Para mis necesidades actuales, solo estoy tratando con pares de colores que son tonos del mismo color, así que creo que promediarlos funcionará. Sin embargo, intentaré convertir a Lab Space para asegurarme de que la suposición sea cierta y que la técnica sea útil en el futuro.

EDIT2: Aquí están mis resultados FWIW. Color1 y Color2 son mis dos colores y las dos columnas del medio son el resultado de promediar en L a b espacio y promediar RGB respectivamente. En este caso, no hay mucha diferencia entre los dos colores y, por lo tanto, las diferencias en la salida de las técnicas de promedio son sutiles.

comparación visual de técnicas de promedio de color

¿Fue útil?

Solución

Eche un vistazo a las respuestas a esta pregunta .

Básicamente, desea convertir los colores en algo llamado Espacio de laboratorio , y encontrar su promedio en ese espacio.

El espacio de laboratorio es una forma de representar colores donde los puntos cercanos entre sí son aquellos que se parecen entre sí a los humanos.

Otros consejos

Varias respuestas sugieren la conversión al espacio de color Lab, que probablemente sea un buen enfoque para una manipulación de color más compleja.

Pero si simplemente necesita una forma rápida de tomar el promedio de dos colores, esto puede hacerse en el espacio RGB. Solo debe tener en cuenta una advertencia: debe ajustar al cuadrado los valores RGB antes de promediarlos y luego tomar la raíz del resultado. (Si simplemente toma el promedio, el resultado tenderá a ser demasiado oscuro).

Me gusta esto:

NewColor = sqrt((R1^2+R2^2)/2),sqrt((G1^2+G2^2)/2),sqrt((B1^2+B2^2)/2)

Aquí hay un gran video que explica por qué este método es eficiente: https://www.youtube.com/watch?v = LKnqECcg6Gw

El promedio en espacio de color HSL podría producir mejores resultados.

No sé si tomar un promedio simple de los componentes es el "mejor" desde un punto de vista perceptivo (eso suena como una pregunta para un psicólogo), pero aquí hay un par de ejemplos que usan el promedio de componentes simple.

texto alternativo ??

El rojo-mostaza-verde es feo pero la interpolación parece bastante razonable.

Sí Puedes promediar dos colores juntos de esa manera. Es el enfoque utilizado por OpenGL para mezclar colores juntos (por ejemplo, al crear mapas MIP para renderizar objetos distantes, o renderizar una textura transparente al 50%). Es rápido, simple y "suficientemente bueno" para muchas situaciones Sin embargo, no es completamente realista, y probablemente no se usaría en imágenes con calidad de fotografía.

Esto es difícil. Primero, un conjunto de valores RGB no define un color. Deben interpretarse a la luz de los colores primarios a los que se refieren (el espacio de color), como sRGB, Rec.709, Rec.2020, Adobe RGB (1998), etc.

Además, los valores RGB como los encontramos normalmente no son proporcionales a la luz lineal: están codificados " utilizando una función no lineal (gamma). Y a veces (principalmente en aplicaciones de video) el valor de "negro" no es cero, pero está desplazado de cero, generalmente 16 para valores de 8 bits. Y "blanco" no es 255 sino 235. sRGB y Rec.709 comparten primarios RGB, pero sus funciones gamma son diferentes.

La conversión del espacio de color comienza con la eliminación de cualquier desplazamiento de negro para que el negro sea cero. Si la función gamma tiene un punto de interrupción (como sRGB y Rec.709), deberá escalar cuidadosamente los valores RGB para que "blanco". es 1.0.

Entonces, "decodificar" la gamma haciendo el inverso de la función gamma original. (Una respuesta sugirió cuadrar los valores, que es una aproximación de la decodificación gamma). Ahora tiene valores RGB de luz lineal en algún espacio de color. En este punto, puede convertir ese espacio de color en espacio de laboratorio. La mayoría de las conversiones de RGB a Lab pasan por un espacio de color intermedio llamado XYZ.

Los pasos como llamadas a funciones anidadas:

Lab = XYZ2Lab (RGB2XYZ (gamma_decode (offset_and_scale (RGB), gammaFunction ), espacio de color RGB ))

(El espacio de laboratorio se desarrolló en 1976 como un intento de crear una deformación perceptualmente uniforme del espacio estándar CIE XYZ. (Luv fue otro intento). La idea es que la distancia euclidiana (en línea recta) entre dos colores que eran notablemente diferentes (1 '' JND '') sería la misma distancia para dos colores. La distancia entre dos colores en Lab se conoce como 'delta-E'. La fórmula de distancia euclidiana delta simple ahora se llama dE76. Ver https://en.wikipedia.org/wiki/Color_difference )

En su caso, puede promediar los dos colores Lab para obtener un nuevo color Lab, luego invertir todas las conversiones para volver a RGB en el espacio de color elegido.

Esto te acercará, pero no está garantizado, simplemente porque " color " es una percepción humana, no una cantidad física, y ha sido notoriamente difícil de caracterizar de manera confiable. El laboratorio en realidad no funcionó tan bien para ser perceptivamente uniforme. Entonces, en lugar de arreglar Lab, propusieron una nueva función delta-E más compleja con otra urdimbre incorporada: DE94. Eso fue mejor, pero no perfecto, por lo que surgió otra propuesta en 2000: DE2000. También mejor pero no perfecto. Vea esa página Wiki arriba para más información.

Si DE2000 no es lo suficientemente bueno (¡o demasiado complejo!), puede echar un vistazo a una alternativa a Lab llamada ICtCp que se afirma que es más perceptualmente uniforme que Lab.

Creo que la respuesta de arntjw va en la dirección correcta y reconoce la capa subyacente logarítmica, como lo menciona Dan W. Sin embargo, la media geométrica adecuada no es sqrt ((C1 ^ 2 + C2 ^ 2) / 2) , pero sqrt (C1 * C2). Entonces el color promedio sería:

NewColor = sqrt(R1*R2),sqrt(G1*G2),sqrt(B1*B2)

Los colores resultantes están más cerca de lo que esperamos. Puede generalizar a más colores usando raíces de orden superior y ponderar cada color agregando un exponente a sus componentes.

En realidad, hay una manera mucho más simple.

  • Reduce la imagen a 1px por 1px.

    El color de 1px es el color promedio de lo que haya escalado

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top