Wednesday, March 20, 2013

Nuevo reto de programación lúdica: Óleo digital



Una característica de las imágenes en la computadora es que son digitales, es decir, hechas de dígitos, de números, pues. Cada dígito representa un punto en la pantalla, y normalmente el valor que vemos corresponde al color que ese punto tiene en la imagen. De esta manera, las fotografías digitales (ya sean escaneadas o tomadas con alguna cámara digital), son en realidad una matriz cuadrada de pixeles (puntos en la pantalla), que bien puede ser en color o en blanco y negro.

En la medida en que la tecnología ha progresado, hemos pasado de imágenes de 256 colores a las que nos pueden mostrar alrededor 16 millones de colores. Actualmente, cualquier tarjeta de video que se precie de serlo muestra los tres componentes de color R(ed – rojo), G(reen – verde) y B(lue – azul) en cada pixel (o punto), el cual puede ser un valor entre 0 y 255. De esta manera, 256 x 256 x 256 nos da 16,777,216 posibles colores. Cabe señalar que el ojo humano no puede ver semejante espectro de colores, pero es un hecho que la computadora puede desplegarlos.

Ahora bien, cada fotografía digital es en realidad una aproximación sobre lo que se fotografía tomando una cámara analógica, es decir, una que tenga filme. Por ello mismo, “el grano” de la cámara digital es la precisión con la cual puede distinguir los detalles. Por ello vemos que hay cámaras digitales de 4, 8, 10 o más megapixeles. De hecho, tampoco ya el ojo humano no distingue entre, digamos, 8 y 10 megapixeles. De esta manera, la resolución de las imágenes ha crecido y con ello la necesidad de usar cada vez más bytes en los archivos y memorias donde se guarda.

Con el advenimiento de la tecnología digital de imágenes y su gran aceptación en el mercado, estamos viendo desaparecer las cámaras analógicas y los filmes. Se acabó el revelado y los costos asociados a esto. Además, con la generación de imágenes digitales, también nació la posibilidad de post procesarlas para generar efectos en ellas. Photoshop, por ejemplo, es uno de los programas más populares para manipulación digital de imágenes.

Filtros Digitales


La manipulación de una imagen digital se denomina genéricamente como un “filtro”, el cual convierte una imagen en alguna otra cosa. Existen filtros que son reversibles, mientras que también los hay aquellos que no lo son. De acuerdo a las necesidades, se pueden tener diversos filtros o transformaciones que pueden aplicarse a una imagen incluso ya filtrada. Los resultados suelen ser sorprendentes.

Muchos filtros gráficos, sino es que todos, se consideran transformaciones gráficas basadas en una matriz llamada también “convolución” (no se asuste por la palabra, es sólo un término que da precisión a todo esto). Estas convoluciones es el procesar segmentos de la imagen a partir de una submatriz (que puede ser de 3×3, 4×4, 5×5, etc.) de pixeles, que va recorriendo la imagen completa. El resultado final convierte la imagen original en alguna otra cosa. Existen filtros para reconocer bordes, para quitar ruido, para meter ruido, para hacer más precisa una imagen, para hacerla más borrosa, para deformarla, etc. Las aplicaciones son infinitas.

El filtro Oleo Digital (en tonos de grises)


En el libro Beyond Photography (The Digital Darkroom), de Gerard J. Holzmann, que trabajó algunos años en los Laboratorios Bell, el autor nos habla de cómo alterar imágenes. Ahí presenta la fotografía de Dennis Ritchie (uno de los inventores del lenguaje C), y al procesarla la convierte en la misma imagen, pero como si fuese pintada al óleo. De acuerdo al autor, lo que hace es esto: “Para cada punto en la imagen, un programa calcula el histograma de los 36 bordes del derredor [del punto de interés], en la vecindad del punto de interés, y se asigna el valor [al propio punto que estamos procesando] el valor que contenga la mayor frecuencia. El resultado es casi una pintura al óleo”.

Cuando intenté escribir mi propio programa que hiciese este filtro “al óleo”, decidí, sin embargo, no usar 36 puntos, sino 49, para que así mi matriz (llamada: de convolución), mi cuadrícula, tenga un punto central en [4,4]. Con una convolución par no se puede tener un punto central. Igualmente, generé un arreglo de 256 números (de 0 a 255), para colocar la frecuencia de los 49 valores de la matriz de 7×7, que voy recorriendo en la imagen, pixel a pixel. Así, saco los primeros 49 valores y encuentro la frecuencia de los mismos. En el punto de interés pongo el que tenga la mayor frecuencia. ¿Qué pasa si hay más de uno valor con la mayor frecuencia? ¿Cuál pongo? Cualquiera de ellos. Da lo mismo.


La imagen de la izquierda es la de Dennis Ritchie (el creador del lenguaje C), como aparece en el libro de Holzmann. A la derecha aparece mi propia versión del algoritmo descrito. ¿Cuál le gusta más a usted? Este programa funcionaba originalmente sólo con imágenes en blanco y negro (tonos de grises), pues en imágenes de tonos de gris hay nada más 256 tonos y además, las componentes RGB de cada pixel tienen el mismo valor, es decir, R=B=G, lo cual hace sencillo el encontrar el histograma de frecuencias de color. La diferencia en resultados es que Holzmann usa una matriz par y yo uso matrices impares.

El filtro Oleo Digital (en color)

Para poder generar imágenes al mejor estilo óleo, en color, se necesita hacer una modificación que parece trivial, pero que no lo es. La dificultad es que al querer pasar a color, tenemos que las imágenes pueden contener poco más de 16 millones de colores. Esto, obviamente hace el problema un poco más difícil, pues no podemos generar un arreglo de 16 millones (para seguir con la técnica usada en la parte en tonos de gris), pues es totalmente ineficiente y absurdo. Así, aquí hay que contar y crear el histograma de frecuencias de manera más sencilla. Después de dos semanas de darle la vuelta al problema, finalmente hallé una solución simple. La implementé y de pronto ya tenía mi programa que generaba el óleo digital en color. (¿Cómo le hice?… es parte del reto)

Al poder hacer el histograma y hallar cuál es el valor de mayor frecuencia, simplemente lo pinto para cada punto en la pantalla. Es claro que el filtro hace una imagen que pierde precisión contra una fotografía real, pero se asemeja, sin duda, a un cuadro hecho al óleo.

El reto es pues el siguiente: hágase el filtro óleo en color siguiendo la técnica: “Para cada punto en la imagen, un programa calcula el histograma de los 36 bordes del derredor [del punto de interés] y se asigna el valor [al propio punto de interés] el valor que contenga la mayor frecuencia. El resultado es casi una pintura al óleo”.




He aquí las bases adicionales del reto:

  • Ganará el programa que transforme la imagen de Lena (que aparece más abajo), en el menor tiempo posible. El segundo mejor tiempo obtendrá el segundo lugar.
  • Habrá dos lugares: Ambos se llevarán una taza con el logotipo de La_Morsa. Mi intención es que al imprimir esas tazas aparezca una leyenda con el título de la misma y el lugar obtenido, para que quede constancia por el tiempo de vida de la taza.
  • Los programas pueden hacerse en cualquier lenguaje de propósito general y no se vale usar en éste particularmente, bibliotecas que hagan filtros gráficos. Los programadores tienen que resolver el problema por sí mismo, sin ayuda de bibliotecas externas. (Desde luego, se vale usar alguna biblioteca para cargar/guardar la imagen de Lena para procesarla, la cual es un JPG, pero nada más). Así pues, C, C++, C#, Pascal (Delphi), Javascript, Python, Ruby, Visual BASIC, Visual C, Java, etcétera, son idóneos para esta labor.
  • Los autores de los programas deberán mandar el código fuente y el archivo ejecutable en Windows 7.
  • Un autor puede mandar versiones mejoradas de su propio software dentro del tiempo del concurso. No se tomarán en cuenta las que se salgan del tiempo establecido.
  • En la medida de lo posible, el programa debe indicar el tiempo total del proceso realizado para crear la imagen al óleo de Lena.
  • El autor debe enviar el código fuente y quienes ganen aceptan que su código quede accesible para quien lo quiera ver.
  • Los programas deben poderse ejecutar en el sistema operativo Windows 7 de 64 bits. Se correrán en una máquina AMD con 6 núcleos y los resultados obtenidos son inapelables y definitivos. De nuevo aclaro: este es un reto de buena fe y no un concurso estrictamente. Los premios son meramente un estímulo extra para que se animen a entrarle al reto. Evidentemente asumo que el código de cada concursante es creación del mismo y que no andan copiando el código de otras partes, foros, sitios en Internet, etcétera. En caso de hallar que el código fue copiado, el programador queda descalificado.
  • El reto dura una semana a partir del día de la publicación del artículo. Por ejemplo, si éste se publica un 10 de mayo a las 3 de la tarde, el reto se cierra el 17 de mayo a esa misma hora.
  • Cuando reciba algún programa participante en el reto, le enviaré un acuse de recibo para asegurarnos que están todos los que son y son todos los que están.
  • El concurso es para quienes viven en la República Mexicana. Si alguien de otro país quiere participar es bienvenido, pero no podrá acceder a los premios.
  • Los programas deben ser enviados a morsa@la-morsa.com o en su defecto a lopem@hotmail.com, por si alguna de las direcciones no funciona.

Así que queridos y entusiastas programadores, a entrarle al reto. Afilen sus herramientas de programación y que gane el mejor.

Imagen a procesar (512 x 512 pixeles):


2 comments:

Bruno Unna said...

Hallo, Morsita!

¿Qué se hace con los pixeles cercanos a las orillas?

Morsa said...

En las orillas tienes dos opciones, o usas ceros en los no pixeles o bien, los ignoras (cosa que yo hice). Así, la imagen aparecerá con un borde de pixeles no procesados, pero no importa.
saludos