hexadecimal convertir color similarity color-space remap argb rgba

similarity - convertir - rgba white



Color similaridad/distancia en el espacio de color RGBA (5)

En primer lugar, un problema muy interesante :)
No tengo una solución completa (al menos no todavía), pero hay 2 casos extremos obvios que debemos considerar:
Cuando Δa==0 el problema es similar al espacio RGB
Cuando Δa==1 el problema solo se encuentra en el espacio alfa 1-tenue
Así que la fórmula (que es muy similar a la que mencionaste) que satisfaría eso es:
(Δr² + Δg² + Δb²) × (1-(1-Δa)²) + Δa² o (Δr² + Δg² + Δb²) × (1-Δa²) + Δa²

En cualquier caso, probablemente sería algo como (Δr² + Δg² + Δb²) × f(Δa) + Δa²

Si fuera tú, trataría de simularlo con varios pares de RGBA y varios colores de fondo para encontrar la mejor función f(Δa) . No es muy matemático, pero le dará una respuesta lo suficientemente cercana

¿Cómo calcular la similitud entre dos colores en el espacio de color RGBA? (donde el color de fondo es desconocido, por supuesto)

Necesito volver a asignar una imagen RGBA a una paleta de colores RGBA buscando la mejor entrada de paleta para cada píxel en la imagen *

En el espacio de color RGB, se puede suponer que el color más similar es el que tiene la distancia euclidiana más pequeña. Sin embargo, este enfoque no funciona en RGBA, por ejemplo, la distancia euclidiana de rgba(0,0,0,0) a rgba(0,0,0,50%) es menor que a rgba(100%,100%,100%,1%) , pero este último se ve mucho mejor.

Estoy usando el espacio de color RGBA premultiplicado:

r = r×a g = g×a b = b×a

y he probado esta fórmula ( edición: consulta la respuesta a continuación para obtener una mejor fórmula ):

Δr² + Δg² + Δb² + 3 × Δa²

pero no parece óptimo: en imágenes con gradientes semitransparentes encuentra colores incorrectos que causan discontinuidades / bordes afilados. Las proporciones lineales entre colores opacos y alfa parecen a pescado.

¿Cuál es la fórmula óptima?

*) Por simplicidad de esta pregunta, estoy ignorando la difusión de errores, los espacios de color gamma y sicovisuales.

Ligeramente relacionado: si desea encontrar el color más cercano en este espacio RGBA no euclidiano, los vp-trees son los mejores.


Finalmente, lo he encontrado! Después de pruebas y experimentación exhaustivas, mis conclusiones son:

  • La forma correcta es calcular la máxima diferencia posible entre los dos colores.
    Las fórmulas con cualquier tipo de diferencia promedio / típica estimada tenían espacio para las no linealidades.

  • No he podido encontrar la fórmula correcta que calcula la distancia sin mezclar los colores RGBA con los fondos.

  • No es necesario tener en cuenta todos los colores de fondo posibles. Se puede simplificar hasta combinar el máximo y el mínimo por separado para cada uno de los canales R / G / B:

    1. combine el canal en ambos colores con el canal = 0 como fondo, mida la diferencia al cuadrado
    2. mezcle el canal en ambos colores con channel = max como el fondo, mida la diferencia al cuadrado
    3. tomar más alto de los dos.

Afortunadamente, mezclar con "blanco" y "negro" es trivial cuando usas alfa premultiplicado ( r = r×a ).

La fórmula completa es:

max((r₁-r₂)², (r₁-r₂ - a₁+a₂)²) + max((g₁-g₂)², (g₁-g₂ - a₁+a₂)²) + max((b₁-b₂)², (b₁-b₂ - a₁+a₂)²)

Fuente C incluyendo implementación de SSE2 .


Mi idea es integrar una vez todos los colores de fondo posibles y promediar el error cuadrado.

es decir, para cada componente de cálculo (usando el canal rojo como ejemplo aquí)

Integral de 0 a 1 ((r1 * a1 + rB * (1-a1)) - (r2 * a2 + rB * (1-a2))) ^ 2 * drB

el cual si calculé correctamente se evalúa a:

dA=a1-a2 dRA=r1*a1-r2*a2 errorR=dRA^2+dA*dRA+dA^2/3

Y luego sumar estos sobre R, G y B.


Nunca lo he hecho, pero la teoría y la práctica dicen que convertir los valores RGB en la imagen y la paleta en luminance–chrominance te ayudará a encontrar las mejores coincidencias. Dejaría el canal alfa solo, ya que la transparencia debería tener poco o nada que ver con la parte de "verse mejor".

Este xmass realicé algunos fotomosaicos para regalos utilizando un software de código abierto que combina fragmentos de la imagen original con una colección de imágenes. Ese parece ser un problema más difícil que el que estás tratando de resolver. Uno de los programas fue metapixel .

Por último, la mejor opción debería ser utilizar una biblioteca existente para convertir la imagen a un formato, como PNG, en el que puede controlar la paleta.


Varios principios:

  1. Cuando dos colores tienen la misma alfa, rgbaDistance = rgbDistance * (alpha / 255). Compatible con el algoritmo de distancia de color RGB cuando ambos alfa son 255.
  2. Todos los colores con alfa muy bajo son similares.
  3. La distancia rgbaDistance entre dos colores con el mismo RGB depende linealmente del delta Alpha.

double DistanceSquared(Color a, Color b) { int deltaR = a.R - b.R; int deltaG = a.G - b.G; int deltaB = a.B - b.B; int deltaAlpha = a.A - B.A; double rgbDistanceSquared = (deltaR * deltaR + deltaG * deltaG + deltaB * deltaB) / 3; return deltaAlpha * deltaAlpha / 2.0 + rgbDistanceSquared * a.A * b.A / (255 * 255); }