TesseractとPyOCRで文字認識する(2021.7.3)

Summary

tesseractをPythonから呼び出してキャプチャ画像から文字認識する

Tesseractコマンドライン版の動作確認

Macへのインストール

下記でインストールできるが、teseractそのものはすでにインストールされていた(いつやったんだ?>俺)

brew install tesseract

言語辞書もインストール

brew install tesseract-lang

以下のコマンドラインオプションで言語の一覧を表示できる

tessearact --list-langs
ls /usr/local/Cellar/tesseract/4.1.1/share/tessdata

いちおう精度重視のデータをダウンロードしておく

【testdata_best/jpn.traineddata】
https://github.com/tesseract-ocr/tessdata_best/blob/master/jpn.traineddataからデータをダウンロードし、“/usr/local/Cellar/tesseract/4.1.1/share/tessdata”にコピーする

【testdata_best/jpn_vert.traineddata】
https://github.com/tesseract-ocr/tessdata_best/blob/master/jpn_vert.traineddataから同じ場所にコピー

コマンドライン版の動作確認

実行

tesseract input.png out -l jpn+eng

なんだかoutと指定するとout.txtというファイル名で出力される。 末尾に勝手に“.txt”が付与されるようだ。

書きかけのMarkdownファイルをキャプチャして認識してみた。

Markdownの画像

結果はこんな感じ(out.txt)。まあまあかも

i

2三

X= —>         B I UYU         H1 H2 H3

# TesseractとPyOCRで文字認識する
(202 1.7.3)

<br>

tesseractをPythonから呼び出してキャプチャ画像から文字認識する

## Mac\OTesseractOf YAR—JbL

下記でインストールできるが、teseractそのものはすでにインストールされ
ていた (いつやったんだ?>俺)

コマンドライン版の動作確認

 

S TesseractとPyOCRで文字認識する(2021.7.3).md

“an                            <>                                   S                            WwW

 

>>

TesseractとPyOCRで文字認識する
(2021.7.3)

Summary

tesseractをPythonから呼び出してキャプチャ画像から文字認識する

MacへのTesseractのインストール

下記でインストールできるが、teseractそのものはすでにインストールさ
れていた (いつやったんだ ?>俺)

brew install tesseract

brew install tesseract-lang
コマンドライン版の動作確認

tessearact --list-langs
実行

tesseract input.png out.txt -l jpnteng

PyOCRから呼び出す

pyocrとpillowをインストールしておく

pip install pyocr
pip install pillow

プログラムはこんな感じ
test_pyocr.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# =======================================================
#  tesseractとpyocrを使って画像ファイルをOCRするスクリプト
#
#  test_pyocr.py
#  coded by Noboru Harada (noboru@ieee.org)
#
#  Changes:
#  2021/07/03: First version
# =======================================================

import os
from PIL import Image
import pyocr

tools = pyocr.get_available_tools()
tool = tools[0]


#open an image file
img = Image.open("./infile.png")

#Read chars from the file
builder = pyocr.builders.TextBuilder(tesseract_layout=6)
text = tool.image_to_string(img, lang="jpn", builder=builder)

print(text)

上記のプログラムを実行するとコマンドライン版とは少し異なる結果となった。

python3 ./test_pyocr.py > out2.txt

結果と考察

コマンドライン版では、文字の領域をあらかじめ区分してからブロックごろに順序をつけてOCR処理が行われているのに対して、pyocrから呼び出した場合には、全体に対して左から右、上から下にOCR処理を行っているように見える。領域をあらかじめ切り出してから処理をするように指定できるのかどうかは不明

( 】                                                     $③ TesseractとPyOCRで文字認識する(2021.7.3) .md
<写 =             B 7 U              H1 H2 H3                呈員民生                2             ぐッ                S、             加                連           >>
ト      ェデミ刃ミド
TesseractとPyOCRで文字認識する
に1「 (0に8 Akでの2                                                                                     (2021 ・7.3)
tesseractをPythonから呼び出してキャプチャ画像から文字認識する                             Summary
tesseractをPythonから呼び出してキャプチャ画像から文字認識する
MacへのTesseractのインストール
下記でインストールできるが、teseractそのものはすでにインストールされ                 _                              、
ていた (いつやったんだ?>俺)                                                                                下記でインストールできるが、teseractそのものはすでにインストールさ
1                                       れていた (いつやったんだ?>俺)
brew install tesseract                                                    CO 論COO
brew 1nsta11 tesseract-]ang
brew install tesseract-lang                                                                コマンドライン版の動作確認
もtessearao --]1st-]angS
コマンドライン版の動作確認
実行
tessearact --list-langs                                                                           tesserao 1nput.png out.もxt -1 ]pn+eng
pl
tesseract input.png out.txt -| jpn+eng

tesseractのsegmentation modesが指定できるらしい。 上記のプログラムでは “builder = pyocr.builders.TextBuilder(tesseract_layout=6)” としていたのでコマンドライン版と結果が違ったのかも。

Page segmentation modes:
  0    Orientation and script detection (OSD) only.
  1    Automatic page segmentation with OSD.
  2    Automatic page segmentation, but no OSD, or OCR. (not implemented)
  3    Fully automatic page segmentation, but no OSD. (Default)
  4    Assume a single column of text of variable sizes.
  5    Assume a single uniform block of vertically aligned text.
  6    Assume a single uniform block of text.
  7    Treat the image as a single text line.
  8    Treat the image as a single word.
  9    Treat the image as a single word in a circle.
 10    Treat the image as a single character.
 11    Sparse text. Find as much text as possible in no particular order.
 12    Sparse text with OSD.
 13    Raw line. Treat the image as a single text line,
       bypassing hacks that are Tesseract-specific.

defaultの“builder = pyocr.builders.TextBuilder(tesseract_layout=3)”を指定し、連続する全角・半角の空白文字列を削除して整形するようにした最終版のプログラムはこんな感じ
test_pyocr2.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# =======================================================
#  tesseractとpyocrを使って画像ファイルをOCRするスクリプト
#
#  test_pyocr.py
#  coded by Noboru Harada (noboru@ieee.org)
#
#  Changes:
#  2021/07/03: First version
# =======================================================

import os
import sys
from PIL import Image
import pyocr
import re

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

tool = tools[0]
#print("Tool found '%s'" % (tool.get_name()))

# Open an image file
img = Image.open("./infile.png")

# Read chars from the file
builder = pyocr.builders.TextBuilder() # use default tesseract_layout=3
#builder = pyocr.builders.TextBuilder(tesseract_layout=6)
#builder = pyocr.builders.TextBuilder(tesseract_layout=3)
text = tool.image_to_string(img, lang="jpn", builder=builder)

# format reguralization for Japanese char-set
text = re.sub('([あ-んア-ン一-龥ー、。]) +((?=[あ-んア-ン一-龥ー、。]))', r'\1\2', text)

# remove multiple spaces
text = re.sub(r'[  \t]+', ' ', text)

# remove leading and trailing space, 2-byte space and tab space
# I found that the reteral '|' is recognized as '\r' on Mac. Why?
text = re.sub(r'^[  \t]+', '', text)
text = re.sub(r'(\| )|([\r\n|\n|\r]) +', r'\1\2', text)

#text = re.sub(r'[\r\n|\n|\r][  \t]+', r'\r', text) # this code is valid only for MacOS


print(text)

プログラムの出力は以下のようになった(out4.txt)

( 】 $③ TesseractとPyOCRで文字認識する(2021.7.3) .md
<写| =ァ B 7 U H1 H2 H3



計を

TesseractとPyOCRで文字語
Summary“<br> (2021 -7.3)

tesseractをPythonから呼び出してキャプチャ画像から文字認識する Summary
tesseractをPythonから呼び出してキャプチャ画像から文字認識する

MacへのTesseractのインストール

下記でインストールできるが、teseractそのものはすでにインストールされに _ 、し、
ていた (いつやったんだ?>俺) 下記でインストールできるが、teseractそのものはすでにインストールさ

れていた (いつやったんだ ?>俺)

b insta11 セも
brew install tesseract rew 1nsta eSSeエac

brew 1nsta11 tesseract-]ang

brew install tesseract-lang コマンドライン版の動作確認

もtessearao --]1st-]angS

コマンドライン版の動作確認


tessearact --list-langs tesserao 1nput.png out.もxt -1 ]pn+eng
Sg

tesseract input.png out.txt -| jpn+eng

蛇足のTips:正規表現によるクレンジング

正規表現パッケージreを用いて、大文字・小文字を含む空白が連続する場合に、半角スペース1個に変換するクレンジング処理を以下のコードで行なっている。このコードでは、カギカッコの中は[全角スペース・半角スペース・タブ]、後ろのシングルクオートの中は半角スペースで、「全角スペース・半角スペース・タブ」のいずれかが1文字以上現れたら、半角スペースに変換する。

text = re.sub(r'[  \t]+', ' ', text)

しかし、これだと行頭・行末にスペースが残ってしまう。
そこで、文字列の先頭および改行コードの直後のスペースを削除するコードを記載した。 Linux, Windows, Macで異なる改行コードに依存せず正しく動作するコードにしたいので、\n (Linux), \r\n (Win), \r (Mac)の全てが記載されている。

text = re.sub(r'^[  \t]+', '', text)
text = re.sub(r'([\n|\r\n|\r]) +', r'\1', text)

最初のr'([\n|\r\n|\r]) +'の一致順序の評価は左から右で、一旦マッチすると次のor条件以降は評価はされないので、\rを最初に書くと上手くいかない。一致条件として後続に半角スペースが無い場合には、。
後半のr'\1'は()丸括弧で囲んだ部分に名前をつけて再度呼び出すためのおまじない。後のr'\1'rがついているのは、。これにより、OSに依存しない改行コードを復元している。

これで完成と思いきや、 |(縦棒)がどうやら改行コードと解釈されてしまうようで、こちらの直後のスペースが削除されるのを回避しないといけないようだ。 ということで、以下のように修正して完成。

text = re.sub(r'^[  \t]+', '', text)
text = re.sub(r'(\| )|([\r\n|\n|\r]) +', r'\1\2', text)

参考

Back to Index