Posts mit dem Label Training werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Training werden angezeigt. Alle Posts anzeigen

Mittwoch, 25. Dezember 2013

Was Training so ausmacht


Bin dank Clemens Neudecker auf das im Rahmen des succeed Projektes entwickelte Tool ocrevalUAtion gestoßen. Damit kann man seine OCR-Ergebnisse mit dem Original vergleichen und bekommt eine Übersicht über die typischen OCR-Fehler.

Ich habe mal eine Seite aus Bunte Bilder aus dem Sachſenlande genommen und hier sind die Werte für untrainiertes Tesseract 3.02.03 mit dem mitgelieferten "deu-frak":


CER7,74
CER-DL7,74
WER27,65
WER (bag of words)27,43
 
Dabei bedeutet CER: Character error rate, CER-DL: Character error rate nach Damerau-Levenshtein und WER: Word error rate.

Hier sind also nur knapp 92% aller Zeichen richtig und gar nur 72% aller Wörter.

Nun die im Laufe des Bunte Bilder Projektes auf den Buchtitel trainierte Variante:

CER2,83
CER-DL2,83
WER7,78
WER (bag of words)9,07

Es sind nun 97% aller Zeichen richtig und fast 91% aller Wörter! Fazit: Trainieren lohnt sich!

Dies deckt sich auch mit den Berechnung aus meinem früheren Beitrag "OCR Qualität bestimmen" bzw. aus Teil 9, wo die Worterkennungsrate 93% betrug.

Das Tool berechnet aber auch für jedes vorkommende Zeichen die Fehlerwahrscheinlichkeit, was hilft sein Augenmerk auf diese typischen Probleme zu lenken. Hier ein Beispiel des untrainierten Tesseract. Ins Auge fällt, daß dies (wie bereits beschrieben) kein langes-s erkennt. Sichtbar sind auch die Problemzeichen 'n', 'u' und 'ü':

Error rate per character and type

CharacterHex codeTotalSpuriousConfusedLostError rate
204632010,65
!210100Infinity
"220100Infinity
)2920000,00
*2a201050,00
,2c3314221,21
-2d602033,33
.2e2901313,79
131610016,67
23240000,00
53540000,00
83830000,00
93950000,00
A4160000,00
B42110109,09
D44100000,00
E4560000,00
F4690000,00
G4760000,00
H4860000,00
I494040100,00
J4a50000,00
K4b80000,00
L4c10000,00
M4d50000,00
N4e40000,00
O4f20000,00
P5030000,00
R5270000,00
S532603011,54
T5450000,00
U5540000,00
V5670000,00
W5770000,00
Z5a70000,00
a611230201,63
b62410102,44
c63660101,52
d641100000,00
e654300411,16
f664005012,50
g67710000,00
h681210403,31
i69178230012,92
j6a3400133,33
k6b210104,76
l6c912002,20
m6d64019029,69
n6e2497705,62
o6f480000,00
p70110000,00
r721480000,00
s73372005,41
t741330100,75
u75105011111,43
v76180000,00
w77310000,00
x7810000,00
y7910000,00
z7a380000,00
«ab0100Infinity
»bb0100Infinity
Äc4201050,00
ßdf70000,00
äe4130000,00
öf6110000,00
üfc2109042,86
ſ17f900900100,00
–20132020100,00
—20140100Infinity
“201c3030100,00
„201e3030100,00

Mittwoch, 5. Juni 2013

Teil 9, Selbstversuch Ebook - Befreiung am Beispiel "Bunte Bilder aus dem Sachsenlande", Verbesserung Tesseracts Erkennungsrate

Im letzten Blogpost "OCR Qualität bestimmen" habe ich grob beschrieben, wie man beurteilen kann, wie gut die Erkennungsqualität der verschiedenen OCR-Engines ist.
Als Maß hatte ich dort die Worterkennungsrate verwendet, da diese im Vergleich zur Zeichenerkennungsrate genauer ist. Gerade bei Verfahren, die intern Wörterbücher verwenden, kann die Zeichenerkennungsrate hoch sein, der Text bleibt dennoch unleserlich.

Um die Erkennungsqualität von Tesseract 3.02 zu verbessern habe ich mir die Beschreibung der Konfigurationsoptionen unter http://www.sk-spell.sk.cx/tesseract-ocr-parameters-in-302-version angeschaut.

Folgende Werte hatte ich bisher in der Datei deu-frak.config stehen:

enable_new_segsearch 1
textord_space_size_is_variable 1
load_bigram_dawg 1

Die Worterkennungsrate betrug damit 86% (die Diskrepanz zum Wert 60% aus Blogpost rührt daher, daß die Wörter der benutzten Seite da noch nicht im fürs Training verwendeten Wörterbuch steckten. Dies zeigt, wie wichtig die Pflege eines korrekten Wörterbuches für die Erkennungsrate von Tesseract ist).

Im ersten Schritt habe ich nur einzelne der ff. Parameter (* zeigt Default an) verändert:

Parameter01
enable_new_search92%(*) 86%
language_model_ngram(*) 86%36%
textord_old_baselines89%(*) 86%

Die Werte textord_space_size_is_variable, load_bigram_dawg, edges_use_new_outline_complexity, permute_script_word, ngram_permuter_activated, use_new_state_cost führten zu keiner Änderung der Erkennungsrate von 86%.

Warum die Erkennungsrate bei  language_model_ngram so stark einbricht, verstehe ich noch nicht.

Im zweiten Schritt habe ich die beiden Parameter, die eine Verbesserung zeigten, kombiniert. Voila!, die Worterkennungsrate steigt auf 93%!

Wer noch Hinweise für sinnvolle Kombinationsmöglichkeiten anderer Parameter hat, immer her damit! :)

Dienstag, 21. Mai 2013

Ocropus 0.7 – Training

Trainingsausgabe Ocropus 0.7

Im letzten Beitrag hatte ich einen ersten Vergleich zwischen Ocropus 0.7 und Tesseract 3.02 gezogen. Da leider die mitgelieferten Dateien für Fraktur keine Unterstützung für das lange-S beinhalten, muß ich Ocropus selber trainieren.

Unterschied Tesseract- und Ocropus Trainingsdaten


Leider hat sich bei Ocropus 0.7 der Trainingsmodus geändert. Um die gleichen Dateien, wie Tesseract 3.02 zu verwenden, habe ich ein Script geschrieben, welches die Tesseract-Boxfiles und zugehörige TIFF-Dateien so umwandelt, daß die von Ocropus erwarteten zeilenbasierten PNG-Dateien mit zugehörigen Text-Dateien erzeugt werden.

Aus dem tess_train Verzeichnis:

tess_train
├── bigram_words
├── deu-frak.bigram-dawg
├── deu-frak.config
├── deu-frak.frak2.exp0.box
├── deu-frak.frak2.exp0.tif
├── deu-frak.frak2.exp0.tr
├── deu-frak.frak2.exp0.txt
:
├── deu-frak.frak2.exp9.box
├── deu-frak.frak2.exp9.tif
├── deu-frak.frak2.exp9.tr
├── deu-frak.frak2.exp9.txt
├── deu-frak.freq-dawg
├── deu-frak.inttemp
├── deu-frak.normproto
├── deu-frak.number-dawg
├── deu-frak.pffmtable
├── deu-frak.punc-dawg
├── deu-frak.shapetable
├── deu-frak.traineddata
├── deu-frak.unicharambigs
├── deu-frak.unicharset
├── deu-frak.word-dawg
├── font_properties
├── freq
├── get_bigramword_list.pl
├── get_freqlist.pl
├── get_wordlist.pl
├── number
├── ogerman
├── punc
├── train.sh
├── unicharset
└── unicharset.edited

Sonntag, 9. Dezember 2012

Teil 5, Selbstversuch Ebook - Befreiung am Beispiel "Bunte Bilder aus dem Sachsenlande"

 

Update

Ergänzt um Wörterbucherzeugung und Häufigkeitsliste. Korrektur Fehler OCR-Text (falsche Datei erwischt).

Seitenweises Zeichenerfassen

Wie im letzten Artikel beschrieben, habe ich mir zur Verbesserung der Erkennungsgenauigkeit von Tesseract 3 Paare von TIFF-Dateien und Box-Dateien erzeugt, um die Zuordnung von Blobs zu den Zeichen im UTF-8 Format mit Hilfe von jTessBoxEditor festzulegen.

Ich hatte dazu 5 Seiten aus dem Originalscan ausgewählt, zwei davon aus dem Inhaltsverzeichnis, um auch Ziffern zu erfassen.

Diese Zuordnung hat relativ lange gedauert, da ich pro Seite ca. 2500 Zeichen editieren mußte.

Hartes Training

Das Training von Tesseract besteht aus mehreren Schritten. Wichtig ist die Erzeugung der font_properties Datei, die angibt, daß der Font gebrochen ist, sprich als Frakturschrift daherkommt. Dazu wird folgende Zeile eingetragen:

frak2 0 0 0 0 1

Ebenfalls wichtig sind zwei Dinge, erstens eine Wortliste, die auch Besonderheiten, wie das lange S korrekt enthalten sollte, zweitens ein Häufigkeitsliste, die angibt, welche Wörter, wie häufig vorkommen. Wenn man hier keine Arbeit reinstecken möchte, kann man die Dateien vom deu-frak-Paket verwenden (ist bei Tesseract dabei), die aber keine Unterstützung für langes S beinhaltet.

Mein Weg war daher folgender. Aus den Box-Dateien habe ich die Wörter extrahiert und daraus meine Wortliste gebaut.

Dazu habe ich mit folgendem Aufruf aus allen Box-Dateien die Wörter in eine Textdatei geschrieben und mit Editor in eine Wortliste umgewandelt:

cat deu-frak.frak2.exp*.box | cut -d " " -f 1 | tr -d '\n' > words.txt
Anschliessend die Liste mit sort sortieren und mit uniq die Dubletten entfernen:

cat words.txt | sort | uniq > ogerman

Die Häufigkeitsliste bekommt man mit

cat words.txt |sort -fd  | uniq -c | sort -n -r >  freq
Mit gnumeric noch schnell die beiden Spalten Häufigkeit und Wort vertauschen.

Die Schritte des Trainings habe ich in einem Script zusammengefasst, ein alternatives Script findet sich unter https://github.com/paalberti/tesseract-dan-fraktur/blob/master/deu-frak/buildscript.sh:

#!/bin/bash
rm -f *.tr *.txt deu-frak.inttemp deu-frak.normproto deu-frak.pffmtable deu-frak.shapetable deu-frak.traineddata deu-frak.unicharset pffmtable unicharset
for i in $(seq 0 5); do
tesseract deu-frak.frak2.exp$i.tif deu-frak.frak2.exp$i nobatch box.train
done
unicharset_extractor deu-frak.frak2.exp0.box deu-frak.frak2.exp1.box deu-frak.frak2.exp2.box deu-frak.frak2.exp3.box deu-frak.frak2.exp4.box deu-frak.frak2.exp5.box
#mftraining -F font_properties -U unicharset -O unicharset deu-frak.frak2.exp0.tr deu-frak.frak2.exp1.tr deu-frak.frak2.exp2.tr deu-frak.frak2.exp3.tr
cat unicharset | sed -e "s/^\([æøåäöüâêàèéçßſ][a-z]*\) 0/\1 3/" \
  -e "s/^\([ÆØÅÄÖÜÂÊÀÈÉÇ][a-z]*\) 0/\1 5/" \
  -e "s/^\([«»„”·§—ɔ–]\) 0/\1 10/" \
  -e "s/^ɔ 3 /ɔ 10 /" \
  -e "s/^½ 0/½ 8/" | sed -e "s/^\([æøåäöüâêàèéçßa-zÆØÅÄÖÜÂÊÀÈÉÇA-Zſ].*\) NULL /\1 Latin /" \
  -e "s/^\([«»„”·§—ɔ–[:punct:][:digit:]].*\) NULL /\1 Common /" \
  -e "s/^\(&c .*\) Common /\1 Latin /" > unicharset.edited
#mftraining -F font_properties -U unicharset -O unicharset deu-frak.frak2.exp0.tr deu-frak.frak2.exp1.tr deu-frak.frak2.exp2.tr deu-frak.frak2.exp3.tr
shapeclustering -F font_properties -U unicharset.edited deu-frak.frak2.exp0.tr deu-frak.frak2.exp1.tr deu-frak.frak2.exp2.tr deu-frak.frak2.exp3.tr deu-frak.frak2.exp4.tr deu-frak.frak2.exp5.tr
mftraining -F font_properties -U unicharset.edited -O deu-frak.unicharset deu-frak.frak2.exp0.tr deu-frak.frak2.exp1.tr deu-frak.frak2.exp2.tr deu-frak.frak2.exp3.tr deu-frak.frak2.exp4.tr deu-frak.frak2.exp5.tr

cntraining deu-frak.frak2.exp0.tr deu-frak.frak2.exp1.tr deu-frak.frak2.exp2.tr deu-frak.frak2.exp3.tr deu-frak.frak2.exp4.tr deu-frak.frak2.exp5.tr
wordlist2dawg ogerman deu-frak.word-dawg deu-frak.unicharset
wordlist2dawg freq.txt deu-frak.freq-dawg deu-frak.unicharset
mv inttemp deu-frak.inttemp
mv normproto deu-frak.normproto
mv shapetable deu-frak.shapetable
mv pffmtable deu-frak.pffmtable
combine_tessdata deu-frak.
Hat alles funktioniert existiert im Verzeichnis tess_train/ die Datei deu-frak.traineddata, die für das OCR der anderen Seiten interessant ist.

OCR über alle Seiten

Zurück im Hauptverzeichnis, geht es nun ans Eingemachte. Tesseract kann man über die Variable TESSDATA_PREFIX mitteilen, wo es die OCR-Trainingsdaten findet.
Tesseract sucht im angegebenen Verzeichnis nach dem Verzeichnis tessdata/, ich kopiere dazu aus tess_train/ die deu-frak.traineddata.
Um jetzt für alle im Verzeichnis ppm_single/ befindlichen Einzelseiten, eine optische Zeicherkennung zu machen, benutze ich folgenden Aufruf, der im Verzeichnis txt/ die Text-Dateien erzeugt:


export TESSDATA_PREFIX=/tmp/Bunte_Bilder_aus_dem_Sachsenlande/
for i in ppm_single/*.ppm; do echo $i; convert $i /tmp/img.tif; tesseract /tmp/img.tif txt/$(basename $i '.ppm') -l deu-frak; done
Alternativ kann tesseract auch hOCR ausgeben. hOCR ist ein HTML/XML Format, welches im Rahmen von Google Ocropus entwickelt wurde und die Zuordung erkannter Text, Struktur und die zugrundeliegenden Bilder ermöglicht. Es wird mittlerweile von einer großen Anzahl an OCR-Programmen unterstützt. Eventuell erzeuge ich das hOCR mit, um ggf. daraus leichter das EPub-Format zu erzeugen.

OCR Ergebnis am Beispiel-Text der Seite 70

 




_.70—

keiten von kunſtgeioerblichem und knltiirhiſtoriſcheiii Jntereſſe enthält: wertvolle
Ringe und Ariuſpangen, lenchtende Dianianten und Rubinen, den größten Onyx
der Welt mit weißeiii Rande, Halsbäiider aus Edelſteinen und Perlen, goldene
Geſäße und ſeltene Uhren, ſeine Knnſtarbeiten früherer Jahrhnnderte und mancherlei
Kurioſitäten. Waffen der verſchiedenſten Zeitalter aus Jtalien und der Türkei,
Figuren aus Bronze und Elſenbein, der Kriſtallbecher Luthers und der Brillant-
ſchinuck der Königin: Tauſende von Prachtſtiicken leuchten hier dem Auge des Ve-
ſchauers entgegen. Fiirwahr, das Grüne Gewöll)e ſteht in Europa einzig in
ſeiner Art da; es hat einen wirklichen Wert von über 40 Millionen, während ſein
Kunſtwert ſich gar nicht abſchätzen läßt. Der Name ,,Griines Gewölbe«, der



bereits im 17. Jahrhundert vorkoniint, wird bald von den Gartenaiilageii her-
geleitet, welche ſich einſt vor den Fenſtern der Samiiiluiig beſanden, bald, was
noch glaubhaſter iſt, von der ſriiheren griinen Färbung der Wände.

Einen andern höchſt wertvollen Schatz beſitzt Dresden in der Gemälde-
galerie, uutergebracht in dem 1854 vollendeten Muſeum, durch deſſen Bau
Semper in genialem Wurſe den Reuaiſſaneeſtil der Neuzeit begri'uidete. Zu-
gleich ſchuſ Seinpers Nieiſterhand damit einen echt künſtleriſchen Abſchliiß des
Zwingers, des pl)antaſtiſchſteii, im Barockſtil gehaltenen Bauwerkes Auguſts des
Starken. Bekaniitlich war der Zwinger, der 1711 vollendet ward, nur als Borhoſ
eines ſreilich nicht zur Ausſiihruiig gekommenen Prachtſchloſſes gedacht, welches ſeine
gewaltige Front mit den Terraſſen gegen die Elbe kehren ſollte. Der Zwinger
bildet ein 250 Meter langes und 1()0 Meter breites Biereck, deſſen weiten Rauin
eine lange Galerie mit 6 Pavillons und 3 Portalen umſchließt, und in deſſen
Mitte ſeit 1843 das Denkmal Friedrich Auguſts des Gerechten, ein Werk Riet-
ſchels, auſgeſtellt iſt.