Foros del Web » Programando para Internet » PHP »

Simplificar los colores de una imagen

Estas en el tema de Simplificar los colores de una imagen en el foro de PHP en Foros del Web. Hola foro, vamos a ver si me explico bien. Estoy intentando hacer mediante PHP y GD una simplificación de colores de una imagen. Básicamente quiero ...
  #1 (permalink)  
Antiguo 05/12/2007, 19:01
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 6 meses
Puntos: 45
Simplificar los colores de una imagen

Hola foro, vamos a ver si me explico bien. Estoy intentando hacer mediante PHP y GD una simplificación de colores de una imagen. Básicamente quiero conseguir que de una imagen como ésta:


Se consiga una cosa como ésta


(esto es un apaño que he hecho con el photoshop, su varita mágica, cuentagotas y bote de pintura nada más...)

Lo que quiero no es conseguir ésta segunda imagen, lo que quiero es quedarme con esos colores que la componen. Si os dais cuenta, esos colores son básicamente un esbozo de lo que aparece en la imagen. Los colores que tendría en la segunda imagen del post son unos 3 azules, 5 ó 6 verdes, 2 ó 3 ocres, un blanco, un gris, y quizá un negro.

Si guardamos la imagen como un GIF con 4 colores veremos ésto:

Que es cercano a la composición que quiero conseguir.

Estoy cerca de lograrlo, pero aún así me faltan ideas...

Los pasos que sigo para conseguir estos colores son los siguientes:
  1. Obtengo la imagen (imagecreatefromjpeg)
  2. Entro en un bucle para leer el color de cada píxel (imagecolorat), y ese color leído lo almaceno en $listaColores (array asociativo color=>cantidad de veces que aparece en la imagen)
  3. Transformo ese color a valor HSV (ó HSL) para poder compararlo más fácilmente a los colores previamente obtenidos en el bucle y encontrar similitudes.
  4. Si ese color es parecido a algún otro ya almacenado (según unos umbrales de tono, saturación y luminosidad personalmente escogidos), éste color no se almacena en $listaColores, sólo aumenta el número de veces que aparece.
  5. Muestro los colores almacenados en $listaColores que son los buscados.


Al parecer ésto es lo que debería servir para hallarlos sin problemas. Bueno esto es lo que obtengo:



Si alguien quiere darme alguna idea, o se le ha ocurrido trabajar con gamas de colores y quiere aportar algo, que no dude en postear. En absoluto he conseguido que los colores obtenidos sean la media de los encontrados en la imagen, simplemente cada color es el primer color leído, y luego los demás se han ido sumando a él por parecido. Si después algún color que se obtiene difiere lo suficiente de sus antecesores, se crea un nuevo registro en el array.

Me gustaría hacer lo de la media, si alguien es capaz de hacer una media entre dos colores HSL será agradecido



Un saludo y gracias por leer
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #2 (permalink)  
Antiguo 05/12/2007, 19:13
 
Fecha de Ingreso: septiembre-2007
Mensajes: 220
Antigüedad: 16 años, 7 meses
Puntos: 1
Re: Simplificar los colores de una imagen

En vez de sumar que un color parecido reaparece quizás sea mejor guardar todos los colores distintos aunque sean muy parecidos y el número de veces que aparece, y luego agrupas los colores parecidos y seleccionas el que más aparezca de los parecidos.
  #3 (permalink)  
Antiguo 05/12/2007, 19:54
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 6 meses
Puntos: 45
De acuerdo Re: Simplificar los colores de una imagen

¡Qué velocidad Sanubrio! Gracias por responder.

De acuerdo, ese método fue con el que empecé. Pero hay que tener en cuenta que hay muchísimos colores posibles y muchísimos colores parecidos en una imagen. Mi intención primaria era esa: sacar todos los colores que encuentre y quedarme con los que más aparecen. El script es lentísimo (por tener que analizar demasiadas cosas) y leyendo de 5 en 5 píxeles me tarda casi 2 minutos la página en terminar de ejecutarse. Saca 3898 valores en el array, de los 7384 píxeles leidos totales, es decir, más de la mitad aparecen más de una vez.

El color que más se repite (172 veces) es el hsl(215,79%,78%), que es un azul pastel clarito. Luego hay unos 25 tonos del mismo azul (entre 209 y 217 de tono de azul) hasta encontrar el primer ocre de la arena hsl(37,35%,73%) 23 veces. El blanco puro aparece dos posiciones más allá, con 22 intervenciones. Hasta la posición 40 en la lista no empiezan a aparecer ocres (tonos del 34 al 40) con una intervención variable de entre 14 y 6.

Después una primera aparición de un verde oscuro hsl(101,100%,12%) que interviene únicamente 6 veces. Azules y ocres con alguna intercalación de un verde oscuro hasta el infinito en la lista, hasta que llegamos a 2 intervenciones de color que aparecen indistintamente azules, ocres y verdes de todo tipo. En 1 intervención, ya a 1/5 de la cabeza de la lista entera aparecen los primeros amarillos y marrones saturados. Luego grises, morados, y colores minoritarios.


Como se puede ver los resultados son bastante repetitivos, hay muchos elementos que son muy parecidos entre sí y merece la pena la estructura de los umbrales para detectarlos y aúnarlos. Sin ir más lejos el primer y sexto resultado son hsl(215,79%,78%) y hsl(215,80%,77%), que seríamos incapaces de distinguirlos visualmente ni esforzandonos. El mismo tono, un punto más de saturación en el segundo y un punto menos de luz. Aparecen 172 y 51 veces respectivamente. ¿No merece la pena aunarlos en un sólo color intermedio que aparezca 223 veces? Eso es lo que he intentado con los umbrales.


Un saludo.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 17:28.