しまぞうブログ

プログラミングと資産運用

【OCR】文字認識をやってみる【tesseract】

読んだ本の内容をメモして残しておきたいとき、量が多くなるとキーボードで打ち込むのは大変です。

メモしたいページを撮影して、文字認識すればラクかなと思い、Pythonで実際にやってみました。

環境構築

作業環境

  • Windows10
  • Anaconda 4.10(scoopでインストール)
  • Python 3.8

参考にしたサイト

以下のサイトを参考に環境を構築します。

qiita.com

OCRツール

tesseractというOCRツールを使います。
Anacondaからコマンドプロンプトを起動して、以下のコードを打ち込みます。

conda install -c conda-forge tesseract

学習ファイル

文字認識をさせるには対象言語に合った学習データが必要です。

私の場合、「日本語」と「日本語(縦書き用)」を文字認識させますので、以下のサイトから「jpn.traineddata」と「 jpn_vert.traineddata 」をダウンロードします。

GitHub - tesseract-ocr/tessdata_best: Best (most accurate) trained LSTM models.

ダウンロードした学習データは”\envs\(環境名)\Library\bin\tessdata”に格納します(人によって若干異なる場合があります)。
なお、英語の学習データ「eng.traineddata」は、はじめから入っています。

動作確認

環境を整えたら、動作確認します。

テスト用画像

以下のテスト用画像を文字認識させます。

コード

コードはこんな感じです。

from PIL import Image
import sys
import pyocr

class OcrConverter():

    def __init__(self, lang, layout):
        self.tool = self.get_ocr_tool()
        self.lang = lang
        self.layout = layout

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

        return tools[0]

    def get_text(self, src):

        if not (src.endswith(('.png', '.jpg', '.PNG', '.JPG'))):
            print("File type is not image.")
            exit()

        txt = self.tool.image_to_string(
            Image.open(src),
            lang = self.lang,
            builder = pyocr.builders.TextBuilder(tesseract_layout=self.layout))

         return txt


if __name__ == "__main__":

    src = 'sample.png'

    if not (src.endswith(('.png', '.jpg', '.PNG', '.JPG'))): exit()
    
    image_recog = OcrConverter(lang='jpn', layout=6)
    print(image_recog.get_text(src))

OcrConverterクラスに対象言語とレイアウトを引数で渡して、get_textメソッドで文字認識を実行するようにしました。

対象言語とレイアウトは26行目のimage_to_stringメソッドで使用します。

言語(lang)は日本語の横書きなので'jpn'とします。

レイアウト(tesseract_layout)は、対象の画像に適したパラメータの設定が必要です。
以下のサイトの「精度向上」のところに説明が書いてあります。

mstn2050.github.io

今回は横書きのテキストなので"6"にしました。

実行結果

実行すると「あいっえおかがかきぎくけこさしすせそ」となりました。
こんな単純な画像でも微妙にうまくいかない…

もしかしたら何か設定がよくないのかもしれません。これはまた今後の課題ということで…