0.はじめに
Tesseractには、言語ごとに認識される単語や文字のセットを定義するファイルがあります。この中には「単語リスト」なるものがあり、ここに存在する単語は認識率が上がるらしいです。
ここにポケモンの名前やら技名などの固有名詞を入れ込んでしまおうという話。
1.用意するもの
- Windows版Tesseract をインストールすると含まれている以下のexeファイル
combine_tessdata.exe
dawg2wordlist.exe
wordlist2dawg.exe
- 学習済み日本語モデル
BEST版を使用します。適当な場所にダウンロード。
https://github.com/tesseract-ocr/tessdata_best/blob/main/jpn.traineddata
2. 作業手順
2-1. 学習済み日本語モデルを分解する
# combine_tessdata.exe -u `ダウンロードしたtraineddataの場所` `任意の出力先+名前`
# (実行例)
combine_tessdata.exe -u C:\download\jpn.traineddata C:\temp\pokemon
上記例ではC:\temp\pokemon
としていますが、この場合は下記の様なファイルが出力されます。
C:\temp\pokemon.config
C:\temp\pokemon.lstm
C:\temp\pokemon.lstm-unicharset
C:\temp\pokemon.lstm-word-dawg
…
今回はlstm-unicharset
とlstm-word-dawg
が必要になります。
2-2. 分解したlstm-word-dawgファイルをテキストに変換する
# combine_tessdata.exe -u `lstm-unicharsetの場所` `lstm-word-dawgの場所` `任意の出力先ファイル名`
# (実行例)
dawg2wordlist.exe C:\temp\pokemon.lstm-unicharset C:\temp\pokemon.lstm-word-dawg C:\temp\word.text
2-1で出力されたlstm-word-dawg
が単語リストです。これを編集可能なテキスト形式に変換します。
2-3. 変換したテキストファイルを編集する
1行につき1単語でポケモン用語を羅列します。
フシギダネ
フシギソウ
フシギバナ
…
2-4. 編集したテキストファイルをlstm-word-dawgファイルに変換する
# combine_tessdata.exe -r 1 `編集したテキストファイル` `lstm-unicharsetを出力する場所` `lstm-unicharsetの場所`
# (実行例)
wordlist2dawg.exe -r 1 C:\temp\word.text C:\temp\pokemon.lstm-word-dawg C:\temp\pokemon.lstm-unicharset
上記例の場合、lstm-word-dawg
が編集したテキストファイルを変換した物で上書きされます。
2-5. 変換したlstm-word-dawgを結合して学習済み日本語モデルに戻す
# combine_tessdata.exe `結合したいファイルがある場所`
# (実行例)
combine_tessdata.exe C:\temp\pokemon
C:\temp\pokemon.*
ファイルが結合され、C:\temp\pokemon.traineddata
が出力されています。このファイルをTesseractのtessdataフォルダにコピーし、言語指定する事でこのファイルでOCRが実行されます。
3. 結果
試してみました。
「ウーラオス」と「インファイト」を単語リストに含めています。
tesseract.exe -l pokemon tsv
-l
オプションで言語を指定、tsv
を付けると単語区切りで結果を出力してくれます。
単語リスト差し替え前
5 1 1 1 1 1 20 20 60 19 91.014992 相手
5 1 1 1 1 2 82 16 18 32 0.000000 の
5 1 1 1 1 3 114 16 40 32 0.000000 ウー
5 1 1 1 1 4 154 21 31 18 93.265129 ラオ
5 1 1 1 1 5 190 22 14 16 92.753342 ス
5 1 1 1 1 6 208 22 17 16 93.231453 の
5 1 1 1 1 7 250 20 36 18 88.840370 イン
5 1 1 1 1 8 289 21 33 17 96.691963 ファ
5 1 1 1 1 9 324 20 32 18 92.663544 イト
単語リスト差し替え後
5 1 1 1 1 1 20 20 60 19 93.129326 相手
5 1 1 1 1 2 85 16 14 32 90.676468 の
5 1 1 1 1 3 105 20 120 19 93.156639 ウーラオス
5 1 1 1 1 4 210 16 20 32 84.360298 の
5 1 1 1 1 5 250 20 121 18 0.000000 インファイト
差し替えた単語リストがちゃんと機能しています。多分。きっと。
4. OCRする画像について
- 画像内の文字は一行にまとめ、
--psm 7
オプションで実行すると認識率が上がる傾向があります。 - 文字の周りには余白を付けた方が良いそうです。公式曰く10ピクセル程度。
- 文字サイズが大きすぎると単語のつながりとして認識してくれなくなります。Switchの画面1920x1080をそのまま認識しても上手くいかない事が多いです。テスト画像は50%に縮小しています。
BEST版とFAST版の違い
今回、学習モデルにはBEST版を使用しましたが、認識率より速度を重視したFAST版もあります。FAST版でも同じ方法で単語リストを差し替える事が可能です。
FAST版は認識可能な文字の数や学習データ量が抑えられており、configファイル(2-1で分解した時に出来る***.configファイル)の内容がBEST版とFAST版では大きく異なります。
configの中には、特定の文字を認識対象外にするtessedit_char_blacklist
、単語リストの優先度を上げるらしいsegment_penalty_dict_nonword
等が存在しており、これらを上手く調整すると認識率の向上が見込めると思います。
が、如何せん資料がなさすぎて断念。
chatGPTに「segment_penalty_dict_nonwordって何?」とか聞くとそれっぽい答えが返ってきます。
余談
本来、単語リストはLSTM学習用のテキストから学習中に生成されるもので、この様な差し替え方はイレギュラーだと思われます。なんか動いちゃった的な奴。
とはいえTesseractの学習はやたら敷居が高いので、お手軽に専門用語を認識しやすくする方法として残しておく事にしました。