Engineering Bear

野球とエンジニアリングを楽しむブログ

Jupyter上でPyOCRを使える環境を整えて、実際にOCRしてみた

どうも。

最近画像関連でOCRに手を出したので年末年始のこのタイミングでまとめようかなと。(もう成人式も終わってるけど)
まあ、目的は「アプリのプロ野球速報をOCRしたら面白そう」って思いつきで始めたのですが…*1
もともと大学時代に画像処理は少し齧っていたので、改めて触れたいなという気持ちもあったり。

基本的なことについて

OCRとは

OCRとは、「光学文字認識」の英語の頭文字をとったもので、画像の中の文字を文字コードの列(機械が認識できる文字)に変換するソフトウェアのことを指す。(Wikipediaより)

要するに、画像の中から文字列を抽出するソフトってことです。

PyOCRについて

そのOCRPythonで利用しやすくするために作られたライブラリが、PyOCRです。
下記のTesseract-OCRというOCRエンジンを、Pythonでラップしたものです。

Tesseract-OCRとは

縮めて"Tesseract"とも。

OCRのエンジンで、多様なオペレーティングシステム上で動作するオープンソースソフトウェアであり、Apache License 2.0 の下で配布されている。文字認識を行うライブラリと、それを用いたコマンドラインインターフェイスを持つ。(これもWikipediaより)

JupyterでPyOCR

Jupyter NotebookであればPyOCRも同様にわかりやすい形で出力してくれます。
下記画像みたいな感じで(結果はさておき)

f:id:kumappp:20200117173117p:plain
実行例

ちなみに元画像はこちら。野球好きならよく見たことある画像ですね。

f:id:kumappp:20200117173145j:plain
速報画像

リポジトリ情報

ここにプッシュしております。
github.com

環境情報

バージョン情報は下記。

  • Python: 3.6.7
  • PyOCR: 0.7.2
  • tesseract-OCR: 4.0.0-beta.1
  • Jupyter: 4.4.0

作成したDockerfile

作成したDockerfileは下記です。今回はJupyter用イメージを引っ張ってきて、そこにtesseract-OCRを追加するような感じ。

FROM jupyter/datascience-notebook

USER root
RUN sudo apt update && sudo apt -y install tesseract-ocr && \
    apt install tesseract-ocr-jpn && \
    apt install tesseract-ocr-script-jpan
WORKDIR /home/jovyan/work
COPY requirements.txt ./
RUN pip install -r requirements.txt

今回は日本語を抽出したいので、日本語エンジンも併せてインストールします。(tesseract-ocr-jpntesseract-ocr-script-jpan

Jupyterの起動

コンテナを起動すればJupyterも同時に起動するので、下記コマンドでビルドや起動を行えばOK。

ビルド

$ docker build -t sokuho/jupyter .

サーバ起動

$ docker run -v <current_directory>:/home/jovyan/work --name sokuho -p 8888:8888 sokuho/jupyter

コンテナ起動

$ docker start -a sokuho

簡単なPyOCRの実践

とりあえず簡単に作ったコードがこちら

from PIL import Image
import sys
sys.path.append('/path/to/dir')

import pyocr
import pyocr.builders

def print_ocr(img_path,tesseract_layout=3):
    tools = pyocr.get_available_tools()
    if len(tools) == 0:
        print("No OCR tool found")
        sys.exit(1)
    tool = tools[0]

    txt = tool.image_to_string(
        Image.open(img_path),
        lang='jpn',
        builder=pyocr.builders.TextBuilder(tesseract_layout=tesseract_layout)
    )
    print(txt)

PILは、画像の読み込みに必要です。

OCRツールの取得

9~13行目でOCRの実行に必要なツールを取得します。
このツールの中で、下記メソッドを使うことで、利用可能言語データも確認できます。

import pyocr

tools = pyocr.get_available_tools()

tool = tools[0]
langs = tool.get_available_languages()

print(langs)

実行例

['Japanese', 'osd', 'eng', 'jpn']

OCRの実行

ツールのimage_to_string()を利用して、OCRを実行します。
引数については下記。

  1. 画像データ(サンプルだとファイル取得までやってる)
  2. 利用言語(上記利用可能言語参照)
  3. レイアウト解析のオプション(詳細は下記、デフォルトは3)

ちなみに実行結果のサンプルは上の方にある、Jupyterによる出力がそれです。

レイアウト解析のオプション

エンジン内で画像をレイアウト解析する際の挙動をオプションを指定することによってコントロール出来ます。
各オプションの挙動は下記。

  • 0: 方向とスクリプト検出(OSD)のみ。
  • 1: OSDによる自動ページセグメンテーション。
  • 2: 自動ページセグメンテーション(OSDなし)。
  • 3: 完全自動ページセグメンテーション(OSDなし)。(デフォルト)
  • 4: 様々なサイズのテキストの単一列を想定。
  • 5: 垂直に配置されたテキストの単一の均一なブロックを想定。
  • 6: 単一の均一なテキストブロックを想定。
  • 7: 画像を単一のテキスト行として扱う。
  • 8: 画像を単一の単語として扱う。
  • 9: 画像を円の中の1つの単語として扱う。
  • 10: 画像を単一の文字として扱う。
  • 11: スパーステキスト。順不同でできるだけ多くのテキストを検索する。
  • 12: OSDによるスパーステキスト。
  • 13: 生のライン。内部の処理をバイパスしつつ画像内にテキストが1行だけあるものとして扱う。

参考
blog.machine-powers.net
github.com

所感

なんとなく始めたOCRですが、思った以上に壁はでかかったようです。
上の実行例の通り、デフォルトの使用だけだと目的の実現は難しそうですが…
調べたところ、訓練データの精度をあげるツールがあるそうなので、(jTessBoxEditorというらしい)
sourceforge.net
こういうのを触ってみるのもありかもです。*2
あと訓練データ自体も日本語の各フォントに対応したものがあるみたいなので、
その点で調査してみてもいいかもです。
qiita.com

今回は勉強がてらOCRを使ってみたかったのでPyOCRを使いましたが、
単純にOCRを利用したいだけなら各企業が提供しているサービスを利用するのが現実的かな、と。
有名なのはGoogleの「Vision API
cloud.google.com

LINEの「LINE BRAIN OCR」(API公開はまだだそう)
www.linebrain.ai

AmazonAWSサービスの一つ)の「Amazon Textract」(日本語未対応)
aws.amazon.com

速報のスクショをとってOCRエンジンに投げてデータ連携を行う、みたいなことをしたければ
上記APIを使うことになるのかな〜と思います。*3
速報以外にもスクショして画像投げて〜って流れを作れば色々なことが出来そうですね。

以上、お読み頂きありがとうございました〜

*1:データ欲しいだけならスクレイピングとかしたほうがいいと言われました、そりゃそうだ

*2:ただJavaの実行ファイルなのでJavaの環境が必要なんだよなぁ…

*3:単純に速報データがほしけりゃスクレイピング(ry