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