Está en la página 1de 4

Python DESARROLLO

Imgenes satlite en Python

VIGILANTES DEL PLANETA


Quin no ha querido alguna vez sentirse como esos informticos de la NASA en su centro de control? Hoy nos construiremos el nuestro y controlaremos el planeta y sus alrededores. POR JOS MARA RUIZ Y PEDRO ORANTES

ada vez que vemos el lanzamiento de un cohete todos quedamos asombrados ante la explosin del despegue, la atenta mirada de todos esos cientficos a los paneles de control, y la monstruosa cifra que nos dicen que se han gastado en el proyecto.

A donde van los impuestos?


Es entonces cuando surge la pregunta y eso a m en qu me repercute? Un da estando en el despacho de la Rama del IEEE de Mlaga tuve una conversacin en la que me contaron que la mayor parte de los satlites emiten al mundo las imgenes y los datos que recogen. Es decir, si se posee el equipo necesario es posible recibir en tu propia casa imgenes fascinantes del universo, de Marte o de la Tierra.

La temperatura del ocano, imgenes meteorolgicas, imgenes del campo magntico del sol o de las misiones a Marte son enviadas constantemente a la Tierra desde estos engendros espaciales. Y el efecto es siempre el mismo, el espectador es deslumbrado por el presentador de televisin con una imgenes increbles mientras se escuchan acordes de sintetizador. Acaso no son esas imgenes de dominio pblico? Dnde puedo conseguirlas? En el presente artculo utilizaremos Python para crear un script CGI que nos permita recoger y mantener actualizadas las imgenes que queremos en una especie de collage o mural. Construiremos nuestro propio centro de control espacial.

Recoger las imgenes


Lo primero ser encontrar las imgenes y reunirlas. Vamos a usar como ejemplo cuatro imgenes de carcter cientfico. Se actualizan a distintos intervalos, de manera que podremos ver cmo evolu-

Curiosidad
Poco tiempo despus de finalizar este artculo apareci una noticia en Slashdot (ver Recursos [4]) hablando de una llamarada solar de tal tamao que iba a alterar las comunicaciones. Cuando se dan este tipo de eventos en muchos centros de control de satlites los ingenieros cruzan los dedos para que sus satlites no caigan ante la ola de viento solar que se origina. El lector puede apreciar la llamarada en la Figura 4.

WWW.LINUX- MAGAZINE.ES

Nmero 10

61

DESARROLLO Python

En la variable c almacenamos el objeto que representa la conexin realizada y podemos enviar peticiones.
>>> c.request("GET","/issue/08") >>>

Figura 1: La imagen original que vamoa a modificar con PIL.

cionan las eventos que se registran. Puedes encontrar las URLs en Recursos [1]. Debemos descargar las imgenes y almacenarlas dentro de nuestro programa, haremos uso de la librera httplib que es parte de la distribucin estndar de Python. Esta librera nos permitir hablar de t a t con un servidor web remoto sin tener que preocuparnos de los detalles de ms bajo nivel. Esta conversacin la realizaremos usando el protocolo HTTP. Este protocolo es bastante simple y de l slo necesitaremos una parte mnima. Cuando Tim Berners Lee realiz el diseo original de la Web quiso que el protocolo para pedir los documentos fuese lo ms simple posible. HTTP se reduce a la recepcin y el envo de informacin al servidor, eso y slo eso. Se compone de varios comandos, pero los ms conocidos son GET, que podemos traducir como tomar, y POST, que podemos traducir en este contexto como enviar o mandar. As que tomamos documentos y enviamos informacin. Una parte importante de HTTP es URL que nos sirve para darle nombre a esos documentos. Todos estamos acostumbrados a tratar con urls, generalmente del tipo http://www.linux-magazine.es/ issue/08. La url se compone de: [protocolo]://[maquina]/[ruta]/[objeto]. Vamos a ver ahora porqu es tan importante que sepamos esto. La librera httplib de Python establece en un primer paso una conexin con el servidor remoto mediante el mtodo HTTPConnection
>>> c = httplib.HTTPConnectionU ("www.linux-magazine.es") >>>

Usamos el comando GET, con lo que estamos solicitando un objeto. El segundo parmetro del mtodo es la ruta hasta el objeto. As que la URL que estamos solicitando es http://www. linux-magazine.es/index.html. Es importante que la ruta comience con una barra /, como si fuese la ruta de un fichero de una mquina. Cmo sabemos si todo ha ido bien?
>>> r = c.getresponse() >>> print r.status,r.reason 200 OK >>>

Figura 2: La imagen del pequeo demonio de BSD rotado 45 con PIL.

>>> c.close() >>>

Para obtener las imgenes vamos a hacer exactamente lo mismo, abriremos una conexin, pediremos la imagen, la almacenaremos en una diccionario y cerraremos la conexin.

Con getresponse podemos conseguir un objeto que representa los datos devueltos por la conexin. Este objeto tiene, entre otros, los atributos status y reason que nos indican el estado, un nmero con un significado especial, y la explicacin del mismo. En este caso todo ha ido bien y por eso recibimos un OK. En caso contrario, si no existiese la ruta que pedimos habramos obtenido:
>>> r = c.getresponse() >>> print r.status, r.reason 400 Bad Request >>>

Python Imaging Library


Nuestra idea original era realizar un mural o collage con las imgenes recuperadas. Python no nos provee de una librera de tratamiento grfico en su distribucin estndar. Eso no quiere decir que no exista tal librera, y no slo existe, sino que adems es muy potente y til. Nos referimos a Python Imaging Library (ver URL [2] en el Listado de Recursos al final del artculo). La librera PIL (Python Imaging Library) nos va a permitir tratar imgenes en una gran cantidad de formatos. Podremos convertirlas a otro formato, rotarlas, escalarlas, mezclarlas, etc. Aquel lector que haya tenido contacto con programas de manipulacin grfica, como por ejemplo GIMP (ver URL [3] en el Listado Recursos), comprender la potencia de una librera con estas funcionalidades.

Ahora ya tenemos la pgina, solo tenemos que leerla, usando el mtodo read() del objeto respuesta.
>>> print r.read() <html> <head> <base href="http://www.U linux-magazine.es/issue/08/" /> <title>Linux Magazine -U Spamassasin, Hypermail,U Encriptacin GPG, SDL,U ...

Listado 1: Ejemplo de uso de PIL


01 >>>mural = Image.new('RGB',(600,480)) 02 >>> im = Image.open("daemon.jpg") 03 >>> im.thumbnail((300,200), Image.ANTIALIAS) 04 >>> mural.paste(im,(0,0)) 05 >>> mural.paste(im,(300,0)) 06 >>> mural.show() 07 >>>

Cuando hayamos finalizado debemos cerrar la conexin invocando el mtodo close() del objeto que representa la conexin, en este caso sera:

62

Nmero 10

WWW.LINUX- MAGAZINE.ES

Python DESARROLLO

Figura 3: Creamos una imagen vaca con PIL y despus colocamos otras imgenes en su interior como mosaico.

Como no viene de serie con Python deberemos instalarla en nuestra distribucin o sistema operativo. Existen paquetes RPM y DEB de la misma. Cmo se trabaja con PIL? Pues mediante la manipulacin de objetos de la clase Image. Esta clase es capaz de albergar imgenes de casi cualquier formato, permitindonos manipularlas. Vemos un ejemplo. En la Figura 1 podemos ver la imagen original del fichero daemon.jpg en mi equipo. Vamos a rotarla 45 grados:
>>> import Image >>> im = Image.openU ("daemon.jpg") >>> img.rotate(45).show() >>>

en el resultado hemos invocado el mtodo show() que mostrar el resultado mediante el programa xv (para cerrar xv solo tenemos que pulsar q). Nosotros no buscamos rotar imgenes, sino escalarlas. Las imgenes presentes en la web suelen ser de gran tamao y nosotros queremos crear un mural de un tamao esttico. Tendremos que adaptar las imgenes descargadas para que quepan en el mural. Para hacerlo vamos a insertar las imgenes en una mayor, pero hay muchas maneras de hacer esto. La solucin que adaptaremos en nuestro caso es la de dividir la imagen-mural en tantos recuadros como imgenes vayamos a insertar. Cmo sabremos la cantidad de cuadrculas? Pues escogeremos la menor potencia de 2 que sea mayor que nuestro nmero de imgenes. No es muy complicado, por ejemplo, si tenemos 7 imgenes, 8 (2 elevado a 3) ser suficiente. Bsicamente multiplicaremos 2 por s mismo hasta que sea mayor que el nmero de imgenes que queramos mostrar. Grficamente lo que haremos ser ir dividiendo en anchura y en altura la imagen en cuadrculas, en cada iteracin se multiplicar por 2 el nmero de cuadrculas. Con este mtodo perderemos espacio en la imagen, pero al ser tan sencillo no complicar mucho el cdigo.

Figura 4: Llamaradas solares que amenazan con dejar fuera de combate a los satlites de comunicadciones.

300x200 pixels. Puede aceptar un parmetro adicional, en nuestro caso es Image.ANTIALIAS que debera mejorar la resolucin de la nueva imagen. A continuacin usamos el mtodo paste() de Image que nos permite pegar una imagen dentro de otra en las coordenadas indicadas como segundo parmetro. Pegamos la imagen daemon dos veces, la primera en la posicin (0,0) del mural y la segunda en la posicin (300,0). Podemos ver el resultado usando el mtodo show().

El fichero de configuracin
Las URLs y la resolucin deben ser recogidas por el programa, pero cmo? Existen varias opciones, podramos pasrselas al programa cuando se ejecute. Las URLs tienen el problema de ser bastante largas en ocasiones, as que la linea de comando para ejecutar el programa puede ser engorrosa. En lugar de eso vamos a usar un fichero de configuracin. Cada vez que el programa se ejecute leer este fichero y recoger los parmetros oportunos. Qu forma tendr el fichero? La ltima tendencia es crear ficheros XML de configuracin. Pero el XML puede ser demasiado complicado si tenemos en cuenta que nuestro fichero de configuracin puede no tener ms de 10 lneas. En UNIX la tendencia es la de usar el formato de clave = valor y ese es el que usaremos. El fichero ser como el que se muestra en el Listado 2. Leeremos cada lnea del fichero, la dividiremos usando el = y usaremos la primera parte como clave en un diccionario, y la segunda como valor. Si ya existe la clave, usaremos una lista como valor con

En la Figura 2 podemos ver el resultado. Hemos usado el mtodo rotate() al que hemos pasado un ngulo de 45 grados, y

Creemos el thumbnail
Primero creemos una imagen vaca, ver Listado 1. La Figura 3 muestra el resultado. Esta vez no cargamos ninguna imagen, sino que usamos el mtodo new() que necesita el tipo de pixel (RGB viene de Red->Rojo Green->Verde Blue>Azul, es uno de los formatos estndar) y el tamao de la imagen medido en pixels. En nuestro caso hemos escogido 600 pixels de ancho por 480 de alto (presta atencin a los (), porque la resolucin se expresa como una secuencia del tipo (x,y) ). Esta nueva imagen no contiene nada a excepcin de un decepcionante fondo negro. Vamos a poner algo de color! Cogemos la imagen del daemon e invocamos el mtodo thumbnail() que escala la imagen tanto vertical como horizontalmente. Tenemos que pasarle el tamao deseado como una secuencia, la nueva imagen tendr un tamao de

Listado 2: collage.conf
01 02 03 04 05 06 [tamao] horizontal = 800 vertical = 600

[imgenes] url1 = http://www-mgcm.arc.nasa.gov/M arsToday/marstoday.gif 07 url2 = http://www.sec.noaa.gov/sxi/cu rrent_sxi_4MKcorona.png 08 url3 = http://www.ssec.wisc.edu/data/ sst/latest_sst.gif 09 url4 = http://www.wetterzentrale.de/pics/D2u.jpg

WWW.LINUX- MAGAZINE.ES

Nmero 10

63

DESARROLLO Python

sobre el collage, de manera los distintos valores como que sea posible pulsar sobre entrada. Pero por qu vamos las distintas imgenes que en a realizar nosotros el trabajo l aparecen. Al hacerlo se carduro cuando alguien ya lo ha gar la imagen a tamao naturesuelto? ral. El mapa se genera recoPython trae en su distriburriendo el diccionario de imcin estndar una librera que genes. Cada entrada del dicnos ser de enorme utilidad. cionario contiene un objeto de Alguien consider oportuno la clase Imagen. elaborar un analizador de Imagen alberga la informaarchivos de configuracin, se cin de cada imagen descarllama ConfigParser. Con ella gada mientras el programa la podemos extraer la informaalmacena. Se almacenan los cin del archivo de configuradatos propios de cada imacin. gen, como por ejemplo las El archivo de configuracin coordenadas que ocupar se compone de Secciones y Figura 5: Nuestro panel de control espacial terminado y colocado en finalmente en el collage. Opciones. Cada seccin conuna pgina web generada dinmicamente. Como siempre, se espera tiene varias opciones, y los que el lector dedique algo de tiempo a nombres de las secciones y opciones Cuando un mtodo comienza con __ jugar con el programa para adaptarlo a deben ser nicos. Por eso las URLs se convierte en privado. Cualquier intensus necesidades o ideas. comienzan con url1, url2 y url3. to de hacer uso de ese mtodo generar Pero esto no ser un problema, vemos una excepcin. Por tanto esos mtodos Conclusin cmo funciona ConfigParser (ver Listado no pueden ser invocados desde fuera del 3). Como podemos apreciar en el ejemobjeto Collage. De esta manera Collage La complejidad de un programa Python plo, el uso de ConfigParser es muy sencislo tiene un mtodo accesible desde el no depende de la cantidad de lneas de llo. Primero se crea el analizador, guarexterior, generaCollage(). Se ha separado cdigo que contenga, sino ms bien del dndolo en la variable config. Despus la generacin de HTML de la del collage nivel al que trabaje. En el programa de cargamos con el mtodo readfp() el fichepara posibilitar las futuras extensiones este artculo hemos hecho uso intensivo ro de configuracin; este mtodo tambin del objeto. Por ejemplo podramos no de libreras que han realizado acciones analiza el fichero. A partir de ese momenquerer generar un fichero HTML sino muy complicadas por nosotros. Python to podemos realizar preguntas al objeto incorporar la imagen en un programa. En posee una amplio abanico de libreras a almacenado en config. Con sections() tal caso heredaramos de Collage y creaexplotar, muchas de ellas con aos de obtenemos una lista de las secciones y ramos un nuevo mtodo desarrollo esperando a programadores con options() de las opciones. Con esa generaCollage() que solo generase la con ideas originales que poner en prctiinformacin ya podemos recoger los imagen y la devolviese. ca. s datos necesarios usando el mtodo get(), El mtodo __generaHTML() genera el al que pasamos una seccin y una cdigo HTML de la pgina web. Un opcin. punto a resaltar es que genera un mapa RECURSOS

Ensamblemos las partes


Ahora ya tenemos: Un sistema de configuracin, usando ConfigParser. Un sistema para descargar las imgenes, usando httplib. Un sistema para manipular las imgenes, usando PIL. Nos toca ahora unirlo todo para que genere la pgina que aparece en la Figura 5. El resultado final se puede descargar de [5]. Crearemos una clase Collage con los mtodos __cargaConf() __descarga() __totalXY() generaCollage() __generaImagen() __generaHTML()

Listado 3: Uso de ConfigParser


01 >>> config = ConfigParser.ConfigParser() 02 >>> config.readfp(open('collage.conf')) 03 >>> config.sections() 04 ['tamao', 'imgenes'] 05 >>> 06 >>> config.options('imagen') 07 ['url1', 'url3', 'url2'] 08 >>> 09 >>> config.get('imagen','url1') 10 '"http://www-mgcm.arc.nasa.gov /MarsToday/marstoday.gif"'

[1] Grficos que usaremos: http://www-mgcm.arc.nasa.gov/ MarsToday/marstoday.gif http://www.sec.noaa.gov/sxi/ current_sxi_4MKcorona.png http://www.ssec.wisc.edu/data/sst/ latest_sst.gif http://www.wetterzentrale.de/pics/D2u. jpg [2] Python Imaging Library: http://www. pythonware.com/products/pil/ [3] The Gimp: http://www.gimp.org [4] Noticia sobre llamarada solar en Slashdot: http://science.slashdot.org/ science/05/09/08/1933205. shtml?tid=215&tid=14 [5] Listado del programa final de este artculo:

64

Nmero 10

WWW.LINUX- MAGAZINE.ES

También podría gustarte