jueves, 20 de agosto de 2015

allRGB mediante algoritmo genético

Como continuación a mi anterior entrada, en esta voy a mostrar mi progreso con respecto a la creación de imágenes allRGB (con todos y cada uno de los colores existentes en informática). En esta ocasión he utilizado un algoritmo genético (evolutivo) ya que, a diferencia de mi algoritmo anterior, es muchísimo más rápido y se obtienen mejores resultados que con un algoritmo en el que los pasos son definidos estrictamente por el programador. Este es el resultado y a continuación explicaré cómo lo he realizado:



Está disponible en la web allRGB con el título "Globos 2":

http://allrgb.com/globos-2

A diferencia de mi anterior algoritmo, en el que analizaba píxel a píxel buscando el color más cercano sin utilizar (para que no se repitan), en este caso he partido de una imagen que ya contenía todos los colores (16.777.216) pero repartidos de forma aleatoria por la imagen. Se ve algo así como el ruido de los antiguos televisores analógicos. Luego selecciono dos píxeles de la imagen al azar y los intercambio. Si este intercambio hace que la imagen de ruido se parezca más a la original, entonces hago el cambio efectivo. Si no se produce una mejoría, busco otros dos píxeles distintos. Conforme se analizan más y más parejas de píxeles, la imagen se va acercando a la original. Aquí una animación en la que se ve el proceso paulatinamente:




La fórmula que he utilizado para calcular la diferencia ("dif") entre dos colores es esta:

Dif_total = (dif_L^2 + dif_a^2 + dif_b^2) + (dif_R^2 + dif_G^2 + dif_B^2)/10

L, a y b son las coordenadas del espacio de color "Lab", basado en estudios de la percepción humana. El canal L representa la luminosidad del color, y los canales a y b representan el tono del color. Aquí podemos ver una animación de este espacio de color:


Imagen obtenida de la web www.brucelindbloom.com

R, G y B son las coordenadas de color usadas en informática por defecto. Las utilizo en mis cálculos pero dividido entre 10 para darle menor importancia, ya que utilizando el espacio de color Lab se obtienen mejoresa resultados visuales. Además he utilizado las coordenadas elevadas al cuadrado por el mismo motivo, para obtener mejores resultados visuales y mejorar la imagen como conjunto, y no unos píxeles más que otros. En mis primeros intentos utilicé un algoritmo evolutivo que sólo medía la diferencia RGB, y sin elevar al cuadrado. Los resultados no fueron todo lo bueno que me esperaba. Pronto me di cuenta de que debía afinar el algoritmo para hacer que funcionase bien

El último paso para mejorarlo más aún es utilizar dispersión del error (dithering), que todavía tengo que aprender a aplicar correctamente de forma que no se genere excesivo "ruido" en la imagen. También me gustaría programarlo en un lenguaje más rápido como es C++ o incluso C, el rey de la velocidad, o utilizar técnicas como el procesamiento multi-hilo o el Open-CL para usar el procesador gráfico como co-procesador en los cálculos. Poco a poco voy mejorando mis conocimientos... :)
 
Contador Gratis