While I love books — enough that I’ve written one myself — they’re often cumbersome to work with: finding things without a good index is very difficult, you can rarely take more than a few with you at a time and if it’s a particularly nice/expensive/rare one, you’d rather leave it in the shelf altogether.

The answer is, of course, to create a digital copy. One possible format for that would be PDF. Problem is: for its image data it has to resort to conventional compression algorithms. That means that scanned documents can turn out to be quite large. A file format that’s much more suited for this is DjVu. One of its tricks is a lossy algorithm that recognizes recurring shapes such as characters. As a result, DjVu encoded books are typically a quarter of the size of PDF encoded books.

Given the need to digitize a couple of books at work, I investigated whether it’s possible to create high-quality digital copies using freely available tools.

It’s not as easy as it sounds

If you already have a high-quality PDF document or a series of scanned images, there are a number of ways for you to end up with a decent DjVu document. The manual one involves calling the cjb2 command line tool from the DjVuLibre project, a more automatized one would be through the pdf2djvu tool. Problem is, when you scan a book, you rarely have high-quality scans to begin with. You typically have something like this:

Raw scan output

Fortunately there’s an excellent tool that can help here. It’s called unpaper and what it does is, among others, remove the ugly black borders and other noise, rotate the pages and split double pages in half. It works with PNM type images, so if your scanning program spits out a PDF, simply use ImageMagick to do the conversion. On a large document it’s most memory-efficient to make individual calls to the convert program, one per page:

for i in `seq 1 $NUMBER_OF_PAGES`; do
 convert -density 600 scan.pdf[`expr $i - 1`] pages`printf %03d $i`.pbm
done

This converts page N of the PDF to pages00N.pbm. Now unpaper can be invoked with the necessary options:

unpaper -v --layout double --pre-rotate -90 --output-pages 2 \
 pages%03d.pbm singlepages%03d.pbm

The result is separate image called singlepages00N.pbm that are nicely cleaned up:

Single page (left)Single page (right)

Extracting the text

At this point you might think that we’re done, given that cjb2 can easily convert the resulting pages to DjVu and djvm can create a multi-page document from them. However, the result wouldn’t be searchable for text, one of the reasons why one would want to digitize in the first place.

The solution here obviously is to apply some OCR technology. There are several free OCR tools available: tesseract, GOCR and ocropus. They all work more or less well, but ocropus has a trick up its sleave: It can not only extract the text from an image but also annotate the text with pixel coordinates. This means that a text search in a DjVu viewer will not only navigate to the right page but also to the right line (unfortunately, ocropus can’t resolve individual words, just lines). Installing ocropus on OS X is a bit of a pain in the neck, but if you follow these instructions to the word, it works. The following commands will then perform the OCR analysis:

ocropus book2pages outdir singlepages*.pbm
ocropus pages2lines outdir
ocropus lines2fsts outdir
ocropus fsts2text outdir
ocropus buildhtml outdir > hocr.html

As you can see, the result is an HTML file in the hOCR format. It contains the text gathered by ocropus in <span> elements, annotated with pixel information. In order to apply this information to DjVu documents, it needs to be transformed into a format that the DjVuLibre tools, specifically the djvused tool, understand. To do that, I hacked a little Python script together:

import sys
import os.path
from elementtree import ElementTree
from PIL import Image

hocrfile = sys.argv[1]
imgfiles = sys.argv[2:]

et = ElementTree.parse(hocrfile)
for page in et.getiterator('div'):
    if page.get('class') != 'ocr_page':
        continue

    if not imgfiles:
        continue
    imgfile = imgfiles.pop(0)

    txtfile = os.path.splitext(imgfile)[0] + '.txt'
    out = open(txtfile, 'w')

    image = Image.open(imgfile)
    print >>out, "(page 0 0 %s %s" % image.size

    for line in page:
        linetitle = line.get('title')
        if not linetitle.startswith('bbox '):
            continue
        x0, y0, x1, y1 = [int(x) for x in linetitle[5:].split()]
        imgheight = image.size[1]
        y0 = imgheight - y0
        y1 = imgheight - y1

        text = line.text.strip().replace('"', '\\"')
        print >>out, '  (line %s %s %s %s "%s")' % (x0, y0, x1, y1, text)

    print >>out, ")"
    out.close()

It’s evidently very crude and makes lots of assumptions specific to the ocropus output. For it to work you need the optional but fairly standard PIL and ElementTree packages installed. The script is invoked like so:

python hocl2djvu.py hocr.html singlepages*.pbm

It will spit out a singlepages00N.txt file for every page it finds text information for.

Putting it all together

Finally the image files for the individual pages can be converted to individual DjVu files:

for i in singlepages*pbm; do
    cjb2 -clean $i `basename $i pbm`djvu
done

Before combining the pages to a compound document, the djvused tool can then be used to apply the text annotations:

for i in singlepages*txt; do
    djvused `basename $i txt`djvu -e "select 1; set-txt $i" -s
done

Lastly, the following command creates the resulting book file:

djvm -c book.djvu singlepages*.djvu

And here’s what the result looks like:

DjVu text search

Conclusion

It’s easily possible to digitize books using free tools. Some rough edges remain, however. For instance, the unpaper program isn’t completely reliable. I haven’t fiddled with the settings yet, though, so perhaps the output can be improved. The same goes for the OCR machinery which still produces lots of erroneous words. Also, it’d be nice if the pixel annotations would work for individual words, too (like on Google book search). Perhaps a linear approximation could work — certainly seems feasible for monospace fonts.

In wenigen Monaten wird vielleicht die zweite Große Koalition der bundesdeutschen Geschichte zu Ende gehen. Ich werde Ihr keine einzige Träne nachweinen. Denn wir haben unter Merkel, Münte & Co. die meiner Meinung nach schlechtesten Gesetze seit langem bekommen:

Der “Hackerparagraph” des Strafgesetzbuches verbietet die Herstellung und Verbreitung von Computerprogrammen, die Zugang zu gesicherten und nichtöffentlichen Daten ermöglichen. Zwar steht natürlich das Abhören bzw. Beschaffen von nichtöffentlichen Daten schon selbst unter Strafe, aber der Gesetzgeber sah es wohl als Notwendigkeit an, schon das Erstellen und Verbreiten sogenannter “Hackertools”, die z.B. auch von Systemadministratoren zur Sicherheitsüberprüfung des eigenen Netzwerkes benutzt werden könnten, zu verbieten. Nachträglich hieß es von Seiten des Justizministeriums, dass dies nicht illegal sei, sondern nur, wenn o.a. Aktivitäten ausgeführt würden mit der Absicht, eine Straftat zu begehen. Es bleibt also ein vager Gesetzestext und die Hoffnung auf die richtige Auslegung vor Gericht.

Online-Durchsuchungen mit dem “Bundestrojaner” sollen es dem Staat hingegen erlauben, Hackertools einzusetzen, um Privatcomputer auszuspionieren. Zum Glück hat das Bundesverfassungsgericht mittlerweile sehr strenge Auflagen dafür erlassen. Wie so oft musste also der Quatsch aus Berlin erstmal in Karlsruhe nachgebessert werden. Zumal bekleckerte sich die Bundesregierung, allen voran Bundesinnenminister Schäuble, in der öffentlichen Diskussion nicht unbedingt mit Ruhm: IT-Experten zweifelten von Anfang an an der Machbarkeit und dem Erfolg einer solchen Maßnahme.

Die Erweiterung des BKA-Gesetzes vom Dezember 2008 gesteht dem BKA nun zu, auch ohne konkreten Tatverdacht tätig zu werden und sich dabei der Kontrolle der Staatsanwaltschaft zu entziehen. Die eben schon erwähnten Online-Durchsuchungen bilden dabei nur ein erlaubtes Werkzeug. Video- und Audioüberwachung in der Wohung, auch von dritten Personen, sind nun ebenfalls möglich.

Eine weitere Präventivmaßnahme bildet die Vorratsdatenspeicherung, die Telekomunikationsanbietern vorschreibt, sämtliche Verbindungsdaten für sechs Monate zu speichern. Hier wird also nicht nur ohne konkreten Tatverdacht ermittelt, sondern schon gänzlich grundlos eine Überwachung aller Bundesbürger durchgeführt. Das schlimme daran ist nicht nur, dass nur ein winziger Anteil der so überwachten Personen überhaupt straffällig werden, sondern dass sich die Daten auch zum Missbrauch gegen rechtschaffene Bürger eignen.

Ebenfalls missbrauchgefährdet ist die Kinderporno-Zensur, wie sie von Ursula von der Leyen (“Zensursula”) kürzlich ausgedacht wurde. Wie beim Bundestrojaner schlugen auch hier wieder IT- und Rechtsexperten Alarm. Aber auch diesmal ließ sich das Kabinett nicht beeindrucken. Das Ergebnis ist ein eigenständiges Gesetz (anstatt eines weiteren Passus im Telekommunikationsgesetz), das unter dem Vorwand der Kinderpornographie eine Zensurinfrastruktur schafft, die sich leicht auf andere Bereiche ausdehnen lässt. CDU-Politiker beeilten sich dann auch, gleich nach der Verabschiedung des Gesetzes die Ausweitung auf “Killerspiele” zu fordern. Das schlimme ist, dass das Gesetz Kinderpornographie nicht bekämpfen wird, dem eigentlich Zweck also nicht zuträglich ist, sondern nur das Fundament weiterer Zensur darstellt.

Diese Zensur könnte z.B. auch beim Urheberrecht (2. Korb) umgesetzt werden: Diese Novelle des UrhG schränkt den Umgang mit digitalen Medien erheblich ein (z.B. innerhalb ein und derselben universitären Einrichtung) und verbietet die Umgehung von Kopierschutz (es sei denn, dies wird ausschließlich für den privaten Gebrauch gemacht).

Zwar zementiert das “Antidiskriminierungsgesetz” (AGG) nicht den Polizeistaat in Deutschland wie die vorhergehenden Gesetze, dafür ist es eine herrliche Bürokratieschleuder. Allein wer sich seit seinem Inkrafttreten einmal eine Stellenanzeige angeguckt hat, wird wissen, wovon ich rede. Dabei halte ich den eigentlichen Nutzen des Gesetzes für äußerst fragwürdig. Im Gegenteil: Das Gesetz kehrt die Beweislast für Diskriminierung um und schreibt sogar Privatleuten vor, wie sie nicht zu diskriminieren haben. Meiner Meinung nach führt das nur zu vorgefertigen Vorwänden und Lügen, nicht aber zu weniger Diskriminierung.

Bei all diesen neuen und geänderten Gesetzes ärgert mich besonders, dass die historische Chance der Großen Koalition, nämlich die Föderalismusreform durchzuführen, völlig vernachlässigt wurde. Dabei brauchen wir sie dringender denn je. Überhaupt wurden sämtliche dringende Reformen vernachlässigt. Schröders Agenda 2010 war eine der wichtigsten Reformen der letzten zehn Jahre, eine Folgereform (“Agenda 2020″?) wäre längst überfällig.

Was mich an all dem aber am allermeisten ärgert: ich habe damals auch noch mitgeholfen, Gerd Schröder abzuwählen. Nun gut, selbst wenn er an der Macht geblieben wäre: durch den Linksrutsch der SPD, der die vorgezogenen Neuwahlen 2005 provoziert hatte, wäre es fraglich gewesen, ob er überhaupt so hätte weitermachen können. Dennoch wünsche ich es mir manchmal. Allerdings sollte man dabei nicht vergessen, dass wir auch unter Schröder Bürokratie- und Überwachungsmonster wie die Autobahnmaut (und damit die systematische Erfassung sämtlicher Nummernschilder auf deutschen Autobahnen) bekamen. Seinem Innenminister Otto Schily haben wir außerdem biometrische Reisepässe zu verdanken, wiederum trotz heftiger Kritik von IT-Sicherheitsexperten. Schily spendierte der Bundesrepublik zudem eine zweite Spiegelaffäre, indem er die Büroräume des Cicero-Magazins durchsuchen ließ.

Die beiden großen Parteien sind also nun endgültig unwählbar geworden, zumindest auf Bundesebene. Zum Glück gibt es Alternativen (die leider in Sachsen zur kommenden Bundestagswahl nicht antreten).

Update: Thomas Stadlers gestriger Blogeintrag zählt noch ein weiteres Gesetz auf, das in meiner Liste nicht auftaucht: das Luftsicherheitsgesetz. Dessen § 14 Abs. 3 räumt den Streitkräften die Möglichkeit ein, Waffengewalt gegen Flugzeuge anzuwenden, sofern diese gegen Menschenleben eingesetzt werden sollten (z.B. wie beim 11. September 2001). Trotz etlicher rechtlicher und ethischer Bedenken verabschiedete die Große Koalition das Gesetz, das Bundespräsident Köhler nur unter großen Bedenken unterschrieb. Das Bundesverfassungsgericht kippte schließlich den umstrittenen § 14 Abs. 3 — ein weiteres Beispiel, wie der Pfusch aus Berlin in Karlsruhe behoben werden musste.

Follow

Get every new post delivered to your Inbox.