Tengo un valor rgb y si no existe en la tabla de colores en mi base de datos necesito encontrar el color más cercano. Estaba pensando en comparar todos los valores y encontrar la diferencia (en rojo, verde y azul) y luego tomar el promedio. La desviación promedio más baja debe ser el color más cercano. Me parece que debería haber una mejor manera. ¿Algunas ideas?Dado un valor RGB, ¿cuál sería la mejor manera de encontrar la coincidencia más cercana en la base de datos?
Respuesta
Considera un color como vector en el espacio tridimensional, a continuación, puede calcular fácilmente la diferencia mediante el uso de Pitágoras 3d:
d = sqrt((r2-r1)^2 + (g2-g1)^2 + (b2-b1)^2)
sin embargo, tenga en cuenta que debido a los colores que son objeto de interpretación por parte de los ojos no tan perfectas, es posible que desee ajustar los colores para evitar que tengan el mismo importancia.
Por ejemplo, el uso de a typical weighted approach:
d = sqrt(((r2-r1)*0.3)^2 + ((g2-g1)*0.59)^2 + ((b2-b1)*0.11)^2)
Dado que los ojos son más sensibles al verde, y menos sensible al azul, dos colores que se diferencian sólo en el componente azul debe por lo tanto tienen una diferencia numérica grande para ser considerado "más diferente" que uno que es la misma diferencia numérica en el componente verde.
También hay varias formas de optimizar este cálculo. Por ejemplo, ya que no está realmente interesado en el valor real d
, se puede prescindir de la raíz cuadrada:
d = ((r2-r1)*0.30)^2
+ ((g2-g1)*0.59)^2
+ ((b2-b1)*0.11)^2
señalar aquí que en muchos lenguajes de programación basados en C-sintaxis (como C#), ^
hace no significa "elevar al poder de", sino más bien "exclusivo binario o".
Así que si esto fuera C#, usaría Math.Pow
para calcular esa parte, o simplemente expandir y hacer la multiplicación.
Agregado: A juzgar por la página en Color difference on Wikipedia, existen varias normas que tratan de manejar las diferencias de percepción. Por ejemplo, el llamado CIE94 usa una fórmula diferente, en el modelo de color L*C*h
, que parece que vale la pena investigar, pero depende de qué tan preciso sea el resultado.
Probablemente mucho mejor que mi idea ... – nfechner
Una respuesta como esta siempre es una delicia para leer. –
+1. Esto parece cercano a mí, excepto que el ojo también es más sensible al brillo que al color, por lo que una diferencia óptima también debe tener en cuenta el ángulo entre los vectores de color, así como su longitud y la distancia desde la punta hasta -propina. – RickNZ
Calcula tanto la media y la distancia así:
(r + g + b)/3 = average
(r - average) + (g - average) + (b - average) = distance
Esto debe darle una buena idea del valor más cercano.
A continuación se hace exactamente lo que usted describe:
select (abs(my_R - t.r) + abs(my_G - t.g) + abs(my_B - t.b))/3 as difference, t.*
from RGBtable t
order by difference desc;
Sin embargo, es posible obtener mejores resultados con algo que no fue lineal. En el enfoque de "tomar promedios", si el color del objetivo es (25, 25, 25) el color (45, 25, 25) estaría más cerca que (35, 35, 35). Sin embargo, apuesto a que el segundo realmente se miraría más cerca, ya que también sería gris.
Algunas ideas vienen a la mente: podría tratar de cuadrar las diferencias antes de promediarlas. O podría hacer algo complicado al encontrar el color con la relación más cercana entre los diferentes valores. Encontrar las proporciones más cercanas te acercaría más al matiz correcto, pero no explicará la saturación (si recuerdo bien los términos ...)
Al mirar the Wikipedia page on Color difference, la idea es tratar los colores RGB como puntos en tres dimensiones. La diferencia entre los dos colores es la misma que la distancia entre dos puntos:
difference = sqrt((red1 - red2)^2 + (green1 - green2)^2 + (blue1 - blue2)^2)
Vamos la base de datos lo haga por usted:
select top 1
c.r,
c.b,
c.g
from
color c
order by
(square(c.r - @r) + square(c.g - @g) + square(c.b - @b))
Dónde @r
, @g
y @b
son el r, g, b valores del color que está buscando (sintaxis del parámetro SQL Server, ya que no especificó una base de datos). Tenga en cuenta que esto todavía tendrá que hacer un escaneo de tabla ya que el order by
tiene una llamada de función en él.
Tenga en cuenta que la llamada de raíz cuadrada extra no es necesaria ya que es una función monótona. No es probable que sea demasiado importante, pero aún así.
La base de datos no es una varita mágica. Hacer esto requerirá tanto trabajo como hacerlo usted mismo; solo está descargando el trabajo a la base de datos. –
Bueno, dado que la información está casi en una base de datos, tiene más sentido para mí simplemente obtener las filas que necesita en lugar de buscarlas todas para calcular las distancias usted mismo. – Donnie
Un paso mejor que el promedio es cercano raíz cuadrada:
((delta red)^2 + (delta green)^2 + (delta blue)^2)^0.5
Esto reduce al mínimo la distancia en el espacio de color 3D.
Dado que una raíz está aumentando estrictamente, puede buscar el máximo del cuadrado en su lugar. La forma de expresar esto en SQL dependería de qué RDBMS esté utilizando.
El Euclidean distancedifference = sqrt(sqr(red1 - red2) + sqr(green1 - green2) + sqr(blue1 - blue2))
es el standard way para determinar la similitud de dos colores.
Sin embargo, si tiene los colores en una lista simple, para encontrar el color más cercano es necesario calcular la distancia del nuevo color con cada color de la lista. Esta es una operación O (n).
La sqrt()
es una operación costosa, y si solo está comparando dos distancias, simplemente puede omitir sqrt()
.
Si tiene una paleta de colores muy grande, es potencialmente más rápido organizar los colores en un kd tree (o uno de los alternatives) para reducir el número de diffreences que requieren computación.
- 1. PHP - devolver la coincidencia más cercana de la base de datos
- 2. ¿Cuál es la mejor manera de almacenar un valor monetario en la base de datos?
- 3. La mejor manera de encontrar un punto en un círculo más cercano a un punto dado
- 4. ¿Cómo encontrar la ubicación más cercana utilizando latitud y longitud desde la base de datos sql?
- 5. ¿Cuál es el mejor algoritmo para la palabra más cercana
- 6. Encontrar la fracción entera más cercana a un real aleatorio dado
- 7. Buscar el valor numérico más cercano en la base de datos
- 8. la hora más cercana
- 9. Cómo encontrar la mejor coincidencia difusa para una cadena en una base de datos de cadena grande
- 10. ¿Cuál es la mejor manera de migrar datos en django
- 11. ¿Cuál es la mejor manera de almacenar datos de tendencia?
- 12. Una manera rápida de encontrar exponente de la más cercana poder superior de 2
- 13. manera eficiente para encontrar la clave más grande en un diccionario con valor distinto de cero
- 14. La mejor manera de administrar la conexión de base de datos para un servlet de Java
- 15. Manera más limpia de encontrar una coincidencia en una lista
- 16. Java: ¿Alguien tiene un método para encontrar la mejor coincidencia de cadena en matriz?
- 17. Resultado de búsqueda de Linq por coincidencia más cercana
- 18. Cuál sería la mejor forma de almacenar registros en SQL
- 19. ¿Cuál es la mejor manera de diseñar este problema particular de base de datos/SQL?
- 20. Cómo obtener el valor de la entrada más cercana Jquery
- 21. La mejor manera de evitar la entrada duplicada en la base de datos mysql
- 22. ¿Cuál es la mejor base de datos de objetos Java?
- 23. ¿Cuál sería la mejor manera de migrar elementos de trabajo de TFS 2010 a JIRA?
- 24. La mejor manera de cortar un queryset de Django sin golpear la base de datos más de una vez
- 25. ¿Cuál es la mejor manera de almacenar archivos multimedia en una base de datos?
- 26. ¿Cuál es la mejor manera de mantener el historial de cambios en los campos de la base de datos?
- 27. ¿Cuál es la mejor manera de almacenar una matriz de bytes en la base de datos SQL utilizando NHibernate?
- 28. ¿Cuál es la mejor manera de validar datos en mongo?
- 29. Encontrar la coordenada de cuadrícula más cercana a la posición del mouse con javascript/jQuery
- 30. Encontrar la coincidencia de la cadena parcial
¿Cuál es la estructura de su mesa donde almacena los colores? – Ryan
Aunque cada respuesta individual sugiere distancia euclidiana en el espacio RGB, ¡no lo haga! HSV es mucho más adecuado para modelar la distancia perceptual que RGB, por lo que debe convertir primero su espacio de color. –