PyTesseractの使い方

この記事ではTesseact OCRのPythonラッパー、pytesseractを紹介します。

目次#

PyTesseractについて#

公式リポジトリ:GitHub - madmaze/pytesseract: A Python wrapper for Google Tesseract

コマンド呼び出し方式のTesseractラッパーライブラリ。ライセンスはGPL v3。
C/C++ APIを使用する場合に比べて性能面でオーバーヘッドがあるものの、tesseractコマンドさえ動けばいいので互換性絡みの問題に遭遇しにくいのが特徴。

PillowおよびOpenCv、NumPy形式でデータを受け取ることができる。
以前はTesseractが対応している画像ファイルフォーマットが限られていたのでそれなりに有用だった。

何故かQiitaでよく紹介されている(ライブラリ名にtesseractと入っているからか?)。

セットアップ#

環境#

この記事ではmacOSおよびTesseract OCR 4.00.beta.4を対象とします。

  • Python 3.6.5
  • Tesseract OCR 4.0.0-beta.4
  • pytesseract 0.2.4
  • Pillow 5.2.0

Tesseractのバージョンは3.0系でも構いませんが、文字の位置の取得機能は3.05以降でないと機能しません。

インストール#

当然ですがTesseract本体がインストールされている必要があります。

$ brew install tesseract --HEAD

現時点でTesseract 4.0系はベータ版のため、--HEADオプション付きでインストールします。

Linux環境の場合は過去記事記事参照。

pipPillowpytesseractをインストールします。

$ pip install pytesseract Pillow

使い方#

pytesseractコマンド#

pytesseractをインストールすると、pytesseractというコマンドが使えるようになります。ありがたみは薄いですが。

$ pytesseract -l eng sample.jpg

-lオプションで言語(データファイルの拡張子を除いた部分)を指定します。
引数に画像ファイルを指定すると標準出力に認識結果を表示します。

動作チェック用のコマンドと言う位置づけかと思います。

ライブラリとして使う#

最も単純な使い方の例。

from PIL import Image
import pytesseract

print(pytesseract.image_to_string(Image.open('sample.jpg'))

tesseractコマンドの対応しているフォーマットであればImage.open()を使用せずに直接ファイルのパスを指定することも可能です。

画像によっては変化処理の関係で直接tesseractコマンドを呼び出す場合の結果が微妙に変化することがあります。

より高度な使い方#

pytesseractモジュールの関数は以下のとおり。

  • get_tesseract_version
  • image_to_string
  • image_to_boxes
  • image_to_data
  • image_to_osd

オプション設定#

image_to_XXX形式の関数の引数は以下のとおり。

  • image: 画像ファイル名またはPillow Image、Numpy array
  • lang: 言語名(省略した場合はNone(eng))
  • config: tesseractコマンドに渡すオプション
  • nice: tesseractコマンドの優先順位(省略した場合は0)
  • output_type: 出力形式(省略した場合はOutput.STRING(str))

言語とページセグメンテーションモードの指定。

from PIL import Image
import pytesseract

print(pytesseract.image_to_string(Image.open('test_jpn_01.jpg'), lang='jpn', config='--psm 6'))

image_to_XXX形式の関数のoutputオプションの詳細です。

指定できる形式は以下の3種類。

  • Output.DICT: 辞書形式(キーごとにリスト形式)
  • Output.STRING: デフォルト
  • Output.BYTES: bytesオブジェクトのリスト
print(pytesseract.image_to_string('sample.jpg', lang='eng', config='--psm 6', output_type=pytesseract.Output.DICT))

Output.DICTを指定した場合の出力例。

出力例(Output.DICT)
```
{'text': 'The quick brown fox jumped over the lazy dogs.'}

box形式#

座標系は左下原点系。

from PIL import Image
import pytesseract

boxes = pytesseract.image_to_boxes('sample.jpg', lang='eng', config='--psm 6')
print(boxes)

image_to_boxes()の戻り値はtesseractコマンドにtsvというconfigファイルを指定して実行した際の出力と同様です。

左から文字、左下座標(x, y)、右上座標(x, y)、ページ番号という形式です。

詳細:Training Tesseract – Make Box Files · tesseract-ocr/tesseract Wiki · GitHub

TSV形式#

座標系は左上原点系。内部的にはtesseractコマンドにtsvというconfigファイルを指定して実行しているだけです。

data = pytesseract.image_to_data('sample.jpg', lang='eng', config='--psm 6')

戻り値はタブ区切りテキスト形式のデータ(Stringオブジェクト)です。

cvsモジュールかPandasと組み合わせてパースする必要があります。

from PIL import Image
import pytesseract
import cvs

data = pytesseract.image_to_data('sample.jpg', lang='eng', config='--psm 6')
tsv = csv.reader(data.splitlines, delimiter='\t')

for row in tsv:
print(row)

1行目がヘッダ行なのでcvs.DictReader()を使うことも可能です。

from PIL import Image
import pytesseract
import cvs

data = pytesseract.image_to_data('sample.jpg', lang='eng', config='--psm 6')

tsv = csv.DictReader(data.splitlines(), delimiter='\t')
for row in tsv :
print(row['text'], row['conf'])

各列の値について下記のとおり。基本的に英単語の略称です。

  • level: レイアウト解析結果のレベル(ページ、ブロック、段落など)
  • page_num: ページ番号
  • block_num: ブロック番号
  • par_num: 段落番号
  • line_num: 行番号
  • word_num: 単語番号
  • left, top, width, height: 文字を囲むボックスの左上角の座標と幅、高さ
  • conf: 確からしさ
  • text: 認識結果の文字列

分かち書きをしない言語では中途半端な位置で区切って単語扱いされる。
辞書にある単語以外はn-gramで区切られているように見えますがドキュメントに記載はありません。

文字方向および言語(書字系)の検出#

print(pytesseract.image_to_osd(Image.open('test_jpn_01.jpg')))

結果の出力。

出力例
Page number: 0
Orientation in degrees: 0
Rotate: 0
Orientation confidence: 7.24
Script: Japanese
Script confidence: 1.83

この機能に関しては出力形式の変更オプションが役に立ちます。

print(pytesseract.image_to_osd(Image.open('test_jpn_01.jpg'), output_type=pytesseract.Output.DICT))

出力形式は以下のようにdict形式になります。

出力例(dict)
{'page_num': 0, 'orientation': 0, 'rotate': 0, 'orientation_conf': 7.24, 'script': 'Japanese', 'script_conf': 1.83}

エラーメッセージについて#

画像によっては情報不足で判定できないため、例外が発生する場合があります。

TesseractError: (1, 'Tesseract Open Source OCR Engine v4.0.0-beta.4-20-ge9b4e with Leptonica Too few characters. Skipping this page Warning. Invalid resolution 0 dpi. Using 70 instead. Too few characters. Skipping this page Error during processing.')

改行が除去されて見づらいですがToo few characters. Skipping this pageというメッセージのとおり、文字数の不足が原因です。

補足#

Pythonのtempfileモジュールで作成した一時ファイルに画像を書き出し、subprocessモジュールでtesseractコマンドを起動しているだけです。

そのため、認識結果に対してループ処理を行うAPIはありません。