lunes, 9 de noviembre de 2015

Contadores inteligentes: ¿Saltan más?

Os dejo el enlace al último artículo que he realizado en Nergiza.com, en el que experimentamos con los nuevos contadores digitales y aprendemos a usarlos en nuestro beneficio:


http://nergiza.com/contadores-inteligentes-saltan-mas/

Con lo aprendido aquí podréis optimizar la potencia contratada en vuestro suministro de electricidad, y ahorraros un buen dinero al año.

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... :)

lunes, 4 de mayo de 2015

allRGB

Las imágenes que capta nuestra cámara o las que vemos en nuestros monitores está compuesta de píxeles, y cada píxel tiene tres sub-píxeles o ingredientes: la luz roja, la verde y la azul, y aplica a cada sub-pixel una intensidad determinada para generar todos los colores posibles. Podemos ver una ampliación de cómo se ve una pantalla de cerca:



Cada sub-pixel puede iluminarse con una intensidad que va desde el 0 (totalmente apagado) hasta el 255 (totalmente encendido). Por ejemplo, si queremos ver por el monitor un color rojo oscuro, necesitaremos crear una imagen en la que los sub-píxeles verde y azul estén apagados, mientras que el rojo deberá tener un valor intermedio, por ejemplo 120.

Dicho color se expresa mediante el modelo de color RGB (Red, Green, Blue; los colores primarios en la síntesis (mezcla) aditiva (que se suma)), y quedaría así: RGB = (120,0,0)



Puede que os enseñaran que los colores primarios eran el rojo, el amarillo y el azul, pero esto no es cierto. No existen unos colores primarios mediante los cuales podamos conseguir todos los colores que existen mediante la mezcla de los mismos, y los que más se aproximan son el Rojo 700nm, el Verde 525nm y el Azul/violeta 400nm. Los colores que podemos conseguir con la suma de estos colores "primarios" son los que se encuentran dentro del siguiente triángulo llamado espacio de color CIE 1931:


Los colores que están fuera del triángulo (como por ejemplo el cyan puro 495nm) no pueden ser representados por los monitores, pero es algo complejo de entender y me llevaría mucho tiempo explicarlo.

A donde quiero llegar es que el número de colores distintos que se pueden conseguir mediante la combinación de todas las distintas intensidades de cada sub-píxel es de 256 x 256 x 256 = 16.777.216 de colores distintos para una imagen de 24 bits (profundidad del color).

Los primeros ordenadores sólo podían reproducir dos colores (profundidad de color de 1 bit), como el verde y el negro. Luego se consiguió reproducir 16 colores, posteriormente 256 colores (8 bit) y hoy día lo más común es utilizar 24 bits, aunque los fotógrafos y otros profesionales pueden llegar a usar imágenes de 48 bits (billones de colores), pero para ello se necesitan unos monitores especiales que actualmente son muy caros y están destinados a profesionales.

Pues existe una web (allRGB.com) en la que distintos artistas y programadores suben imágenes creadas por ellos en las que se cumple una característica común: poseen todos y cada uno de los colores posibles, sin que falte ninguno y sin repetir ninguno. Para conseguirlo es necesario tener conocimientos de programación, como es mi caso. Así que he presentado mi propuesta que consiste en transformar una foto normal en otra que contenga todos los colores. Para ello he creado un código que tardó una semana en ejecutarse debido a la complejidad computacional del problema a resolver. Este es el resultado una vez aceptado y publicado:

http://allrgb.com/globos

Os dejo una miniatura de la imagen original y del resultado. La original tenía unas dimensiones de 4092 x 4092 píxeles, lo que multiplicado hace un total de 16.777.216 píxeles, todos ellos distintos:






Y para ver la diferencia de una forma más clara, he creado un gif animado. He de decir que dicho gif sólo tiene 256 colores distintos, por eso se diferencia un poco del original:



El algoritmo lo he programado usando Processing por su simplicidad, aunque en un futuro usaré C# ya que es mucho más rápido ejecutándo el código. Esta primera versión del algoritmo lo que hace es:

Leer la imagen original
Crear las variables y objetos necesarios
crear matrices en las que se vuelca la información de la imagen original, como por ejemplo la posición de cada color en la imagen, etc
empezando por arriba de la imagen original, buscar el color más próximo que no haya sido usado aún.

Como es lógico, al principio no hay apenas colores usados, por tanto la imagen producida se parece mucho a la original. Pero a medida que avanzamos cada vez hay menos colores disponibles y el algoritmo tiene que recurrir a colores que se parecen menos al original. Por eso al final se obtienen colores muy distintos. Aquí una imagen creada con un algoritmo que mide la diferencia entre la imagen original y la modificada. Cuanto más diferencia haya, mas claro será el píxel correspondiente:



La siguiente versión del algoritmo (que ya he empezado) hará justo lo contrario. Buscará los colores que menos se acercan al de la imagen original y serán los primeros en usarse. El objetivo es reducir al mínimo el error cometido en conjunto. Y la última versión del algoritmo aplicará una difusión del error (dithering) para que a simple vista el conjunto tenga mucho mejor aspecto.
 
Contador Gratis