環境
Win10 Pro 64bit
Anaconda
Python = 3.8
Pillow 、OpenCV
インストール
Tesseractのインストール
Tesseract OCR をWindowsにインストールする方法
64bit版をインストール
PyOCRのインストール
PythonでOCRを実行する方法
condanの場合
conda install -c conda-forge pyocr
Tesserractのアプリのパスを通す必要があります。
pyocr 文字認識したい tool でとまる・・・
# 32bit ->
path_tesseract = "C:/Program Files (x86)/Tesseract-OCR"
# 64bit ->
path_tesseract = "C:/Program Files/Tesseract-OCR"
if path_tesseract not in os.environ["PATH"].split(os.pathsep):
os.environ["PATH"] += os.pathsep + path_tesseract
なお、Tesseract OCRのPythonラッパーには、
pyocrとpytesseractなどがあるようです。今回はpyocrの方を使いました。
pytesseractを使ったサンプルプログラム
Tesseract、OpenCV、Pythonを使用したOCR
pyocrを使ったサンプルプログラム
(最終回)Python + OpenCVで遊んでみる(OCR編)
サンプルコード
[Pythonの画像処理ライブラリPillow(PIL)の使い方](Pythonの画像処理ライブラリPillow(PIL)の使い方 | note.nkmk.me)
ImgeファイルをPillowで読み込むと、型はPIL.Image、一方OpenCVで読み込むとndarray
pyocrはPIL.Imgae型で読み込まないとエラーになる。そのためOpenCVで読み込んだ場合、型の変換が必要。
【Python】画像データ(NumPy,Pillow(PIL))の相互変換
Pillow ↔ OpenCV 変換
import os
import pyocr
import pyocr.builders
import cv2
from PIL import Image, ImageOps,ImageDraw
import sys
from matplotlib import pyplot as plt
# 1.インストール済みのTesseractのパスを通す
path_tesseract = "C:\Program Files\Tesseract-OCR"
if path_tesseract not in os.environ["PATH"].split(os.pathsep):
os.environ["PATH"] += os.pathsep + path_tesseract
def cv2pil(image):
'''
[Pillow ↔ OpenCV 変換](https://qiita.com/derodero24/items/f22c22b22451609908ee)
OpenCV型 -> PIL型
'''
new_image = image.copy()
if new_image.ndim == 2: # モノクロ
pass
elif new_image.shape[2] == 3: # カラー
new_image = cv2.cvtColor(new_image, cv2.COLOR_BGR2RGB)
elif new_image.shape[2] == 4: # 透過
new_image = cv2.cvtColor(new_image, cv2.COLOR_BGRA2RGBA)
new_image = Image.fromarray(new_image)
return new_image
def ocr_tool_opencv(file_name,bitwise=True):
"""
using opencv and Pillow
Args:
file_name ([type]): file name str
bitwise (bool, optional): Black and white inversion . Defaults to True.
"""
#利用可能なOCRツールを取得
tools = pyocr.get_available_tools()
if len(tools) == 0:
print("Do not find OCR tools")
sys.exit(1)
#利用可能なOCRツールはtesseractしか導入していないため、0番目のツールを利用
tool = tools[0]
np_image = cv2.imread(file_name)
np_gray_image = cv2.cvtColor(np_image, cv2.COLOR_BGR2GRAY)
# 画像処理
blue = cv2.GaussianBlur(np_gray_image,(5,5),0)
# print(blue.dtype, np_gray_image.dtype) -> uint8
# th_image = cv2.adaptiveThreshold(blue,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
ret , tho = cv2.threshold(blue,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
if bitwise:
tho = cv2.bitwise_not(tho)
# convert to pillow image -> pil.Image型にしないとエラーになる
pil_image = Image.fromarray(tho)
builder_list = pyocr.builders.WordBoxBuilder(tesseract_layout=6)
builder_text = pyocr.builders.TextBuilder(tesseract_layout=6)
# TextBuilder 文字列を認識
# WordBoxBuilder 単語単位で文字認識 + BoundingBox
# LineBoxBuilder 行単位で文字認識 + BoundingBox
# DigitBuilder 数字 / 記号を認識
# DigitLineBoxBuilder 数字 / 記号を認識 + BoundingBox
res = tool.image_to_string(pil_image,lang="eng",builder=builder_list)
res_txt = tool.image_to_string(pil_image,lang="eng",builder=builder_text)
#取得した文字列を表示
print(res_txt)
# WordBoxBuilderを指定するとリスト型が戻り値
# print(type(res))
#以下は画像のどの部分を検出し、どう認識したかを分析
out = cv2.imread(file_name)
for d in res:
print(d.content) #どの文字として認識したか
print(d.position) #どの位置を検出したか
# print(d.position[0], d.position[1])
cv2.rectangle(out, d.position[0], d.position[1], (0, 0, 255), 2) #検出した箇所を囲む
#検出結果の画像を表示
print('quit press key')
cv2.namedWindow("img", cv2.WINDOW_NORMAL)
cv2.imshow("img",out)
cv2.waitKey(0)
cv2.destroyAllWindows()
def ocr_tool_pillow(file_name,bitwise=True):
"""
using Pillow
Args:
file_name ([type]): file name str
bitwise (bool, optional): Black and white inversion . Defaults to True.
"""
#利用可能なOCRツールを取得
tools = pyocr.get_available_tools()
if len(tools) == 0:
print("Do not find OCR tools")
sys.exit(1)
#利用可能なOCRツールはtesseractしか導入していないため、0番目のツールを利用
tool = tools[0]
pil_image = Image.open(file_name)
if bitwise:
npil_image = ImageOps.invert(pil_image.convert('RGB'))
builder_list = pyocr.builders.WordBoxBuilder(tesseract_layout=6)
builder_text = pyocr.builders.TextBuilder(tesseract_layout=6)
res = tool.image_to_string(pil_image,lang="eng",builder=builder_list)
res_txt = tool.image_to_string(pil_image,lang="eng",builder=builder_text)
#取得した文字列を表示
print(res_txt)
# print(type(res))
#以下は画像のどの部分を検出し、どう認識したかを分析
out = Image.open(file_name)
print(out.format, out.size, out.mode)
draw = ImageDraw.Draw(out)
for d in res:
print(d.content) #どの文字として認識したか
print(d.position) #どの位置を検出したか
# print(d.position[0], d.position[1])
draw.rectangle(d.position, outline=(255,0,0) )
#検出結果の画像を表示
out.show()
if __name__ == '__main__':
file_name =" "# 認識したいファイル名を入れてください
# ocr_tool_pillow(file_name,bitwise=False)
ocr_tool_opencv(file_name,bitwise=False)