Python+Tesseractによる画像処理でOCRを試してみた!
IT技術
Tesseract とは?
Tesseract は、オープンソースの OCR エンジンです。
「OCR」とは、画像ファイル中の文字を、テキストファイルとして読み込む技術のことです。
Tesseract は、コマンドラインのインターフェースを実装しているため、パソコンへインストールするだけで、OCR ができます。
Tesseract と Python で画像処理するメリットは?
Tesseract を Python と組み合わせて利用すれば、画像を前処理してから Tesseract へ渡すことができます。
これにより、OCR の精度が向上し、Tesseract が読み取った文字列を任意の形に処理できます。
例えば、紙に印刷された文書も、Tesseract を利用すれば、テキストデータとして保管できるのです。
さて、今回は、Tesseractを使って、画像処理でOCRを試してみたいと思います!
Tesseract の導入方法
Tesseract は、Python のモジュールではありません。
そのため、通常の「pip コマンド」ではなく、以下の手段を使ってインストールしなければなりません。
- Windowsの場合:インストーラ
- Linuxの場合:各ディストリビューションのパッケージ管理ソフトウェア
今回は、Windows へ導入していきます。
Windows のインストーラは、「マンハイム大学図書館」のものを利用します。
また、バージョンは「5.0」が推奨されているので、それに従います。
【Tesseract at UB Mannheim】
https://github.com/UB-Mannheim/tesseract/wiki
インストール時の注意点
インストール時の注意点は、以下となります。
Additional script data(download) を設定
「Choose Components」画面が表示されたところで、「Additional script data(download)」を展開します。
そして、「Japanese script」と「Japanese vertical script」にチェックを入れます。
Additional language data(download) を設定
次に、「Additional language data(download)」を展開してください。
そして、「Japanese」と「Japanese(Vertical)」にチェックを入れます。
インストール完了
この4箇所を追加で選択することで、日本語の読み込みが可能になります。
選択が終わったら、インストーラを最後まで完了させましょう。
これで、Tesseract のインストールは完了です。
PyOCR のインストール
「PyOCR」は、Python から OCR エンジンを利用可能にするためのモジュールです。
今回は、Python から Tesseract を利用するために導入します。
PyOCR の導入方法
PyOCR は、以下のコマンドで導入できます。
1pip install pyocr
モジュールを読み込む
インストールできたら、プログラム内から、モジュールを読み込みます。
1import pyocr
インストール完了
これで、Python から Tesseract を利用する準備が整いました!
※PyOCR をインストールすると、画像処理ライブラリの「Pillow」もインストールされます。
Tesseract を利用する際の注意点
Tesseractを Python から利用するためには、環境変数の PATH へ登録しておかなければなりません。
以下の方法を用いて、Tesseract の登録を行いましょう。
- あらかじめ Tesseract を環境変数の PATH へ登録しておく
- プログラム中に、Tesseract の PATH を環境変数に登録するよう実装
今回利用する PyOCR の関数
今回利用する PyOCR の関数は、以下となります。
利用可能な OCR エンジンをリストで取得する
1tools = pyocr.get_available_tools()
利用する OCR エンジンのオブジェクトを作成する
上記の配列を変数に入れ、オブジェクトを作成します。
1tool = tools[0]
Tesseract のオプションを設定する
引数に「オプション値」を記載します。
記載しない場合は、デフォルト値が設定されます。
特に重要なオプションは、OCR の実行方式を切り替える「tesseract_layout」オプションです。
デフォルト値は、「3」で「0~6」まで設定することができます。
今回は、「6」の精度が良さそうなので「tesseract_layout=6」を利用しています。
1builder = pyocr.builders.TextBuilder(tesseract_layout=6)
OCR を実行する
読み取り対象は、「Pillow」などでファイルから読み込みます。
Lang は、日本語であれば「jpn」を指定します。
builder のオプションは、上記で作成した builder オブジェクトを指定しましょう。
1tool.image_to_string("読み取り対象", lang="読み取り対象言語", builder="オプション")
実装例
まずは、以下の画像(test.jpg)を読み取ってみます。
処理の流れ
処理の流れは、以下のとおりです。
- Tesseract を OS 環境変数の PATH へ登録
- PyOCR で OCR の準備
- Pillow を使って画像を読み込む
- 読み取った結果を print する
コード
1import os
2from PIL import Image
3import pyocr
4
5#インストールしたTesseract-OCRのパスを環境変数「PATH」へ追記する。
6#OS自体に設定してあれば以下の2行は不要
7path='C:\\Program Files\\Tesseract-OCR'
8os.environ['PATH'] = os.environ['PATH'] + path
9
10#pyocrへ利用するOCRエンジンをTesseractに指定する。
11tools = pyocr.get_available_tools()
12tool = tools[0]
13
14#OCR対象の画像ファイルを読み込む
15img = Image.open("test.jpg")
16
17#画像から文字を読み込む
18builder = pyocr.builders.TextBuilder(tesseract_layout=6)
19text = tool.image_to_string(img, lang="jpn", builder=builder)
20
21print(text)
実行結果
このプログラムを実行して得られる結果は、以下のとおりです。
とりあえず読み込めているみたいです。
もう少し実用的な画像で実験
次に利用する画像は、一般に公開されているマイナンバーカードの裏面サンプル(test2.jpg)です。
これで「マイナンバー」「氏名」「生年月日」が読み取れるか、実験してみます。
実行結果
結果は、以下の通りです!
必要な情報は、生年月日しか読み取ることができませんでした。
失敗した原因は?
画像をよく見ると、マイナンバーの箇所は、背景がグレーで読みにくくなっています。
さらに、カード全体の背景にも柄が入っているため、これが OCR の処理を邪魔しているのでしょう。
前処理をして再び実験
そこで、「Pillow」を使って前処理をしてみました。
「一定の明るさを持つピクセルは白にする」という処理を施してみました。
コード
1import os
2from PIL import Image
3import pyocr
4
5#インストールしたTesseract-OCRのパスを環境変数「PATH」へ追記する。
6#OS自体に設定してあれば以下の2行は不要
7path='C:\\Program Files\\Tesseract-OCR'
8os.environ['PATH'] = os.environ['PATH'] + path
9
10#pyocrへ利用するOCRエンジンをTesseractに指定する。
11tools = pyocr.get_available_tools()
12print(tools[0].get_name())
13tool = tools[0]
14
15#OCR対象の画像ファイルを読み込む
16img = Image.open("test2.jpg")
17
18
19#画像を読みやすいように加工。
20img=img.convert('RGB')
21size=img.size
22img2=Image.new('RGB',size)
23
24border=110
25
26for x in range(size[0]):
27 for y in range(size[1]):
28 r,g,b=img.getpixel((x,y))
29 if r > border or g > border or b > border:
30 r = 255
31 g = 255
32 b = 255
33 img2.putpixel((x,y),(r,g,b))
34
35
36#画像から文字を読み込む
37builder = pyocr.builders.TextBuilder(tesseract_layout=3)
38text = tool.image_to_string(img2, lang="jpn", builder=builder)
39
40print(text)
実行結果
結果は、以下のようになりました。
Pillow のおかげで、文字もくっきりしているので、読みやすいです。
しかし、名前が「番号」→「改号」となっています。
その箇所以外は問題ないため、非常に惜しい結果となりました。
日本語の学習データを精度重視のものに置き換えてみる
Tesseract をインストールした時に導入される日本語のデータは、「速度」を重視しています。
そのため、これを「精度」を重視したデータに置き換えて実施してみます。
学習データを入れ替える
以下の2つの日本語学習データをダウンロードして、既存のフォルダに配置(上書き)します。
配置先フォルダは、「C:/Program Files/Tesseract-OCR/tessdata」です。
【tessdata_best/jpn.traineddata】
https://github.com/tesseract-ocr/tessdata_best/blob/master/jpn.traineddata
【tessdata_best/jpn_vert.traineddata】
https://github.com/tesseract-ocr/tessdata_best/blob/master/jpn_vert.traineddata
結果
学習データ入れ替え後の OCR の結果は、以下の通りです。
目的のデータを取得することができました!
ただし、速度重視の学習データから精度重視の学習データへ変更したことで、処理時間は少し伸びてしまいました。
さいごに
Tesserct + Python を組み合わせた OCR の使い方、ご理解いただけましたか?
1件、2件の読み込みであれば、自力でやるのも苦にはなりません。
しかし、数十件、数百件単位を手動で実施するのは骨が折れます。
ぜひ OCR エンジンの利用を検討してみてください。
あなたの力になること間違いなしです!
こちらの記事もオススメ!
2020.07.30Python 特集実装編※最新記事順Responder + Firestore でモダンかつサーバーレスなブログシステムを作ってみた!P...
2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ
「好きを仕事にするエンジニア集団」の(株)ライトコードです! ライトコードは、福岡、東京、大阪、名古屋の4拠点で事業展開するIT企業です。 現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。 いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。 システム開発依頼・お見積もり大歓迎! また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」を積極採用中です! インターンや新卒採用も行っております。 以下よりご応募をお待ちしております! https://rightcode.co.jp/recruit