みなさん、こんにちは。
Pythonを使ってOCR(光学文字認識)をされている方なら、一度はTesseractOCRにお世話になったことがあるのではないでしょうか?手軽で便利ですよね。
でも、「画像の前処理によって、認識精度が全然安定しない…」なんてお悩みはありませんか?私もまさにその一人でした。ほんの少し環境が変わるだけで、結果が大きくブレてしまうのが長年の悩みだったんです。
そんなときに出会ったのが、今回ご紹介するPaddleOCRです!中国のBaidu社が開発した、ディープラーニングベースのOCRエンジンで、ここ数年で一気に人気が出てきています。
「よし、乗り換えてみよう!」と意気込んで、いざ日本語情報を探してみると、あれ?情報が古い?!
2025年8月15日にリリースされた最新のv3.1.1でチャレンジしてみたところ、ネット上の情報がうまく当てはまらないことが多いんです。
そこで今回は、TesseractOCRからPaddleOCR v3.1.1への移行を試み、無事にやり遂げた私が、その重要なポイントと注意点をギュッとまとめてみました。この記事を読めば、これから移行する人にとってハマる心配がなくなるかも!
なお、今回の私の環境は、Windows Server 2019、Python 3.10.11です。ぜひご自身の環境に合わせて読み進めてみてくださいね。
1. 依存関係の変更
まずは、環境をきれいにするところから始めます。TesseractOCR関連のライブラリはもう必要ないので、きっぱり削除してしまいます。
削除する依存関係
pyocr
: TesseractOCRのPythonライブラリPIL.Image
:pyocr
での画像処理用tesseract-ocr
: システムレベルのTesseractインストール
そして、新しくPaddleOCRに必要なものをインストールします。GPUを使う方は、paddlepaddle
の代わりにpaddlepaddle-gpu
をインストールしてくださいね。
追加する依存関係
pip install paddleocr==3.1.1
pip install paddlepaddle # CPU版
# または
pip install paddlepaddle-gpu # GPU版
2. インポート文の変更
次に、Pythonスクリプトの冒頭部分を書き換えます。
変更前(TesseractOCR)
import pyocr
import pyocr.builders
import PIL.Image as Image
tools = pyocr.get_available_tools()
tool = tools[0]
変更後(PaddleOCR)
from paddleocr import PaddleOCR
import warnings
import logging
# 警告とログの無効化
warnings.filterwarnings('ignore')
logging.getLogger('paddleocr').setLevel(logging.ERROR)
logging.getLogger('paddlex').setLevel(logging.ERROR)
logging.getLogger('ppocr').setLevel(logging.ERROR)
PaddleOCRはデフォルトでたくさんのログを出力するので、上のコードで警告やログを非表示にすると、コンソールがスッキリして見やすくなります。
3. 画像前処理の変更
ここはTesseractOCRからPaddleOCRに移行する上での最大のメリットかもしれません。Tesseractでは画像のノイズ除去や二値化など、細かな前処理が必要でしたが、PaddleOCRは前処理がほぼ不要です!
TesseractOCR(複雑な前処理が必要)
# グレースケール変換
img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# ノイズ除去
img_blur = cv2.medianBlur(img_gray, 5)
# 2値化
ret, img_blur = cv2.threshold(img_blur, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# PIL形式に変換
image_pil = Image.fromarray(img_blur)
PaddleOCR(最小限の前処理)
# OpenCV形式の画像をそのまま使用可能
# リサイズのみ(必要に応じて)
if height <= 50:
rs_img = cv2.resize(image, (width*4, height*4), interpolation=cv2.INTER_CUBIC)
なんと、OpenCVで読み込んだ画像をそのまま渡すだけでOKなんです。これだけでコードがぐっとシンプルになりますね。
4. OCR実行と結果データの取得
実行方法と結果の形式も大きく変わります。Tesseractは文字列を直接返してくれましたが、PaddleOCRはJSON形式のデータを返してくれます。この中に、認識した文字列や信頼度、座標情報など、すべての情報が入っています。
TesseractOCR
txt = tool.image_to_string(
image_pil,
lang="eng",
builder=pyocr.builders.TextBuilder(tesseract_layout=6)
)
PaddleOCR 3.1.1
# 実行
result = ocr_engine.predict(image)
# JSON形式の結果を解析
if result and isinstance(result, list) and len(result) > 0:
result_data = result[0]
if 'rec_texts' in result_data and 'rec_scores' in result_data:
rec_texts = result_data['rec_texts']
rec_scores = result_data['rec_scores']
# 信頼度でフィルタリングもできちゃいます
high_confidence_texts = []
for text, score in zip(rec_texts, rec_scores):
if score >= 0.7: # 信頼度70%以上
high_confidence_texts.append(text)
結果の解析が必要になりますが、信頼度を使ってフィルタリングできるのはとても便利です。精度が低い結果を最初から除外できるので、後処理が楽になりますね。
5. パフォーマンス最適化とモデル管理
ここは、安定した運用を目指す上でとても重要なポイントです。
遅延初期化パターン
PaddleOCRは、初めて使うときにモデルを読み込むため、少し時間がかかります。そこで、必要なときにだけエンジンを初期化する「遅延初期化」パターンがおすすめです。
Python
_ocr_engines = {}
def get_ocr_engine(target_type):
engine_key = f"type_{target_type}"
if engine_key in _ocr_engines:
return _ocr_engines[engine_key]
# 初回のみエンジンを初期化
engine = PaddleOCR(...)
_ocr_engines[engine_key] = engine
return engine
これで、複数のOCRタイプを使う場合でも、メモリの無駄遣いを防ぎ、起動時間を短縮できます。
ローカルモデルの事前準備
PaddleOCRは、初回実行時にインターネットからモデルを自動でダウンロードしてくれます。しかし、毎回ダウンロードすると時間がかかったり、ネットワーク環境に左右されたりします。
これを避けるために、あらかじめモデルをダウンロードしておき、ローカルパスを指定してOCRエンジンを初期化しましょう。
# ❌ langで指定してしまうと毎回ダウンロードが発生する
ocr = PaddleOCR(lang='en')
# ✅ model_dirを指定するとローカルモデルを使用してくれる
ocr = PaddleOCR(
text_detection_model_dir="./models/PP-OCRv5_mobile_det",
text_recognition_model_dir="./models/PP-OCRv5_mobile_rec"
)
この方法なら、オフライン環境でも使えますし、起動も速く、安定して動作します。
まとめ
TesseractOCRからPaddleOCRへの移行は、単なるライブラリの置き換えではありません。画像前処理の簡素化や、信頼度付きの結果取得など、アーキテクチャレベルでの改善が期待できます。
最初は少し戸惑うかもしれませんが、今回ご紹介したポイントを押さえておけば大丈夫です。ぜひPaddleOCRの優れた認識精度と安定性を体験してみてくださいね!
本日も最後までお読みいただき、ありがとうございました。
それでは、よいOCRライフを!