目次
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
ベースモデルの分解
学習用の始点として trainneddataを用いることはできないので、これを分解して、学習用の始点となる lstm ファイルを得る。
$ combine_tessdata -u eng.traineddata eng. Extracting tessdata components from eng.traineddata Wrote eng.lstm Wrote eng.lstm-punc-dawg Wrote eng.lstm-word-dawg Wrote eng.lstm-number-dawg Wrote eng.lstm-unicharset Wrote eng.lstm-recoder Wrote eng.version Version:4.00.00alpha:eng:synth20170629:[1,36,0,1Ct3,3,16Mp3,3Lfys64Lfx96Lrx96Lfx512O1c1] 17:lstm:size=11689099, offset=192 18:lstm-punc-dawg:size=4322, offset=11689291 19:lstm-word-dawg:size=3694794, offset=11693613 20:lstm-number-dawg:size=4738, offset=15388407 21:lstm-unicharset:size=6360, offset=15393145 22:lstm-recoder:size=1012, offset=15399505 23:version:size=80, offset=15400517 $
ここで得られた eng.lstm が学習の始点ファイルとなる。
学習データの用意
学習データとしては、個別の文字画像と対応するテキスト、または一行分の画像ファイルと対応するテキスト列ファイルのいずれかを用意する。多ければ多いほど精度は高くなる。
例えば、ここに 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行分用意して学習データとする。
ファイルが用意出来たら、画像からの学習を開始する。
$ tesseract D130.png D130 --psm 7 lstm.train --groundtruth D130.gt.txt
これを用意したファイルの分繰り返す。 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... $
これで dumplist.traineddata というモデルファイルが取得できる。 できたモデルファイルは、システムフォルダーにコピーするか、TESSDATA_PREFIX環境変数がポイントするフォルダーにコピーしておく。
$ sudo cp dumplist.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
若干の欠落や誤認識が見られるがおおむね良好な認識を行っているといえると思う。


