Member of The Internet Defense League Últimos cambios
Últimos Cambios
Blog personal: El hilo del laberinto Geocaching

Data Bus

Última Actualización: 12 de enero de 2013

A.J.I.V. (Asociación Juvenil para la Informática Viguesa) fue una asociación fundada en 1988, con el fin de promover la informática, a un nivel técnico. La asociación tuvo bastante relevancia en su momento. Por ejemplo, fuimos miembros del consejo de la juventud de Galicia.

Fieles a ese compromiso técnico, en 1990 empezamos a elaborar una revista en papel, gracias a subvenciones oficiales. Lamentablemente la revista no tenía una periodicidad fija. Simplemente íbamos acumulando artículos hasta que completábamos cada número. Tampoco conseguimos nunca tener un grupo fijo de colaboradores.

Por supuesto, el nivel técnico de la revista, hoy en día, no es muy alto, pero hay que ser conscientes del contexto histórico: antes de Internet y realizada por gente joven autodidacta sin titulación universitaria, con recursos informáticos domésticos.

A pesar de todo se llegaron a publicar nueve números, interesantes por la perspectiva histórica y la precariedad de los medios puestos en juego.

La asociación se cerró oficialmente en 2001, tras un largo período de inactividad. Al ser una asociación juvenil, es preciso que los cargos directivos estén en manos de personas menores de treinta años, y no conseguimos una renovación generacional. Lástima.

Las revistas se hicieron con ordenadores Atari ST y el software Calamus. Imprimíamos con una impresora de inyección de tinta HP DeskJet 500 (pionera en su época).

Años después (2003) discutimos la posibilidad de recuperar las revistas para el mundo digital.

La primera idea era utilizar una versión moderna de Calamus para leer las revistas, y generar PDFs a partir de ellas. Pero no conseguimos encontrar a nadie que tuviese el soft y que pudiese probarlo con nosotros. En 2012 Simón probó la versión moderna de Calamus para PC y los resultados fueron bastante buenos, pero nos encontramos con el problema de recuperar los ficheros informáticos originales, como describo más abajo, además de verse algunas inconsistencias en el formato.

Nuestra segunda idea fue utilizar el software original en un emulador, imprimiendo en una HP DeskJet 500 virtual. El emulador genera un fichero con el volcado de los comandos de la impresora. Un programa en Python, funcionando en nativo (Linux), cogía ese volcado de impresora e interpretaba los códigos de la HP para generar un PNG, sin pérdida de calidad.

La prueba de concepto del decodificador es: (basado en Hewlett-Packard Laser and DeskJet Printer Escape Code Sequences)

#!/usr/bin/env python

from PIL import Image

a = open("/tmp/hp.prn").read()
im = Image.new("1", (1000, 1000), 255)

secuencia = "\\x1b*b0052W"
p = 0
y = 0
while True :
    p = a.find(secuencia, p)
    if p == -1 : break
    p += len(secuencia)
    v = a[p:p+52]
    for i,j in enumerate(v) :
        x = i*8
        j = ord(j)
        for dummy in xrange(8) :
            if j&128 :
                im.putpixel((x,y), 0)
            j *= 2
            x += 1
    y += 1

im.show()

El problema ahora era localizar y leer los discos originales. Alfonso, Pablo y yo invertimos para ello medio verano. Las revistas se conservaban en diskettes de 3.5 pulgadas que, hoy en día, son prácticamente ilegibles (tanto por no disponer de lectores compatibles como porque el propio soporte físico está degradado), o faltan componentes necesarios como tipos de letra, etc. Algunas revistas faltaban por completo, y otras eran borradores inacabados, no la versión final que finalmente se publicó.

Tras intentar localizar todos los diskettes posibles, nos dimos por vencidos. Esta opción era la que proporcionaría mejor calidad final, pero no era viable.

Yo, como editor y coleccionista impenitente, conservaba varias copias en papel de las revistas originales. En la mayoría de los casos, incluso los "masters" -sacados por impresora- que usábamos para fotocopiar las versiones finales. Alfonso y yo invertimos algo de tiempo en las navidades de 2010 escaneando algunas páginas y haciendo pruebas para la conversión a dos niveles de color (blanco y negro, sin grises). Los resultados eran buenos, pero la operación muy manual (fijar el umbral de corte se hacía página a página, a mano). Tras las navidades yo volví a Madrid y Alfonso se dedicó a escanear todas las revistas y pasarlas a blanco y negro, mientras yo escribía el software para generar los PDFs.

El siguiente verano comparamos notas, y la conversión a blanco y negro manual no nos acababa de convencer. Se perdían detalles y la calidad no era homogénea. Tras investigar opciones, descubrimos los algoritmos de thresholding. Hice algunas pruebas y acabamos reconvirtiendo otra vez todas las imágenes (que Alfonso había escaneado y conservado en tonos de gris) de nuevo de forma automatizada.

La generación de PDFs se completó en enero de 2012. Y ahora las entregamos al mundo, con una mezcla de vergüenza propia :-) y nostalgia de ver de dónde venimos.

Los scripts toman los PNG originales en tonos de grises, los corta, los gira, los convierte a un bit por píxel (blanco y negro) usando el algoritmo de thresholding "Otsu" y genera un PDF en formato A5.

La idea de usar "Otsu" fue comprobando que el algoritmo de "thresholding" de GIMP es bastante bueno y, mirando el código fuente (¡ventajas del Open Source!) había referencias a dicho algoritmo.

Los scripts para generar estos PDF a partir de los PNG en tonos de grises originales son los siguientes:

#!/usr/bin/env python

# Otsu Thresholding
# http://www.labbookpages.co.uk/software/imgProc/otsuThreshold.html

import sys, math
from PIL import Image
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import portrait, A5
from reportlab.lib.utils import ImageReader
#reportlab.lib.utils.Image = Image

a=canvas.Canvas("z.pdf", pagesize=portrait(A5))

def otsu_1(width, heigh, histogram) :
    l = width*height
    umbral = 0
    varianza_umbral = 1e+100
    for i in xrange(257) :
        cb = float(sum((v for j,v in enumerate(histogram[:i]))))
        cw = float(sum((v for j,v in enumerate(histogram[i:], i))))
        if (cb == 0) or (cw == 0) : continue
        wb = cb/l
        ww = cw/l
        mb = sum((j*v for j,v in enumerate(histogram[:i])))/cb
        mw = sum((j*v for j,v in enumerate(histogram[i:], i)))/cw
        vb = sum(((j-mb)*(j-mb)*v for j,v in enumerate(histogram[:i])))/cb
        vw = sum(((j-mw)*(j-mw)*v for j,v in enumerate(histogram[i:], i)))/cw

        varianza = wb*vb + ww*vw

        if varianza < varianza_umbral :
            umbral = i
            varianza_umbral = varianza

    return umbral

# Esta rutina, para mis escaneos, es 2-3 veces mas
# rapida, y el umbral calculado es el mismo.
def otsu_2(width, heigh, histogram) :
    l = width*height
    umbral = 0
    varianza2_umbral = -1
    for i in xrange(257) :
        cb = float(sum((v for j,v in enumerate(histogram[:i]))))
        cw = float(sum((v for j,v in enumerate(histogram[i:], i))))
        if (cb == 0) or (cw == 0) : continue
        wb = cb/l
        ww = cw/l
        mb = sum((j*v for j,v in enumerate(histogram[:i])))/cb
        mw = sum((j*v for j,v in enumerate(histogram[i:], i)))/cw

        varianza2 = wb*ww*(mb-mw)*(mb-mw)

        if varianza2 > varianza2_umbral :
            umbral = i
            varianza2_umbral = varianza2

    return umbral

for fichero in sys.argv[1:] :

    im = Image.open(fichero)
    im = im.transpose(Image.ROTATE_90).convert("L")
    histogram = im.histogram()
    width, height = im.size

    umbral = otsu_2(width, height, histogram)
    print fichero, umbral

    im = Image.eval(im, lambda x : 0 if x<umbral else 255)
    im = im.convert("1")
    #im.save("z.png")
    #im.show()

    im=im.crop((0,0, width/8*8, height))
    im.load()
#    a.drawImage(ImageReader(im), 0, 0, width=419, height=419*math.sqrt(2),
#            preserveAspectRatio=True)
    a.drawInlineImage(im, 0, 0, width=419, height=419*math.sqrt(2),
            preserveAspectRatio=True)
    a.showPage()

a.save()

Un problema imprevisto fue que los PDF generados eran enormes, mucho más grandes que las imágenes originales, lo que no tenía sentido. Se investigó y se parcheó :-). ¡Open Source!.

Por último, todo este trabajo se presentó en una reunión mensual de Python-Madrid.

Data Bus 1, Abril 1990

  • Editorial

  • Guía del profano Eduardo Cunha

  • Virus en tu ordenador Simón Gómez

  • Algoritmos: Técnicas de compresión Jesús Cea

  • Música por ordenador: el protocolo MIDI Eduardo Cunha

  • Procesamiento en paralelo Telmo Lago

  • Curiosidades informáticas: Ordenadores que piensan Jesús Cea

  • Prontuarios: Tabla de conversión decimal-hexadecimal-binario

  • Historia de la informática: Parte primera Nacho Agulló

  • Glosario Eduardo Cunha

Data Bus 2, Diciembre 1990

  • Editorial

  • Guía del profano: El sistema operativo, aritmética binaria Eduardo Cunha

  • Hardware Marcos Vaqueiro Rodríguez

  • Procesamiento en paralelo: Transputers Telmo Lago

  • Algoritmos: Emulación de la recursividad Jesús Cea

  • Curiosidades informáticas: Fractales (I) Jesús Cea

  • Historia de la informática: Parte segunda Nacho Agulló

  • Glosario Eduardo Cunha

Data Bus 3, Abril 1991

  • Editorial

  • Nuevas tecnologías: el chip en 3 dimensiones Telmo Lago

  • Algoritmos: Algoritmos de compresión de textos Jesús Cea

  • El ordenador y su entorno: Impresoras Pablo Lobariñas

  • Historia de la informática (III): Los primeros ordenadores Nacho Agulló

  • Curiosidades informáticas: Fractales (II) Jesús Cea

  • Aplicaciones prácticas: El C.A.D. (I) Simón Gómez

Data Bus 1, segunda época, Octubre 1991

  • Editorial

  • Fractales: El conjunto de Mandelbrot Jesús Cea

  • Hardware: Diseño de circuitos impresos Telmo Lago

  • Técnica: El Z80 de Zilog Nacho Agulló

  • Algoritmos: Algoritmo generador de Huffmann Jesús Cea

  • Técnica: Unidades de Entrada/Salida Pablo Lobariñas

  • Historia: Historia de la informática - parte IV Nacho Agulló

Data Bus 2, segunda época, Noviembre 1991

  • Editorial

  • Técnica: El Z80 de Zilog (II) Nacho Agulló

  • Curiosidades Informáticas: La guerra nuclear Jesús Cea

  • Reportaje: El tratamiento de la imagen fotográfica en "El Sol" J.M. Suárez

  • Historia: Historia de la informática - parte V Nacho Agulló

  • Técnica: Anomalías en los ordenadores Telmo Lago

  • Algoritmos: Rutinas matemáticas - Primera parte Jesús Cea

Data Bus 3, segunda época, Octubre 1992

  • Editorial

  • Algoritmos: El formato numérico de coma flotante Jesús Cea

  • Técnica: El concepto de multimedia Telmo Lago

  • Resultados del gran concurso de programación Guerra Nuclear

  • Microprocesadores: El microprocesador Z80 de Zilog (III) Nacho Agulló

  • Curiosidades Informáticas: Las leyes de Murphy Jesús Cea

  • Historia: Historia de la informática - parte VI Nacho Agulló

  • Noticias: ¡¡Noticias Frescas!! J.M. Suárez

Data Bus 4, segunda época, Marzo 1993

  • Editorial

  • Algoritmos: Una somera introducción al Procesado de Imagen Francisco Bellas Aláez, David Martínez Oliveira

  • Microprocesadores: El microprocesador Z80 de Zilog (IV) Nacho Agulló

  • Curiosidades Informáticas: Aleatorización de textos Jesús Cea

  • Noticias: ¡¡Noticias Frescas!! José Manuel Suárez

  • Historia: Historia de la informática - parte VII Nacho Agulló

  • La precisión ante todo (PI)

Data Bus 5, segunda época, Agosto 1993

  • Editorial

  • Algoritmos: Algoritmos de clasificación (I) Jesús Cea

  • Noticias: ¡¡Noticias Frescas!! José Manuel Suárez

  • Microprocesadores: El microprocesador Z80 de Zilog (V) Nacho Agulló

  • Impresoras: Una pequeña introducción a las impresoras láser José Luis Estévez

  • Historia: Historia de la informática - parte VIII Nacho Agulló

  • La precisión ante todo (II) (e)

Data Bus 6, segunda época, Septiembre 1994

  • Editorial

  • Imagen: Una somera introducción al Procesado de Imagen (II): Transformaciones de intensidad Francisco Bellas Aláez, David Martínez Oliveira

  • Algoritmos: Algoritmos de clasificación (II) Jesús Cea

  • Noticias: ¡¡Noticias Frescas!! José Manuel Suárez

  • G.D.I.: Grupo de Desarrollo Informático

  • Historia: Historia de la informática (IX) Nacho Agulló

  • La precisión ante todo (III) (√2)



Python Zope ©2012-2013 jcea@jcea.es

Más información sobre los OpenBadges

Donación BitCoin: 19niBN42ac2pqDQFx6GJZxry2JQSFvwAfS