今回の記事はTesseractOCRの4.1.1で「OpenCV画像処理」「出力文字の制限」などの条件でどの程度OCRの精度が変化するかを比較しまとめた記事です。実際に使用して比較してので正しい比較となっているともいます。TesseractOCRのバージョンで迷っている方は是非決定の手助けができれば幸いです。
まずTesseract4.1.1.系をDocker環境で構築するところまではこちらの記事を参考にしてください。
Tesseract OCRの文字制限とは?
まずTesseractでインプットする画像の処理が必要だということはわかると思うのですが、出力文字を制限することができることを知っている方はなかなか初心者の方ではいないと思います。
Tesseractを実行するにあたりオプションで指定の文字を除く「balcklist」、指定の文字のみで出力を行う「whitelist」というものが存在します。
こちら下記のようにTesseract実行時に指定します。下記の場合はホワイトリストに制限文字と入っているのでこの4文字しか使用されません。
tesseract -l jpn_best '[読み込み画像パス.JPG]' stdout -c tessedit_char_whitelist="制限文字"
上記のように出力文字を絞って精度をあげることが可能かどうかも検証していきます。
Tesseract OCRによる画像OCRの精度確認
まず画像処理などを入れない状態で精度を確認する為に画像を用意します。検証した画像は下記です。

Tesseract結果
tesseract -l jpn_best '/test.JPG' stdout
Empty page!!
Empty page!!
大前提として画像内の文字を何も検出で来ていませんでした。念のため領域を切り取って再度実行

Tesseract結果
tesseract -l jpn_best '/test2.JPG' stdout
Empty page!!
Empty page!!
ここで画像がダメなのかをかくにんする為比較的真正面をむいて傾きを持っていない画像をピックアップして再度OCRしてみました。できるだけ看板に似ているものをピックアップしてみました。

Tesseract結界
tesseract -l jpn_best '/test3.JPG' stdout
スト
Cafe レ スト ラブ
た
反応があった笑。少なくとも無反応よりも嬉しい。
ここでまず一つ言えることはOCRに際しては確実に画像は真正面、傾きなしを採用する必要があるということです。
ではこの画像で領域切り取りや色変換などを試していきましょう。
OpenCVにより前処理を行った画像に対してTesseract OCRを行い精度確認
今回画像処理を行った画像は下記です。2値化、グレースケール、オリジナル画像の順番に並んでおります。












OpenCVの画像処理に関してはまとめた記事を要しているのでそちらをご参照ください。
「【Python】OpenCV・Kerasを使って機械学習に有効な画像Augmentation(画像の水増し)方法まとめ。」
領域切り取り
まずは領域を切り取った下記画像をTesseractにかけてみます。
コード状の画像名と画像に降っているtitleが紐付いておりますのでどの画像でどのような結果になったかは下記をご参照ください。




Tesseract結果
tesseract -l jpn_best '/test4.JPG' stdout
VANA
油 交 人 世
tesseract -l jpn_best '/test5.JPG' stdout
「
tesseract -l jpn_best '/test6.JPG' stdout
ヒレ セン 3 時 紀 現地 調査 を ds 生 c 放 倒 た に
に の 新規 看板 開 飲 c あ の ま 生 記
tesseract -l jpn_best '/test7.JPG' stdout
Empty page!!
Empty page!!
この結果から領域切り取りは有用ということがわかります。
精度は今ひとつですが笑。
test7画像に関してはおそらく変な文字(矢印)が含まれていることや、文字の高さが一定でない点などが原因と考えられます。
グレースケール
では次にグレースケール画像で試してみましょう。
試した画像は下記です。




Tesseract結果
tesseract -l jpn_best '/testimage/test4_gray.JPG' stdout
Warning: Invalid resolution 0 dpi. Using 70 instead.
Estimating resolution as 595
Error in boxClipToRectangle: box outside rectangle
Error in pixScanForForeground: invalid box
Error in boxClipToRectangle: box outside rectangle
Error in pixScanForForeground: invalid box
Detected 36 diacritics
7 vo て
況 交 人 世
tesseract -l jpn_best '/testimage/test5_gray.JPG' stdout
Warning: Invalid resolution 0 dpi. Using 70 instead.
Estimating resolution as 312
Cafe レ スト ラフ
万 スト
tesseract -l jpn_best '/testimage/test6_gray.JPG' stdout
Warning: Invalid resolution 0 dpi. Using 70 instead.
Estimating resolution as 209
tesseract -l jpn_best '/testimage/test7_gray.JPG' stdout
Warning: Invalid resolution 0 dpi. Using 70 instead.
Estimating resolution as 963
Empty page!!
Estimating resolution as 963
Empty page!!
精度良くなったものもありますね。この結果グレースケールは有用です。特にtest5に関してはかなり向上しています。
test7はおそらく特殊な文字が入っている点や、文字の高さが違う点などからOCRできないですね。。
2値化(白黒)
最後に2値化を行ってみます。
下記画像を使用しております。




Tesseract結果
tesseract -l jpn_best '/testimage/test4_2chi.JPG' stdout
Warning: Invalid resolution 0 dpi. Using 70 instead.
Estimating resolution as 194
tesseract -l jpn_best '/testimage/test5_2chi.JPG' stdout
Warning: Invalid resolution 0 dpi. Using 70 instead.
Estimating resolution as 313
Cafe レ スト ラフ
カス ト
tesseract -l jpn_best '/testimage/test6_2chi.JPG' stdout
Warning: Invalid resolution 0 dpi. Using 70 instead.
Estimating resolution as 212
tesseract -l jpn_best '/testimage/test7_2chi.JPG' stdout
Warning: Invalid resolution 0 dpi. Using 70 instead.
Estimating resolution as 975
Empty page!!
Estimating resolution as 975
Empty page!!
test4、6は共に文字が認識しにくくなってしまった為OCRできずtest7はそのままできないまま。test5に関してはグレースケールよりも向上しております。
test5に関しては有用と言えると思います。test5の精度はあと一歩といった感じで100に近い気がします。
上記が私の試した画像処理です。以上のことを踏まえると下記が言えるのではないでしょうか。
画像処理によるTesseract OCRの精度向上に関して考察
・画像は真正面かつ角度なくする必要がある
・領域切り取りは全ての画像に対して行う必要がある
・グレースケールも全ての画像に対して有用
・2値化は画像によっては文字として認識できる状態でおさまるのであれば有用
・文字の高さはOCRに関係
これだけ分かっただけでも大きいです。
おそらく角度などの補正や文字が消えてしまうことに関してもopenCVの水平補正や、ノイズ除去などで解消できるかもしれませんので気になる方は確認してみてください。
出力文字制限によるTesseractの精度確認
次に先ほど説明していた文字出力の制限を行ってみて、精度がどのように変化するかをかくにんしてみましょう。
先ほどまでの検証画像で一番精度のでていたtest5を使用します。



では早速みていきましょう。まずは先ほどの文字制限なしの結果をまとめておきます。
tesseract -l jpn_best '/test5.JPG' stdout
「
tesseract -l jpn_best '/testimage/test5_gray.JPG' stdout
Cafe レ スト ラフ
万 スト
tesseract -l jpn_best '/testimage/test5_2chi.JPG' stdout
Cafe レ スト ラフ
カス ト
こちらを出力文字を除外する「ブラックリスト」と制限する「ホワイトリスト」を使ってそれぞれ検証していきます。
出力文字除外のブラックリスト
先ほどから出力の邪魔をしていた「カ」を除外して「ガ」として出力させてみます。
tesseract -l jpn_best '/testimage/test5_2chi.JPG' stdout -c tessedit_char_blacklist="カ"
Warning: Invalid resolution 0 dpi. Using 70 instead.
Estimating resolution as 313
Cafe レ スト ラフ
ママ
全然良くない。全く違う文字に全てんってしまった。
tesseract4系からはLSTMのニューラルネットを使用しているとのことだったのでおそらく前後の文脈までOCR処理に関わってきております。その為、文字除外はあまり良い手法ではないのかもしれません。
対象限定のホワイトリスト
次は出力して欲しい文字列を入れてみました。この文字のみで出力を行うのでかなり精度上がるのではと思っておりました。
root@cf89c9b89fad:/# tesseract -l jpn_best '/testimage/test5_2chi.JPG' stdout -c tessedit_char_whitelist="Cafeレストラ ガスト"
Warning: Invalid resolution 0 dpi. Using 70 instead.
Estimating resolution as 313
Cafe レ スト ラ
ス ト
これおそらく文字がどれにも合わないので出力していないパターンかな?
ということで文字出力制限はともに難ありということになりました。海外の記事を見ていると英語、数字に関しては有用みたいですが日本語のOCRはまだまだ難ありという感じみたいですね。
要は画像の前処理がかなり注力する必要があるということですね。
ただ、Tesseract OCRには画像の再学習を行うことなどもできるのでそちら方面も調べてみます。折角オープンソースとして名前の知れているものがあるのですから使えるようになればかなり便利ですもんね。
コメント