ユーザ用ツール

OCR

概要

国立国会図書館のデジタルアーカイブなどにより、昔の雑誌などが徐々に閲覧可能になってきている。 古いPC向け雑誌などに掲載されているプログラムリストを入力することも可能だが、すでにあるものならこれをOCRで取り込めれば助かる。

ここでは、OCRを使ったプログラムリストの入力などについて、備忘録的にまとめておく。

tesseract-ocr

非常に強力なOCRツールで、学習によって、特定のフォントなどに適応可能なOCRである。

きりだし

画像ファイル dump_list.pngに雑誌から取得したダンプリストが入っており、これを dump_list.txtにテキストとして取り出す場合は次のようにする。

tessedit_char_whitelist は文書中に使われている文字で、文字種を絞ることでより精度を高めることができる。

$ tesseract -l eng -c tessedit_char_whitelist="0123456789ABCDEF :" --psm 6 dump_list.png dump_list

但し、古い雑誌の多くは「0」に斜めの線が入ったフォントを使用しているが、eng モデルでは単純な縦長の丸を期待しているため、このままそのようなダンプリストを処理すると、6, B, 4 などと誤認識するか、そもそも認識しそこなうかで実用的ではない。

そこで次にあげる「学習」が必要となる。

学習

tesseract-ocr の最大のポイントはこの「学習」にあるといえる。 使用するフォントを含んだ一行分の画像ファイルと、その内容を記したテキストファイルとをペアとして用意して、これを学習させることで、画像のフォントに適応したモデルを得ることができ、認識率を飛躍的に向上させられる。

実際、ダンプリストであれば、256バイトあたり数個のご認識が混ざる程度で処理が可能となる。

ベースモデルの取得

tesseract-ocrのパッケージに含まれているモデルは fast モデルで、これをベースとして学習させることはできない。 best モデルを取得する必要がある。

ダンプリスト用であれば英語モデルがベースであり、それを取得する。

$ wget https://github.com/tesseract-ocr/tessdata_best/raw/main/eng.traineddata

tesstrainの取得

学習は tesstrain を使って行う。 tesstrain はパッケージではなく GitHubから取得する。

$ git clone https://github.com/tesseract-ocr/tesstrain.git
cd tesstrain

学習データの用意

学習データとしては、個別の文字画像と対応するテキスト、または一行分の画像ファイルと対応するテキスト列ファイルのいずれかを用意する。多ければ多いほど精度は高くなる。

例えば、ここに D130.png というダンプリストの一部を切り出した画像を用意したら、D130.gt.txt1) という内容を記述したテキストファイルを同じ場所に置く。

D130.gt.txt
D130 : 66 FF 99 FF FF 3C 00 00 00 0C F8 06 FC F8 00 00

例えば、これをD100 - D1F0 までの16行分用意して学習データとする。

ファイルが用意出来たら、画像からの学習を開始する。 ../tessdata_best にGitHubから取得した学習のベースモデルが、./traindataに分解した画像ファイルとGround Truthテキストファイルがまとめておかれているとする。

ベースモデルは eng で、kougakushaというモデルを作成するには、以下のコマンドを実行する。

$ make training \
MODEL_NAME=kougakusha \
START_MODEL=eng \
TESSDATA=../tessdata_best \
GROUND_TRUTH_DIR=./traindata \
MAX_ITERATIONS=10000

これを用意したファイルの分繰り返す。 lstmfファイルができたら、学習用と評価用に分ける。 例では14を学習用に、2を評価用に振り分けているが、別に両方全部使ったっていいような気がします。

ls *.lstmf > list.all
head -n 14 list.all > list.train
tail -n 2 list.all > list.eval

学習データが準備んで来たので実際に学習を行う。

$ lstmtraining --continue_from ./eng.lstm --model_output ./dumplist --traineddata ./eng.traineddata --train_listfile ./list.train --eval_listfile ./list.eval --max_iterations 5000 --learning_rate 0.0001
Loaded file ./eng.lstm, unpacking...
Warning: LSTMTrainer deserialized an LSTMRecognizer!
Continuing from ./eng.lstm
2 Percent improvement time=32, best error was 100 @ 0
At iteration 32/100/100, mean rms=0.615%, delta=1.140%, BCER train=5.796%, BWER train=7.444%, skip ratio=0.000%, New best BCER = 5.796 Transitioned to stage 1 wrote best model:./dumplist_5.796_32_100.checkpoint wrote checkpoint.
2 Percent improvement time=0, best error was 5.796 @ 32
At iteration 32/200/200, mean rms=0.354%, delta=0.570%, BCER train=2.898%, BWER train=3.722%, skip ratio=0.000%, New best BCER = 2.898 wrote best model:./dumplist_2.898_32_200.checkpoint wrote checkpoint.
2 Percent improvement time=0, best error was 5.796 @ 32
At iteration 32/300/300, mean rms=0.259%, delta=0.380%, BCER train=1.932%, BWER train=2.481%, skip ratio=0.000%, New best BCER = 1.932 wrote best model:./dumplist_1.932_32_300.checkpoint wrote checkpoint.
2 Percent improvement time=0, best error was 5.796 @ 32
At iteration 32/400/400, mean rms=0.209%, delta=0.285%, BCER train=1.449%, BWER train=1.861%, skip ratio=0.000%, New best BCER = 1.449 wrote best model:./dumplist_1.449_32_400.checkpoint wrote checkpoint.
2 Percent improvement time=0, best error was 5.796 @ 32
At iteration 32/500/500, mean rms=0.177%, delta=0.228%, BCER train=1.159%, BWER train=1.489%, skip ratio=0.000%, New best BCER = 1.159 wrote best model:./dumplist_1.159_32_500.checkpoint wrote checkpoint.
2 Percent improvement time=0, best error was 5.796 @ 32
At iteration 32/600/600, mean rms=0.155%, delta=0.190%, BCER train=0.966%, BWER train=1.241%, skip ratio=0.000%, New best BCER = 0.966 wrote best model:./dumplist_0.966_32_600.checkpoint wrote checkpoint.
2 Percent improvement time=0, best error was 2.898 @ 32
At iteration 32/700/700, mean rms=0.139%, delta=0.163%, BCER train=0.828%, BWER train=1.063%, skip ratio=0.000%, New best BCER = 0.828 wrote best model:./dumplist_0.828_32_700.checkpoint wrote checkpoint.
2 Percent improvement time=0, best error was 2.898 @ 32
At iteration 32/800/800, mean rms=0.126%, delta=0.142%, BCER train=0.725%, BWER train=0.931%, skip ratio=0.000%, New best BCER = 0.725 wrote best model:./dumplist_0.725_32_800.checkpoint wrote checkpoint.
2 Percent improvement time=0, best error was 2.898 @ 32
At iteration 32/900/900, mean rms=0.116%, delta=0.127%, BCER train=0.644%, BWER train=0.827%, skip ratio=0.000%, New best BCER = 0.644 wrote best model:./dumplist_0.644_32_900.checkpoint wrote checkpoint.
2 Percent improvement time=0, best error was 2.898 @ 32
At iteration 32/1000/1000, mean rms=0.108%, delta=0.114%, BCER train=0.580%, BWER train=0.744%, skip ratio=0.000%, New best BCER = 0.580 wrote best model:./dumplist_0.580_32_1000.checkpoint wrote checkpoint.
2 Percent improvement time=0, best error was 2.898 @ 32
At iteration 32/1100/1100, mean rms=0.050%, delta=0.000%, BCER train=0.000%, BWER train=0.000%, skip ratio=0.000%, New best BCER = 0.000 wrote best model:./dumplist_0.000_32_1100.checkpoint wrote checkpoint.
Finished! Selected model with minimal training error rate (BCER) = 0
$ 

dumplist_x.xxx_yy_zzzz.checkpoint の x.xxxx はエラーレートで小さいほどよい。 つまりここでは dumplist_0.00_32_1100.checkpoint が最も良い学習を行ったファイルになり次の処理に使われるファイルになる。

$ lstmtraining --stop_training --continue_from ./dumplist_0.000_32_1100.checkpoint --traineddata ./eng.traineddata --model_output ./dumplist.traineddata    
Loaded file ./dumplist_0.000_32_1100.checkpoint, unpacking...
$

これで kougakusha.traineddata というモデルファイルが取得できる。 できたモデルファイルは、システムフォルダーにコピーするか、TESSDATA_PREFIX環境変数がポイントするフォルダーにコピーしておく。

$ sudo cp kougakusha.traineddata /usr/share/tesseract-ocr/5/tessdata

モデル使用の例

以下の画像ファイルをこの学習で得たモデルファイルで処理した結果が次のものになる。

$ tesseract -l dumplist -c tessedit_char_whitelist="0123456789ABCDEF :" dumpd600.png dumpd600

dumpd600.txt
D600 : E0 C3 76 D5 00 00 00 D5 CD 26 D6 0E 20 06 20 7E
D610 : FE 00 20 05 AF D3 02 D1 C9 3E 20 D3 0C 7B D3 0C
D620 : 7A CD 34 D6 18 E5 3E 08 03 02 3E 36 D3 0F C5 00
D630 : 00 00 16 05 1E 00 1B 7A B3 20 FB C9 00 00 00 36
D640 : 80 23 36 81 23 36 62 C9 36 83 23 36 84 23 36 80
D650 : C9 36 86 23 36 87 23 36 88 C9 36 89 23 36 8 23
D660 : 36 8B C9 36 8C 23 36 8D 23 36 8E C9 36 8F 23 36
D670 : 90 23 36 91 C9 36 92 23 36 93 23 36 94 C3 36 95
D630 : 23 36 96 23 36 97 C9 36 98 23 36 99 23 36 9A C8
D690 : 36 9B 23 36 9C 23 36 9D C9 36 CA 23 36 CB 23 36
D6A0 : CC C 36 00 23 36 00 23 36 00 23 C9 36 FD 23 36
D680 : FE 23 36 FF C9 36 A5 23 36 A6 23 36 A7 23 36 A8
D6C0 : D5 11 88 FF 19 D1 36 B3 2B 36 A4 2B 36 A3 2B 36
DED0 : A2 C9 36 ED 23 36 EE 23 36 EF 23 36 F0 D5 11 88
D6E0 : FF 19 D1 36 F4 2B 36 F3 2B 36 F2 2B 36 F1 C3 36
D6F0 : F5 23 36 F6 23 36 F7 23 36 F8 D5 11 88 FF 19 D1
D700 : 36 FC 2B 36 FB 2B 36 FA 2B 36 F9 C3 CD A2 D6 36

若干の欠落や誤認識が見られるがおおむね良好な認識を行っているといえると思う。

1)
ground truth ファイルと呼ぶ

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also, you acknowledge that you have read and understand our Privacy Policy. If you do not agree, please leave the website.

More information