OCR con Software Libre

De Gleducar, http://www.gleducar.org.ar

Contenido

Advertencia preliminar

Este texto debería subtitularse "sapere aude".*

(*) Literalemente, "atrevete a saber". En el contexto en que lo empleo Horacio (Epistolario, Lib. I, 40), "Dimidium facti qui coepit habet: sapere aude", "solo ha hecho la mitad quien ha comenzado: atrevete a saber".

Procedimiento

Scanear

Como vamos a scanear libros, el alimentador automático del scanner (a menos que tengamos uno muuuy especializado, que los hay pero cuestan una gónada y media y un ojo) es tan útil como un cenicero en una moto. Este scriptcito de bash o Korn shell scanea las páginas una a la vez y crea un archivo por cada una en formato netpbm (portable anymap format):

for i in $(seq --format=%003.f 1 [fin]); do
 echo Preparar pagina $i y pulsar Enter
 read
 scanimage --device '[dispositivo]' --format=pnm --mode 'True Gray' \
 --resolution 300 -l 90 -t 0 -x 210 -y 200 --brightness -20 --contrast 15
 scan-$i.pnm
done

Noten que usé los corchetes para indicar un parámetro que debe llenarse. El parámetro va *sin* corchetes. Donde [fin] es un número entero que define la última página a scanear (siendo '1' la primera) donde [dispositivo], entre comillas simples, es el modelo de scanner y su asignación, por ejemplo:

'brother2:bus1;dev1'

Se pueden saber los nombres de dispositivo con:

$ scanimage -L

y las opciones específicas del dispositivo con:

$ scanimage --help --device [tu_dispositivo]

Los ajustes del código anterior son puramente a título de ejemplo. En la práctica, deberán ajustar los seteos para los parámetros según corresponda:

-l  = descartar a izquierda (en pixels)
-t  = descartar arriba
-x e -y = coordenadas de la esquina inferior derecha de la página.

Intenten posicionar el libro de modo que sea posible usar estos parámetros para definir un rectángulo que solo contegna el texto, no el "aire" de los bordes.

No se preocupen por el número de página: podrán cortarlo después con poco esfuerzo. ¡Listo! Ya tenemos un montón de archivos (uno por página) con el texto scaneado.

Limpiando las imágenes

Casi inevitablemente, los scaneos no estarán posicionados de manera consistente y tendrán sombras en las esquinas. Si le pasamos esas imágenes a un programa OCR, por mejor que sea, no vamos a tener resultados precisos.

Pero ahí aparece el Chapulín Colorado: unpaper.

Si escanearon las páginas con la orientación correcta (esto es, lado derecho arriba) pueden usar los ajustes por default de unpaper. Si no, pueden usar alguna de las sofocientas opciones de unpaper. Por ej.,

--pre-rotate -90

rota la imagen 90 º en sentido antihorario. También se le puede decir a unpaper que hay dos páginas de texto en una imagen, etc. Para ver todas las opciones, man es tu amigo (o dicho de otro modo, RTFM)

El siguiente ejemplo de script prepara las imágenes para un rendimiento óptimo del OCR:

for i in $(seq --format=%003.f 1 150); do
 echo Preparando pagina $i
 unpaper scan-$i.pnm unpapered-$i
 convert unpapered-$i.pnm prepared-$i.tif && rm unpapered-$i.pnm
done

Es necesario convertir a TIFF porque la herramienta que vamos a usar para hacer el OCR requiere archivos de entrada TIFF.

OCR

La herramienta más precisa que parece haber para OCR es Tesseract (un antigo proyecto de HP-Bristol, ahora en Google code).

Tesseract usar archivos de idioma (ojo al instalarlo, el programa viene por un lado y los archivos de idioma por otro) y, por supuesto, tiene un entrenador para cada lenguaje, para las palabras que no están en el diccionario. La versión estable es 2.04. La versión 3.00 tiene algunas mejoras importantes, incluyendo muchos más language files, pero es incompatible con la 2.04 y aún está en estado de release candidate.

Se puede bajar del repositorio svn o de http://code.google.com/p/tesseract-ocr/downloads/list.

Este tontísimo script pasa cada página scaneada por el motor OCR:

for i in $(seq --format=%003.f 1 150); do
 echo Reconociendo texto en pagina $i
 tesseract prepared-$i.tif tesseract-$i -l [lengua]
done

donde [lengua] es el código correspondiente al idioma del texto original. El resultado del proceso es un conjunto de archivos, cada uno de los cuales tendrá el texto de una página escaneada.

Para textos multilingües, habrá que hacer más de una pasada, recortes y pegados, como fácilmente podrán imaginar. La estrategia dependerá del caso: un texto bilingüe en páginas enfrentadas implicará dos pasadas (una para las páginas pares, otra para las impares, con el incremental de 'i' en 2; un texto bilingüe a dos columnas se procesará mejor si hacemos dos scaneos por página, usando los parámetros -l, -x e -y descriptos más arriba, etc.

Poniendo todo junto

Antes de crear un documento consolidado, probablemente quieran sacar los números de página, encabezados o pies que aún existen en los archivos de texto. Los comandos 'tail' o 'head' servirán para el propósito. Por ejemplo, el siguiente script suprimirá la primera línea de cada uno de los archivos de texto que Tesseract produjo:

for i in $(seq --format=%003.f 1 150); do
 tail -n +2 tesseract-$i.txt >text-$i.txt
done

Si el número de página está al pie del texto, en el script anterior usen 'head -n -1' en lugar de 'tail -n +2'. Si hay, por ejemplo, un encabezado con el nombre del capítulo y un pie con el número de página, habrá que hacer un pipe de la salida de tail a la entrada de head (o viceversa).

Ahora tenemos un montón de archivos con el texto del libro "limpio". Para unificarlos podemos usar:

$ cat text-*.txt >completo.txt

lo que creará un solo archivo de texto conteniendo todo el libro. Con su editor favorito editen el texto para reemplazar cada ocurrencia de un guión y una nueva línea con una cadena vacía. También podrán eliminar todas las ocurrencias innecesarias de salto de línea, etc.

Por ejemplo, con tr podemos convertir todos los saltos de línea en espacios (el resultado será un choclo ilegible, así que el ejemplo es solo para mostrar cómo funciona tr):

$ cat complete.txt | tr '\n' ' ' > LibroListo.txt

¡Tarea completa! Ahora pueden tomar el texto , procesarlo con LaTeX, y obtener un PDF decente :)

Aviso de copyright

Copyright (C) 2010 Enrique A. Chaparro

Este texto puede ser libremente copiado, distribuido y modificado conforme a los términos de la WTFPL (Do What The Fuck You Want To Public License) versión 2.0.

Copyright © 2002-2010 Asociación Civil Gleducar
Todo los contenidos de este sitio se encuentran bajo una licencia libre del tipo Copyleft
Este sitio ha sido desarrollado usando Software Libre y respeta los estándares web.
Además ha sido diseñado para verse correctamente usando cualquier navegador, en cualquier resolución de pantalla.