Pythonを使った文字認識に興味を持ったので、ネット上の情報を頼りに、画像データからの文字起こしをサクッとやってみた。

今回は下記二つのツールを使って試してみた。

Tesseract

OSSの光学文字認識(OCR)エンジンで、様々なOSにインストールして使うことができる。

Macへインストールする場合、ターミナルで以下のコマンドを実行する。

brew install tesseract

もしインストールに失敗するようなら、エラーメッセージにあるとおり、権限変更のコマンドを実行すれば良い。
俺の環境では以下二つのコマンドを実行すると、tesseractをインストールすることができた。

sudo chown -R $(whoami) /usr/local/lib/pkgconfig /usr/local/share/man/man8

chmod u+w /usr/local/lib/pkgconfig /usr/local/share/man/man8

学習用データの準備

次にTesseractの学習用訓練データを用意する。

まず、以下のリンクから訓練データをダウンロード。

https://github.com/tesseract-ocr/tessdoc/blob/master/Data-Files.md

今回は「tessdata」を使うことにする。

次に、ダウンロード・解凍したファイルを以下の場所に移動する。

/usr/local/Cellar/tesseract/※tesseractのバージョン/share/tessdata/

PyOCR

PythonでOCRツールを使うためのラッパーで、Pythonを使ってTesseractをはじめとする様々なOCRツールを扱うことができる。

インストールコマンドは下記のとおり。

pip3 install pyocr

文字認識のテストコード

こちらのサイトの「Usage」を参考にテストコードを書いてみた。

from PIL import Image
import sys

import pyocr
import pyocr.builders

tools = pyocr.get_available_tools()
if len(tools) == 0:
	print("No OCR tool found")
	sys.exit(1)

tool = tools[0]
print("Will use tool '%s'" % (tool.get_name()))

txt = tool.image_to_string(
	Image.open("./img/test.jpg"),
	lang="eng",
	builder = pyocr.builders.TextBuilder(tesseract_layout=6)
)

print(txt)

今回の実験に用意した画像はこちら。

エディタ上のテストコードをキャプチャしたものだ。

解析結果

それではコードを実行し結果を確認してみる。

python main.py

# 以下解析結果
Will use tool 'Tesseract (sh)'
from PIL import Image
import sys
import pyocr
import pyocr.builders
tools = pyocr.get_available_tools()
if len(tools) == @:
print("No OCR tool found")
sys.exit(1)
tool = tools[0]
print("Will use tool '%&s'" % (tool.get_name()))
txt = tool.image_to_string(
Image.open("./img/test.jpg"),
lang="eng",
builder = pyocr.builders.TextBuilder(tesseract_layout=6)
)
print(txt)

結果は上々。
ほぼ完璧に画像からの文字起こしに成功している。

日本語の文字起こし

次は日本語の文字起こしもやってみよう。

txt = tool.image_to_string(
	Image.open("./img/test-jpn.jpg"),
	lang="jpn",
	builder = pyocr.builders.TextBuilder(tesseract_layout=6)
)

先ほどのコードを一部(lang=の部分)変更するだけでOK。

また、このままコードを実行すると文字間に不要な空白が入ってしまうため、これを除去するため以下のコードを追記する。

# 日本語の不要な空白を削除
import re
txt = re.sub('([あ-んア-ン一-龥ー、。]) +((?=[あ-んア-ン一-龥ー、。]))',
      r'\1\2', txt)

これでテストコードを実行してみる。

Will use tool 'Tesseract (sh)'
⑮ 歳で熊本から単身大阪へ渡り、囲碁棋士に
なるための修行を積む。学歴は中卒だ。その
後、紆余曲折ありプログラミングを学び職と
する。現在プログラミングや統計、機械学習
の勉強に合わせ、双子の育児に奮闘中。

日本語の文字起こしもかなり高い精度で実現することができた。

※15が丸で括られるのは仕様のようで、現状解決策を探している。