Archivo

Archivo para la categoría ‘Imagen Digital’

Recopilación de soluciones para los retos de #tuentiContest . Challenge #12

Sábado, 25 de Junio de 2011 Gaspar Fernández 2 comentarios

Últimamente he hablado acerca del I concurso de programación de Tuenti. Un concurso de programación Online que se llevó acabo durante la semana pasada (del 13 al 20 de Junio, muy mala fecha).

Podéis ver los enunciados de todos los problemas, con ejemplos sobre la entrada y salida (aunque a veces no hay que haerles mucho caso) en la web oficial del concurso, pero en Vidas Concurrentes lo encontramos todo en español.

Challenge #12 : The Stargate Problem

Tenemos que dar saltos entre planetas. Llegar de la Tierra a Atlantis, dando saltos entre planetas a través de Stargates, cada salto tendrá un coste en tiempo, empezaremos en la fecha estelas 25000 y si podemos llegar en el pasado mejor. Eso sí, si no podemos determinar la fecha, tendremos que decir: “BAZINGA”

Soluciones:

Si no estás en la lista y quieres plantear tu solución, deja un comentario con tu link !

Actualización 2011/06/25 13:23 : Añadida solución de @enwillyado
Actualización 2011/06/28 08:30 : Añadida solución de @theom3ga
Actualización 2011/07/03 01:45 : Añadida solución de @frisco82
Actualización 2011/07/03 13:45 : Añadida solución de @Rosapolis
Actualización 2011/07/13 02:48 : Añadida solución de @lagunex

Recopilación de soluciones para los retos de #tuentiContest . Challenge #2

Miércoles, 22 de Junio de 2011 Gaspar Fernández 2 comentarios

Últimamente he hablado acerca del I concurso de programación de Tuenti. Un concurso de programación Online que se llevó acabo durante la semana pasada (del 13 al 20 de Junio, muy mala fecha).

Podéis ver los enunciados de todos los problemas, con ejemplos sobre la entrada y salida (aunque a veces no hay que haerles mucho caso) en la web oficial del concurso, pero en Vidas Concurrentes lo encontramos todo en español.

Challenge #2 : TLang

Se trata de implementar un parser que suma, reste y multiplique, con los símbolos ^= ,^# 2 2 y ^@, eso sí, el final de la operación siempre lo marcará un $. Por otra parte, hay símbolos, como ^@ (resta) que pueden ir sólo con un número, en lugar de con varios. Debemos leer de la entrada las operaciones a realizar y devolver el número de salida.

Soluciones:

Si no estás en la lista y quieres plantear tu solución, deja un comentario con tu link !

Actualización: 2011/06/22 13:54 : Error tipográfico
Actualización: 2011/06/22 20:00 : Añadida solución de @Puigcerber
Actualización: 2011/06/28 07:58 : Añadida solución de @theom3ga
Actualización: 2011/07/02 22:30 : Añadida solución de @frisco82
Actualización: 2011/07/03 13:30 : Añadida solución de @Rosapolis
Actualización: 2011/07/08 12:37 : Añadida solución de captain_regex

Limitando recursos en ImageMagick

Jueves, 21 de Abril de 2011 Gaspar Fernández 2 comentarios

A veces, utilizar ImageMagick puede ser horrible, sobre todo porque en ocasiones, se come todos los recursos de nuestro sistema, al procesar imágenes grandes, múltiples imágenes, vídeo, etc… en ocasiones puede que el OOM Killer de Linux detenga la tarea, y puede que mientras procesamos las imágenes, necesitemos el ordenador para algo.

NOTA: Utilizaré convert para poner ejemplos de cómo utilizar esta herramienta, pero estos consejos valen para todos los programas de tratamiento de imagen que componen imagemagick: convert, mogrify, montage…

Bien, ImageMagick tiene opciones para modificar cuánta memoria va a acaparar. Si sabemos que es una tarea muy pesada para la memoria (una imagen de 5000×5000 ocupará cerca de 70Mb, una imagen de 10000×10000 cerca de 300Mb, sin contar la memoria utilizada para el tratamiento de la imagen) podemos decir a ImageMagick que utilice como mucho 20Mb de RAM (el resto de memoria que necesite la cogerá del disco duro, de nuestro directorio temporal).
Para esto, podemos utilizar lo siguiente:

$ convert imagenA.jpg -limit memory 20MiB -resize 50% imagenB.png

Si durante el proceso, ejecutamos top podremos ver la diferencia de memoria utilizada.
Podemos ver los recursos que podemos limitar con:

$ identify -list resource
File Area Memory Map Disk Thread Time
——————————————————————————-
768 4.2324GB 2.9563GiB 7.8835GiB 18.446744EB 1 unlimited

Las peticiones de memoria que hace ImageMagick como vemos aquí son las siguientes:
Se intenta reservar memoria para los pixels, pero si la memoria excede el límite de memory, o falla (puede que el sistema no disponga de memoria suficiente), lo escribirá en disco y lo mapeará en memoria, pero si se excede la memoria del mapa de memoria, todo va a disco, si ya no tenemos disco duro suficiente, o hemos limitado el disco disponible fallará.
Tenemos que tener en cuenta que hacemos distinción entre MiB (MebiBytes) (1MiB=1.048.576 bytes) y MB (MegaByte) (1MB = 1.000.000 bytes)

Así que también podemos limitar la memoria de los mapas de memoria, de disco, los threads a utilizar (o podemos darle más, si queremos), por ejemplo, si queremos insertar imágenes en un pdf:

$ convert *.jpg -limit memory 200MiB -limit map 200MiB resultado.pdf

También es muy útil el parámetro de area, este vale para limitar la memoria de forma absoluta, es decir, para que ImageMagick no intente hacer nada en memoria si excedemos esta cantidad de memoria (a veces es mejor limitar la memoria, antes de que intente encajar las reservas de memoria en los otros dos parámetros, y tenemos más control sobre la memoria utilizada):

$ convert *.jpg -limit area 300M resultado.pdf

Todas estas opciones de ImageMagick pueden ser variables de entorno: MAGICK_AREA_LIMIT, MAGICK_DISK_LIMIT, MAGICK_FILE_LIMIT, MAGICK_MEMORY_LIMIT, MAGICK_MAP_LIMIT, MAGICK_THREAD_LIMIT, MAGICK_TIME_LIMIT. Podemos hacer lo siguiente para ver que los cambios se aplican correctamente:

$ export MAGICK_AREA_LIMIT=50M
$ export MAGICK_MEMORY_LIMIT=10MiB
$ export MAGICK_MAP_LIMIT=30MiB
$ convert -list resource
File Area Memory Map Disk Thread Time
——————————————————————————-
768 50MB 10MiB 30MiB 18.446744EB 1 unlimited

Como habréis podido comprobar, también se puede limitar por tiempo, incluyendo -limit time [segundos] o con la variable de entorno MAGICK_TIME_LIMIT.

Pero no acaba aquí, podemos hacer que el procesado de imagen sea un poco más lento, pero nos deje el ordenador libre para otros usos, esto es con la variable de entorno MAGICK_THROTTLE, ImageMagick periodicamente dejará respirar el procesador tantos milisegundos como le hayamos asignado a la variable:

export MAGICK_THROTTLE=100

Dejará de procesar 100ms en varias ocasiones durante el proceso, lo podremos usar si vemos que el proceso será largo, no nos importa la velocidada y va a utilizar toda nuestra CPU.

También podemos acompañar todas estas opciones de ImageMagick con nice e ionice. Por ejemplo, con ionice podremos retrasar o priorizar los accesos a disco y con nice la prioridad del proceso. Si de verdad no nos importa cuánto tarde la conversión podemos hacer lo siguiente:

nice -n 20 ionice -c3 convert *.jpg -limit area 200M resultado.pdf

Con lo que asignaremos la menor prioridad al proceso, y además sólo accederá a disco cuando nadie más lo haga (si otro proceso quiere escribir en disco, convert tendrá que esperar)

Gráficos híbridos, Linux, la cabezonería de los fabricantes y el reinado de Microsoft

Miércoles, 16 de Marzo de 2011 Gaspar Fernández 6 comentarios

Desde hace años el diseño de hardware informático ha ido consumiendo más y más energía; cuando hace años, un ordenador funcionaba con una fuente de alimentación de 200W, hoy en día, es fácil encontrar hardware para el que se recomiendan 700W. Como es lógico, tal como están las cosas en cuestión energética y con el fin de hacer una informática más verde, los fabricantes se esmeran en buscar soluciones hardware y software que nos permitan hacer que nuestros equipos informáticos consuman menos electricidad.

Antes de nada decir que aunque Hybrid Graphics sea una tecnología de ATI, me referiré como gráficos híbridos a la coexistencia de dos sistemas gráficos en un mismo ordenador, poco a poco iremos matizando.

En el terreno sobremesa

En el terreno gráfico, es muy fácil ver una GPU con cerca de 2000 millones (dos mil millones) de transistores en su interior (este año saldrán modelos con 6000 millones de transistores), y aunque sólo estén en pleno funcionamiento durante la ejecución de juegos, contenido 3D o procesamiento GPGPU, los chips gráficos por sí solos tienen un consumo que va creciendo a medida que se complican los circuitos (sin contar la memoria asociada y la circuitería periférica). Existen tecnologías como el escalado de la frecuencia (la circuitería consume algo menos, los chips se calientan menos y ahorramos más energía en ventilación), o desactivación de algunas partes de la GPU, aunque cuando estamos realizando un trabajo con poca carga gráfica, es inevitable que mucha potencia se consuma por culpa de la GPU y no la estamos aprovechando.

Gracias a la inclusión de chips gráficos en placas base, a la reciente (desde primeros de 2009), inclusión de chips gráficos en procesadores Intel (este enlace es un ejemplo), y la nueva generación de APUs de AMD (AMD Fusion, que aunque llevan desde 2006 desarrollándolas acaban de salir), en el terreno energético, vemos que vamos a tener un chip gráfico asegurado, tal vez no sea lo más potente del mundo, pero nos permite poner imágenes en un monitor; así que, si no compramos una tarjeta gráfica, podremos utilizar esa GPU como gráfica, habrá una circuitería interna para generar una salida para monitor y podemos salir del paso, además, no consumirá demasiado. Ahora bien, si compramos una gráfica aparte, querremos utilizarla (normalmente tendrá una GPU más potente, más memoria y consumirá más), en este caso tendremos dos “tarjetas gráficas” trabajando a la vez y consumiendo energía.

La idea de la tarjeta gráfica integrada viene de lejos, recuerdo que en el año 97, se podía comprar un hardware similar, con un chip gráfico integrado en placa base; la diferencia de precio de modelos con y sin chip gráfico no era demasiada, por lo que no debemos esperar mucho de esa tarjeta. Eso sí, la placa base tenía su salida de monitor, y si pinchábamos una tarjeta, ésta tendría su salida aparte; también era una forma barata de poder conectar dos monitores, aunque como la mayoría de los mortales de la época trabajábamos con un monitor, si queríamos conectar una gráfica externa, era recomendable desactivar el hardware gráfico integrado en placa desde BIOS, por un lado, por problemas de compatibilidad y por otro, para no tener chips trabajando de forma innecesaria. (Aunque no recuerdo si se dejaban de alimentar los chips gráficos con esa configuración, no creo).

3dfx-voodoo-1Volviendo a la actualidad (por un momento) algo ha cambiado, y es que con la conciencia ecológica de los fabricantes, seguro que podemos dejar de alimentar los chips gráficos integrados, al menos gran parte de ellos. Pero si por ejemplo queremos dejar de lado el terreno energético podemos hacer que los chips gráficos trabajen en colaboración para una experiencia de usuario inigualable (no es más que procesamiento paralelo CPU+GPU+GPU). Todo esto, me hace sentir viejo, ya que me recuerda a la tarjeta Voodoo, esta tarjeta pionera en el furor del 3D, necesitaba una tarjeta gráfica adicional para todo lo que fuera 2D (la Voodoo tenía una salida y una entrada de monitor por fuera de la torre; la tarjeta gráfica 2D se conectaba con la Voodoo y ésta al monitor. Además, para algunos modelos posteriores permitía conectar dos tarjetas Voodoo con un interfaz interno para que éstas trabajaran en colaboración y trabajar 3D a más resolución (SLI, una idea de 1998 que, se abandonó y luego se volvió a poner en marcha en 2004/2005, en ATI se llamará la tecnología Crossfire).

En conclusión en este terreno la tecnología ha avanzado mucho; y normalmente con Linux puede que sólo haya una pequeña pega. Hablando de sobremesas, normalmente en la configuración de la BIOS encontramos opciones para desactivar la gráfica integrada (en placa base), desconozco si se podrá desactivar desde aquí cuando viene integrada en el procesador. Desde nuestro sistema operativo, depende de dónde conectemos el monitor, trabajaremos con una u otra gráfica, en Xorg configuramos con qué driver gráfico trabajar y con qué pantalla. El problema viene cuando queramos utilizar la potencia de las dos tarjetas, sólo a veces, es decir, cuando nos interese tirar de GPGPU sin importar el consumo energético, como tengo los dos chips gráficos activados, no hay problema, pero cuando termine de trabajar, sería muy efectivo poder dejar de trabajar con un chip y desactivarlo desde software, y este interruptor sólo está disponible en Windows. Aunque hay proyectos para ello, o si nos ponemos a jugar con ACPI podemos conseguirlo, los fabricantes no nos lo podrán fácil (estamos acostumbrados a ello, aunque [1]AMD lleva [2]liberando [3]especificaciones [4]unos [5]años) y así contribuyen a que Microsoft gane terreno en el campo energético (aunque podamos conseguir que un Linux sea más respetuoso con el sistema y el medio ambiente , no podremos lograr quitarle la corriente a un chip que se dedica a absorber potencia y producir calor, en algunos casos y cuando se logra, es necesaria una investigación previa y echar un día buscando por Internet.

En el terreno portátil

Casi todo lo explicado para la parte sobremesa nos vale aquí; aunque tenemos que pensar que un portátil pretende ser más eficiente energéticamente y de hecho necesitaremos que lo sea; personalmente cuando compré mi portátil (hace casi 5 años), logré extender las 2h y media de uso con batería en Windows a más de 4h y 30 minutos en GNU/Linux.

Y como tenía que ser, la inclusión de 2 GPUs en un mismo equipo portátil está presente desde el 2007 más o menos y siempre tendremos el caso de un chip malo (por así decirlo, es un chip barato, consume poco, pero también tiene pocas capacidades) y un chip bueno (un NVIDIA, un ATI con GPUs potentes). Aunque bueno, si nos compramos un portátil y no podemos desactivar una GPU, pues lo tenemos enchufado, o confiamos en que el fabricante saque algo para poder desactivarlo. En principio no sería un problema mayor.

Lo malo viene ahora, y es que en un portátil normalmente se economiza también el espacio y las conexiones, por lo que tendremos sólo una salida de pantalla y lo peor es que normalmente estará conectada a la gráfica “mala”, la integrada. Para un trabajo normal, no pasa nada, podemos  utilizar el ordenador perfectamente, pero siendo conscientes de que sólo podremos utilizar la gráfica menos potente y, aun teniendo una buena tarjeta gráfica al lado, para juegos, vídeo o tratamiento 3D, no podremos manejar la GPU más potente, vamos para todo lo que sea visualización, ya que al estar presente y conectada podemos aprovechar la potencia para GPGPU, pero sólo para eso, ya que si le decimos a Xorg que sólo utilice el chip gráfico “bueno” nos dirá que no tiene pantallas conectadas.

Ese es el gran problema, tenemos dos sistemas gráficos y una sola salida, y un conmutador software. Dado que los ordenadores portátiles no destacan por sus opciones en BIOS, estoy seguro al 90% que nuestro portátil con tecnología gráfica híbrida no tendrá la capacidad de desactivar por BIOS el sistema gráfico integrado, otra manera es con un interruptor hardware, es como la manera antigua y la manera que queda es con un driver y desde nuestro sistema operativo, vamos la forma modernita.

toshiba-a660-1emCuando tratamos este problema, mi primera toma de contacto con este tema fue al adquirir un portátil Toshiba A660-1EM. Dado que su sistema operativo principal era GNU/Linux me dispuse a su instalación, y pude comprobar rápidamente que después de una hora de uso (más o menos) con GNU/Linux se calentaba más que con Windows, y consumía más.

Este portátil trae una gráfica NVIDIA 33oM y la gráfica Intel que viene con el Core i5, los drivers de NVIDIA los instalé sin problema, por lo que supuse que todo iba bien hasta que comprobé qué controlador se estaba utilizando (bueno, también basta con arrancar nvidia-settings que te dice que no está funcionando). Fue cuando me puse a investigar sobre el tema. Además, este modelo trae una tecnología llamada Optimus que promete ser la panacea para el ahorro energético, es un controlador que cambia dinámicamente el sistema gráfico que se usa: si el ordenador piensa que necesitas potencia gráfica, conecta el chip gráfico bueno y si no, lo desconecta; sólo para Windows 7, y sin planes de dar soporte para Linux de esta tecnología, porque no les da la gana (dicen que en un futuro, pero si leéis los foros veréis que ponen a caldo a NVIDIA). Bueno, funciona en W7, y con software nuevo, hay quien ha reportado algún problema, muchos programas que no saben lo que es Optimus e identifiquen la salida gráfica activa, fallarán [1][2], incluso en el archicompatible Windows 7.

Es decir, la gráfica Intel funciona, la gráfica NVIDIA funciona pero no se ve, todo el sistema funciona perfectamente, y sólo falta la capacidad de un mísero sistema de conmutación entre la salida gráfica de la Intel a la NVIDIA.

Desde NVIDIA no dicen nada más, y no nos facilitan las cosas. Existen varios proyectos (que enlazo al final del post), hechos con ingeniería inversa y colaboración de muchos usuarios afectados para poder hacer que ese interruptor actúe y funciona en varios modelos de portátiles (aunque cada uno es de su fabricante y no es algo general y válido para todos); el método es algo artesano, requiere investigar un poco, además, se necesita el Kernel Mode Setting (KMS, más info), el gran problema es que los drivers oficiales de NVIDIA no soportan esta tecnología, y con una gráfica tan nueva, el driver nouveau, que sí soporta KMS, se queda un poco corto. Además, lo más fácil es desactivar la corriente de la GPU “buena” por lo que vale, no consume energía, pero me he gastado 200€ más en un portátil con una gráfica buena para no poder usarla, ya que muchas veces, si desactivamos el sistema gráfico integrado, el sistema deja de responder.

Por lo que, de momento, el hecho de comprar un portátil (para uso con GNU/Linux) con una tarjeta NVIDIA Optimus queda descartado, porque no vamos a poder usarla, aunque si lo que queremos es programar en CUDA, sí que vamos a poder. Aunque otro inconveniente que he encontrado en otros modelos, es que aunque no soportan Optimus, el conmutador que cambia la salida de la gráfica “buena” a la “mala” y viceversa es software y con un driver que no se encuentra en Linux (eché una mañana hablando con varios técnicos de Toshiba, sé que ellos sólo saben de Windows, pero al menos, saber si la gráfica se conmuta por software, por BIOS o por un interruptor sí que tienen que saberlo).

Con ATI la cosa va mejor, ya que Catalyst soporta KMS, y realiza la conmutación, y aunque no lo he probado hay mucha gente que lo ha conseguido, por ejemplo vemos información aquí, aunque el combo Intel/ATI suele funcionar, no lo hace el 100% de las veces, aunque hay mucho terreno recorrido, pero no del todo y de todas formas el modo colaborativo entre los dos chips gráficos es otra historia.

En conclusión

Lo realmente indignante, es que, aunque sea un sistema operativo minoritario (que no tanto), y aunque la culpa sea difícil de echar (NVIDIA? Intel? El fabricante de la placa base? El de la BIOS? Todos ellos?), no se haya desarrollado un estándar para esta conmutación en portátiles (al menos no lo he encontrado), o en su defecto, por parte de los fabricantes haberse desarrollado un parche para el kernel, que sabiendo cómo está hecho en pocos días de trabajo puede salir algo a la luz, eso les daría publicidad en muchos blogs/foros especializados y ganarían clientela; o al menos liberar las especificaciones de cómo lo han implementado.

Es una lástima perder el tiempo intentando lidiar con un problema parecido, aunque al menos en mi caso Toshiba perdió una venta (devolví el portátil), además, en el servicio técnico, me recomendaron que para mi problema podía comprar un Serie Qosmio (no recuerdo el modelo, pero cuando vi que costaba 1400€ cerré la página inmediatamente) y Asus también (porque estudié comprarme un portátil de esa marca), al final compré un sobremesa.

Para saber más

Linux Hybrid-Graphics . Tienen blog y una lista de correo en Launchpad.

ASUSM51Ta & Linux . Howto para este portátil con un combo ATI/ATI

airlied @ LiveJournal . David Airlie (de Red Hat) creó un módulo para el kernel que conmuta la energía para los chip GPU (vga_switcheroo)

VGA Switcheroo en Gentoo Wiki . A la manera Gentoo, mirando el kernel y paso a paso

Vídeo digital: Secuencias de imágenes

Jueves, 16 de Septiembre de 2010 Gaspar Fernández Sin comentarios

Esta vez voy a presentar algunos ejemplos de uso de ffmpeg con secuencias de imágenes. Para empezar a trabajar con vídeo digital desde GNU/Linux.

Crear vídeo a partir de una secuencia de imágenes

Es una buena técnica el hecho de trabajar con secuencias de imágenes para crear un vídeo. Podemos, por ejemplo utilizar la potencia de Imagemagick (I, II, III, IV) para modificar el color de la imagen, etiquetarlas o darle algún tratamiento. O incluso para manejar transparencias en vídeo de una forma controlada. Para las secuencias de imágenes es conveniente utilizar un formato de imagen sin pérdidas como png, pnm, o jpg sin pérdidas (ojo, no jpg normal).

Para hacer la conversión podemos utilizar esta orden:

$ ffmpeg -f image2 -i directorio/imag%d.png -r 25 -vcodec mpeg4 video.avi

Elegimos como entrada un formato de imágenes y las exportaremos a 25 fps, con el codec mpeg4 y el archivo se llamará video.avi. Todas las imágenes estarán dentro de directorio y se llamarán imag0.png, imag1.png, imag2.png, …

Siempre depende el codec que vayamos a utilizar, si queremos enviarlo por Internet, o grabarlo en algún soporte como montaje definitivo podemos utilizar el formato mpeg4, theora, h264, vp8, etc; si queremos grabarlo en DVD podemos escoger mpeg2, aunque si vamos a utilizarlo como parte de nuestro proceso de montaje podemos usar dv o algún codec sin pérdidas como ljpeg, jpegls, v210, etc; el objetivo, para montaje es utilizar un formato sin comprimir o comprimido sin pérdidas.

Creando un vídeo sólo con una imagen

En ocasiones, puede ser necesario crear un archivo de vídeo que sólo contenga una imagen. ¿ Por qué ? Podemos crear algún script que haga algún efecto con ese vídeo, una transición, o podemos unirlo a un vídeo, para hacer de cortinilla de inicio o cierre.

Para ello hacemos lo siguiente:

$ ffmpeg -loop_input -f image2 -i imagen.png -vframes 50 -r 10 -vcodec libtheora video.avi

Donde grabaremos 50 frames con la imagen imagen.png a 10 fotogramas por segundo y con el codec theora. Aunque, en lugar de especificar los fps podemos especificar el tiempo que queremos que dure (en hh:mm:ss.[xxx], es decir, horas, minutos, seguntos, centésimas):

$ ffmpeg -loop_input -f image2 -i imagen.png -t 00:00:5.50 -r 10 -vcodec libtheora video.avi

Donde grabaremos un vídeo de 5 segundos y medio con la misma imagen.

Pasando un vídeo a secuencia de imágenes

Ahora tratamos de hacer la primera conversión, de vídeo a imágenes, intentando escoger el codec adecuado. Aunque podemos utilizar jpg, vamos a exportar a png para dar más calidad a las imágenes:

$ ffmpeg -i video.avi -f image2 -vcodec png video/frame_%d.png

Grabaremos los distintos fotogramas del video (video.avi) en el directorio video y con archivos llamados frame_1.png, frame_2.png, frame_3.png…

Jugando con ImageMagick (IV): Automatizando procesos, creando animaciones

Martes, 14 de Septiembre de 2010 Gaspar Fernández 3 comentarios

El cuarto post de la serie, anteriormente hablábamos de:

  1. Dimensiones, Captura, Color y Efectos
  2. Color (continuación) y Rotación
  3. Jugando con ImageMagick (III): Colecciones, texto, y unión de efectos

Ya que estamos hartos de ver lo que es capaz de hacer ImageMagick, ahora mezclemos esto con la potencia de la consola, y tendremos una de las herramientas más potentes jamás inventadas en cuanto a imagen digital se refiere.

Modificando imágenes en un directorio

Aunque podremos hacer cualquier tipo de modificación, tal y como hemos visto anteriormente, haremos un ejemplo en el que redimensionaremos todos los archivos de un directorio al 50% (muy útil si preparamos en un directorio muchos archivos directamente de una cámara digital para subir a Internet):

$ mogrify -resize 50% directorio/*

Con mogrify podemos hacer lo mismo que con convert, sólo que el fichero de origen y de destino es el mismo.

Aunque… ¿y si queremos guardar los archivos originales? Tendremos que hacer un pequeño script para convertir los archivos de un directorio y guardarlos en otro direcorio diferente; pero… y si son muchos ? Tenemos algunas posibilidades:

$ for f in test/*.jpg; do convert -monitor -resize 50% $f “test2/”${f##*/}; done

Si tenemos todos los archivos en el directorio test, queremos redimensionar al 50% y guardarlos en test2/ con el mismo nombre que tienen. ${f##*/} elimina el directorio del nombre del archivo, es lo mismo que la orden basename. Y con el parámetro -monitor veremos más o menos lo que está haciendo convert en cada momento.

Aunque, tal vez queramos un indicador de progreso para saber más o menos cuánto queda y cuántos archivos llevamos, lo podemos hacer con bc y Xdialog:

1
2
3
4
5
6
7
8
9
archivos=`ls test/*.jpg`;
total=`echo $archivos | wc -w`;
hecho=0;
for f in $archivos;
do
convert -resize 50% $f "test2/"${f##*/};
let hecho=$hecho+1;
echo "scale=0;$hecho*100/$total"|bc;
done | Xdialog --gauge "Progreso..." 10 100 0

En este ejemplo, separamos en variables los archivos a tratar y contamos el total de archivos a procesar. La variable hecho contará cuántos archivos ha convertido hasta el momento.

Luego en el bucle principal convertiremos los archivos e iremos incrementando la variable hecho en 1. Más adelante, con la ayuda de bc calculamos el porcentaje hecho. El bucle lo pasamos con una pipe a Xdialog, con su opción de gauge con lo que iremos indicando el proceso a medida que se vayan convirtiendo archivos.

Añadiendo un texto a todas las imágenes

Podemos, además, añadir un texto a todas las imágenes con un formato determinado para incluir el nombre de fichero, ancho, alto, la etiqueta de fichero, etc:

$ mogrify -gravity South -pointsize 20 -fill black -annotate ‘%f %b bytes” *

Con lo que anotaremos dentro de la imagen en color negro el nombre del archivo y el tamaño en bytes. Para esto tenemos algunas palabras clave como %f y %b en este enlace: Imagemagick.org (Identify -format).

hamburguesonAunque tal vez queramos poner un texto diferente a cada foto. Imaginemos que tenemos muchos ficheros jpg y muchos ficheros txt. Los ficheros txt tienen el mismo nombre que los jpg y sólo varía la extensión; y queremos plasmar el texto de los txt en los ficheros jpg:

1
2
3
4
5
6
7
8
9
10
11
for f in *.jpg;
do
if [ -r ${f%.*}.txt ];
then
txt=`cat ${f%.*}.txt`;
else
txt="Mis guisos 2010";
fi;
echo $txt en $f;
mogrify -gravity North -pointsize 15 -fill white -annotate 0x0+10+10 "$txt" $f;
done

Esta vez, si encontramos el fichero de texto con el mismo nombre que la imagen, solo que con extension txt escribiremos ese texto en la parte superior de la imagen; pero si no, escribiremos “Mis guisos 2010″ y así recorriendo todos los archivos jpg del directorio.

Una animación sencilla

destinVamos a crear una transición entre dos imágenes. Y para el ejemplo, hemos utilizado estas dos imágenes:

$ convert -size 720×576 xc:black -gravity Center -fill white -pointsize 250 -font impact -draw ‘text 0 0 A’ a.jpg

$ convert -size 720×576 xc:black -gravity Center -fill white -pointsize 250 -font impact -draw ‘text 0 0 B’ b.jpg

Para realizar el fundido hacemos lo siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
n_imgs=30; # Número de imágenes
s=`echo "scale=2;100/$n_imgs" | bc` # Porcentaje de inremento de cada paso.
o=0;   # Visibilidad de la imagen B
d=100; # Visibilidad de la imagen A
f=0;   # Fotograma actual
while (( $f < 20 ));
do
convert -compose blend -set "option:compose:args" $o,$d a.jpg b.jpg -composite dest/anim_$f.jpg;
o=`echo "scale=2;$o+$s" | bc`;
d=`echo "scale=2;$d-$s" | bc`;
f=$(($f+1));
echo "Frame: $f O=$o D=$d";
done

Con esto se creará la secuencia de $n_imgs (que al principio le damos valor 30) imágenes en el directorio dest/; todas empezando por anim_.

Si queremos crear un gif animado con esto, podemos hacer lo siguiente:

$ convert dest/anim_{0..29}.jpg trans.gif

Jugando con ImageMagick (III): Colecciones, texto, y unión de efectos

Lunes, 6 de Septiembre de 2010 Gaspar Fernández Sin comentarios

El tercer post de la serie, anteriormente hablábamos de:

  1. Dimensiones, Captura, Color y Efectos
  2. Color (continuación) y Rotación

Juntando imágenes en una sola

Ahora, la cosa se anima, veremos cómo recopilar varias imágenes en el mismo archivo de imagen; habréis visto algún ejemplo en la entrega II, en los que muestro varias imágenes juntas:

variasPara ello usamos montage:

$ montage -tile 4×2 -geometry 200×160+1+0 taza1.jpg taza2.jpg taza3.jpg taza4.jpg hamburgueson1.jpg hamburgueson2.jpg hamburgueson3.jpg hamburgueson4.jpg varias.jpg

Donde, con el parámetro tile, especificamos la agrupación de las imágenes ancho x alto (4×2 en este caso) y con geometry, el tamaño de cada imagen 200×160 de máximo, con una separación de 1 pixel a los lados y ninguno verticalmente.

La imagen conserva su aspecto, pero de alto ocupa 160 pixels por lo que existe una pequeña separación.

Añadiendo texto

outSin imagen original, simplemente un texto en un archivo de imagen. Obtenido de la siguiente forma:

$ convert -background black -fill red -gravity center -font Verdana -pointsize 20 -size 200×80 caption:’Rojo sobre negro’ rojosobrenegro.png

Donde:

  • -background especifica el color de fondo
  • -fill especifica el color de primer plano
  • -gravity es la alineación, centrada, tanto horizontal como verticalmente.
  • -font indica el tipo de letra
  • -pointsize indica el tamaño de la letra
  • -size indica el tamaño de la imagen (porque no vamos a utilizar ninguna imagen de origen).
  • caption:’Texto’ con ello indicamos el texto

out1

$ convert -size 300×120 xc:rgb\(50,50,70\) -fill rgb\(90,150,200\) -gravity SouthEast -font helvetica -pointsize 25 -draw ‘text 10 2 “Poesía Binaria”‘ poesia_binaria.jpg

Donde incluimos el texto en una determinada posición: 10×2 desde la esquina inferior derecha (SouthEast), tipo de letra helvetica y tamaño 25; de fondo (50,50,70) y de color (90,150,200).

out2Ahora, aprovecharemos un poco más las capacidades de la orden draw. Para ello, dibujaremos un cuadro en negro dentro de la imagen (antena.jpg de dimensiones 314×300) a modo de marco (verde); luego trazaremos una línea horizontal de color blanco (rojo) en el borde del cuadro que acabamos de dibujar y tras ello escribiremos un texto (azul).

$ convert antena_2.jpg -gravity SouthEast -font helvetica -pointsize 25 -fill black -draw ‘rectangle 0,270 314,300′ -fill white -draw ‘line 0,270 314,270′ -draw ‘text 13 1 “Mi antena Wifi”‘ out.jpg

out3Ahora introduciremos el texto directamente en la imagen, pero para facilitar la lectura incluiremos una sobra en el texto.

$ convert antena_2.jpg -gravity North -font helvetica -pointsize 25 -fill black -draw ‘text 0 0 “Mi antena Wifi”‘ -fill white -draw ‘text 1 1 “Mi antena Wifi”‘ out.jpg

Podemos incluir de forma opcional -blur 1×1 (por ejemplo) para difumirar el texto que hace de sombra y suavizarla.

Juntando los efectos disponibles

Uno de los mejores ejemplos es el siguiente: http://www.imagemagick.org/Usage/thumbnails/ aunque encontramos cientos de webs con efectos preparados para ImageMagick:

Jugando con ImageMagick (II): Color y rotación

Miércoles, 1 de Septiembre de 2010 Gaspar Fernández Sin comentarios

Sigo con la serie de posts sobre ImageMagick, anteriormente estuvimos viendo cómo podemos redimensionar, añadir y quitar bordes a la imagen, cambiar y ecualizar el espacio de color, añadir efectos y capturar de la pantalla. Ahora veremos más cosas relacionadas con el color:

Tocando los canales de color

hamburgueson_33Imagina que queremos aplicar un efecto sólo en un canal, por ejemplo, un efecto radial-blur sólo en el canal rojo:

$ convert -channel red -radial-blur 30 hamburgueson.jpg hamburgueson_rojo.jpg

Donde 30 es el radio del emborronamiento (blur) radial.

Pero por ejemplo, si queremos aumentar el nivel de rojo, verde, o azul (o de los tres valores) de una imagen, podemos modificar los niveles de blanco y negro de la propia imagen.

tazasPara el ejemplo superior:

$ convert -level 30,100% taza.jpg taza_oscura.jpg

$ convert -channel blue -level 0,50% taza.jpg taza_azul.jpg

$ convert -channel red -level 30,80% taza.jpg taza_arojo.jpg

De izquierda a derecha.

Podemos también obtener la imagen a dos colores (blanco y negro), obtenido desde un valor umbral (valores inferiores, se representarán con negro y superiores con blanco), aunque, como veremos en el ejemplo, también podemos filtrar según el canal:

tazas1Para este ejemplo, hice lo siguiente:

$ convert -threshold 25% taza1.jpg tazaBN.jpg

$ convert -channel red,blue -threshold 55% taza.jpg taza_naranja_verde.jpg

$ convert -channel green -threshold 75% taza_magenta.jpg

Más efectos de color

taza_3Para conseguir el tono sepia hacemos lo siguiente:

$ convert -sepia-tone [umbral] origen destino

En el ejemplo hice lo siguiente:

$ convert -sepia-tone 90% taza.jpg taza_sepia.jpg

También disponemos del efecto posterizado (si no se aprecia bien en la miniatura, hacer click para ver en grande). Para conseguir el efecto hacemos lo siguiente:

taza_31

$ convert -posterize 4 taza.jpg taza_poster.jpg

Donde 4 es el número de niveles con el que vamos a posterizar.

También tenemos el efecto solarizado con el siguiente comando:

$ convert -solarize 2% taza.jpg taza_sol.jpg

taza_32Donde el 2% es el umbral deseado para el efecto, que vemos en la siguiente imagen.

Para completar los efectos de color, veamos también cómo podemos cambiar brillo, saturación y tono. Para controlarlo tenemos la orden:

$ convert -modulate [brillo],[saturacion],[tono] origen destino

Vemos en el siguiente ejemplo las imágenes con los efectos uno a uno:

tazas2

# En la primera se ha modificado el tono de la imagen:

$ convert -modulate 100,100,142 taza.jpg taza_hue.jpg

# En la segunda se modificó la saturación

$ convert -modulate 100,142,100 taza.jpg taza_sat.jpg

# En la tercera se cambió el brillo:

$ convert -modulate 142,100,100 taza.jpg taza_brillo.jpg

Todos estos parámetros se indican en porcentaje.

Rotación y transposición

Además de estos efectos de color, encontramos también algunas transformaciones de imagen

tazas3

$ convert -flip taza.jpg taza1.jpg

$ convert -flop taza.jpg taza2.jpg

$ convert -transpose taza.jpg taza3.jpg

$ convert -transverse taza.jpg taza4.jpg

taza_2

Para la rotación de la imagen ejecutamos lo siguiente:

$ convert -rotate 40 taza.jpg taza_r.jpg

Donde 40 es la cantidad de grados a rotar.

taza_33Para la rotación hay otra orden muy curiosa: polaroid. La podemos utilizar de la siguiente manera:

$ convert -polaroid 40 taza.jpg taza_p.jpg

Jugando con ImageMagick (I): Dimensiones, captura, color y efectos

Jueves, 26 de Agosto de 2010 Gaspar Fernández Sin comentarios

A menudo es necesario hacer una manipulación básica de imágenes y da mucha pereza ejecutar GIMP u otro editor de imágenes para una tontería; e incluso a veces necesitamos modificar gran cantidad de imágenes y necesitamos automatizar el proceso:

Ejecución

Aunque ImageMagick, que seguro que lo encontráis en los repositorios de vuestra distribución favorita, da mucho más de sí, aquí veremos ejemplos con convert, import y mogrify

Redimensionado de imágenes

hamburgueson_2$ convert -resize [dimensión/porcentaje] origen destino

Por ejemplo para redimensionar con un ancho de 320 pixels:

$ convert -resize 320 hamburgueson.jpg hamburgueson_mini.jpg

De esta forma, si especificamos la altura, se ignorará, ya que convert intentará mantener el aspecto de la imagen.

También podemos imponer la altura y que se calcule automáticamente el ancho:

$ convert -resize x500 hamburgueson.jpg hamburgueson_mini.jpg

O si queremos, podemos también redimensionar con un porcentaje del tamaño original:

$ convert -resize 40% hamburgueson.jpg hamburgueson_mini.jpg

hamburgueson_21También es posible la redimensión sin mantener el aspecto (relación ancho/alto) de la siguiente forma:

$ convert -resize \!600×300 hamburgueson.jpg hamburgueson_deforme.jpg

Y esto mismo, también por porcentaje:

$ convert -resize \!100×30% hamburgueson.jpg hamburgueson_deforme.jpg

Capturando el escritorio

Puede que nuestro entorno preferido de escritorio no venga con esta funcionalidad, o incluso que estemos desde una máquina remota y queramos ver lo que pasa en el escritorio, una captura de pantalla no viene mal. Para ello podemos hacer lo siguiente:

screenshot-26-08-2010-100842

$ import -window root captura.jpg

O si queremos capturar una ventana en especial:

$ import ventana.jpg

Nos aparecerá un puntero especial que nos permitirá seleccionar la ventana a capturar.

O si queremos capturar una ventana en especial sin necesidad de hacer click (muy útil si estamos en un equipo remoto):

$ import -window “Titulo de la ventana” ventana.jpg

También podemos sacar el ID de la ventana con:

$ wmctrl -l

Y poner en lugar del título, el ID. Es necesario que nos encontremos en el mismo escritorio de la ventana para hacer la captura. Cómo podemos hacer eso remotamente ?

$ wmctrl -l # Nos dirá en la segunda columna el escritorio donde está la ventana

$ wmctrl -s [numero] # Saltaremos al escritorio [numero], el primero es el cero.

Espacios de color

Podemos cambiar el formato del color de forma rápida usando colorspaces, dependiendo del formato de salida y la forma en la que la imagen será utilizada, para vídeo, por ejemplo. Aunque también tenemos algunos espacios interesantes como:hamburgueson_3

$ convert -colorspace gray hamburgueson.jpg hamburgueson_gris.jpg

El tono de gris estará calculado para adecuarse al ojo humano: Gris = 0.299*Rojo+0.587*Verde+0.114*Azul

Aunque también podremos transformar a YUV, XYZ, LAB, HSL, etc; también necesitamos que el formato de salida sea compatible con esos espacios de color. Para ver una lista de todos los colorspaces disponibles:

$ covert -list colorspace

hamburgueson_31También podemos ecualizar la imagen con respecto a los diferentes espacios de color de la siguiente forma:

$ convert -colorspace [espacio] -equalize origen destino

En el ejemplo:

$ convert -colorspace hsl -equalice hamburgueson.jpg hamburgueson_hsl.jpg

Y si no queremos decir el colorspace, usaremos el actual de la imagen:

$ convert -equalize hamburgueson.jpg hamburgueson_e.jpg

Recortar imágenes

Es más cómodo hacerlo con el ratón, pero en ocasiones querremos hamburgueson_4automatizar el proceso, y podemos hacerlo de la siguiente forma:

$ convert -crop [ancho]x[alto]+[x]+[y]

Por ejemplo lo siguiente:

$ convert -crop 300×300+100+100

Creará una imagen de 300×300 y empezará a partir del punto 100×100 (desde la izquierda/arriba).

Bordes

hamburgueson_41Para añadir un borde podemos hacer lo siguiente:

$ convert -bordercolor [color] -border [ancho]x[alto] origen destino

En el ejemplo tenemos:

$ convert -bordercolor black -border 10×10 hamburgueson.jpg hamburgueson_borde.jpg

Para especificar el color podemos hacerlo de varias formas:

$ convert -bordercolor black/red/green/blue… # Por su nombre. Si queremos saber los nombres de color disponibles:

$ convert -list color

$ convert -bordercolor “#aacc11″ # Por su equivalente hexadecimal

$ convert -bordercolor “rgb(100,150,200)” # En función de sus valores RGB

$ convert -bordercolor “hsl(100,150,200)” # En función de sus valores HSL

$convert -bordercolor “cmyk(100,200,150,230)” # En función de sus valores CMYK

… etcétera… tantos formatos como espacios de color.

Ahora bien, queremos quitar el reborde añadido:

$ convert -trim hamburgueson_borde.jpg hamburgueson_nuevo.jpg

Pero es posible que por la compresión jpeg no se detecte bien el borde (es una compresión con pérdida de calidad, y se modifica la imagen; para nosotros el borde es negro, pero para el ordenador hay muchos tonos de negro), entonces podemos hacer lo siguiente:

$ convert -fuzz 10% -trim hamburgueson_borde.jpg hamburgueson_nuevo.jpg

Con esto damos una tolerancia de un 10% al color, es decir, si se parecen los tonos de negro en menos de un 10% serán considerados iguales.

hamburgueson_42También podemos añadir un biselado como el del ejemplo de la siguiente manera:

$ convert -mattecolor red -frame 20×20+10+10 hamburgueson.jpg hamburgueson_rojo.jpg

Filtros y efectos

hamburgueson_32Por si fuera poco, podemos aplicar los filtros típicos a las imágenes como blur, motion-blur, blur gaussiano (gaussian-blur), ruido (noise), carboncillo (charcoal).

En el ejemplo, se ha añadido motion-blur de la siguiente forma:

$ convert -motion-blur 10×40+10+0 hamburgueson.jpg hamburgueson_movido.jpg

Historia de Lenna

Viernes, 19 de Marzo de 2010 Gaspar Fernández Sin comentarios

lenna_mainEste post lo he rescatado de un antiguo blog que tenía allá por 2007, y es que en la Universidad estuve estudiando una asignatura, Tratamiento Digital de Imagen y había una foto que se repetía hasta la saciedad.

Todo se remonta a Julio del 1973 cuando en el Instituto de Procesamiento de Señal e Imagen del USC (California) estaban buscando una imagen para una conferencia. La imagen debía tener un gran margen dinámico. Estaban pensando en una cara, y por supuesto, qué mejor que sacarla de la revista Playboy… y como eran tontillos… Playmate de Noviembre del 1972, no, si la muchacha es guapa, aunque en la foto tenía 21 años. Y la foto no está entera, como os podéis imaginar… pero si queréis os dejo unos enlaces al final :)

Tras la conferencia mucha gente estuvo interesada en la foto, para sus investigaciones con filtros y compresión de imagen. imaginaos que sin Lenna, el JPEG no sería lo que conocemos actualmente; y bueno, que había pocas chicas en la investigación de imagen digital, todo sea dicho.

Con respecto al nombre, es Lena Söderberg, de origen sueco; pero como siempre la manía de cambiar los nombres, en la revista se llamba Lenna Sjööblom (con dos N para que los anglosajones lo pronunciaran bien). Fue el número más vendido de la historia de la revista. Aquí tenéis la ficha de Lenna.

La imagen de Lenna se ha convertido con los años en un estándar de facto de  imagen de prueba de miles de algoritmos relacionados con este campo y muy importante para la comunidad científica, tanto es así que hasta Playboy autorizó su publicación en estos círculos (normal ellos también han terminado utilizando la tecnología desarrollada por ese hecho), no denunciando ni a la revista Optical Engineering(01/1992) ni a IEEE Transactions on Image Processing (1996), ya que la foto tiene derechos. David C. Munson, editor de ésta última reista escribió una nota explicando las razones de por qué se utiliza la foto de Lenna. Más o menos viene a decir dos razones:

* Es una buena imagen de prueba, tiene regiones planas, sombras y texturas lo que es bueno para probar algoritmos de procesamiento de imágenes.

* Segundo, es una chica atractiva, y es normal que esta comunidad de investigación (casi todo hombres) giren en torno a una imagen que encuentran atractiva.

Además la imagen se ha utilizado en multitud de libros para demostrar ciertos algoritmos. Por ejemplo el que estoy leyendo ahora para la asignatura Digital Image Processing de Rafael C. Gonzalez y Richard E. Woods (muy gordo por cierto).

Ahora tenemos la otra cara de la moneda, la cara de un mundo que se empeña en criticar todo lo que se ha creado, porque es incorrecto, les parece mal. A ciertas personas les molesta que sea una mujer la que esté posando, pero les molesta aún más que provenga de una portada de Playboy, al menos está recortada, les molesta que haya salido en revistas, en libros, en miles de pruebas del desarrollo de JPEG.

Lo mejor de todo es que hasta el 1988 ella no se enteró de la repercusión que tenía, hasta que la entrevistaron de una revista de informática sueca. Y en mayo de 1997, fue invitada a la la 50th Annual Conference of the Society for Imaging Science in Technology, como parte de de la historia de la imagen digital. Y bueno, casi casi pudo montar un club de fans, todo el mundo pidiéndole autógrafos, yo creo que le hicieron más caso a ella que a todo lo demás… tantas horas delante de un ordenador mirándola fijamente, unen mucho :) Y una de sus frases fue: deben estar tan cansados de mí … ¡mirando la misma foto por todos estos años!

lenna_oldHay muy poca información sobre ella actualmente. Está casada, tiene tres hijos y trabaja para el estado. Cuando la invitaron para la conferencia que he citado antes trabajaba ayudando a discapacitados a trabajar con ordenadores.

Por cierto, el póster también sale en la película El dormilón (Original: Sleeper) de Woody Allen (1973). Lenna en Sleeper.

Aquí os dejo unos cuántos enlaces si queréis más información:

May 2001 Newsletter of the IEEE Professional Communication Society (PDF)
La Historia de Lenna
Lenna - Wikipedia
The Rest of The Lenna Story

Visita otras webs de la red