はじめに(イントロダクション)
PaddleOCR は、Baidu が開発しているオープンソースの OCR(Optical Character Recognition:光学文字認識)ライブラリで、画像や PDF からテキストを抽出することに特化したツールです。
日本語を含む 100 を超える言語に対応し、通常の文書画像だけでなく、傾き・歪み・スマホ撮影など、現実世界の様々なシーンに強いことが特徴です。
このガイドでは、初心者の方でも安心して学べるように、PaddleOCR の基本用語から実用的なコード例までを 15 章構成で物語のように丁寧に解説していきます。
第1章 PaddleOCR とは何か
PaddleOCR は、ディープラーニングフレームワーク PaddlePaddle 上に構築された軽量かつ高精度な OCR ツールキットで、テキスト検出・文字認識・レイアウト解析など複数のモデルを組み合わせて動作します。
特に PP-OCR シリーズと呼ばれるモデル群は、通常文書・スキャン・スマホ撮影・歪み画像など多様な場面に最適化されており、簡単な Python API を通じて一行のコードで実行できるよう設計されています。
# PaddleOCR の基本的な使い方イメージ
from paddleocr import PaddleOCR
# 日本語と英語を扱う OCR インスタンスを作成
ocr = PaddleOCR(lang="japan", use_angle_cls=True)
# 画像からテキストを抽出
img_path = "sample.jpg"
result = ocr.ocr(img_path)
for line in result:
for box, (text, score) in line:
print(f"文字列: {text}, 信頼度: {score:.3f}")
第2章 OCR の基本用語を理解しよう
OCR の世界では、テキストを探す「検出(detection)」、見つけた部分を読む「認識(recognition)」、ページの構造を理解する「レイアウト解析(layout analysis)」など、いくつか重要な用語が登場します。
PaddleOCR では、テキスト検出モデル・文字認識モデル・向き判定モデル・テーブル構造認識モデルが連携して動作し、それぞれが画像中の文字の位置や向き、表のセル構造などを把握することで、より正確なテキスト抽出を実現しています。
from paddleocr import PaddleOCR
# 検出+認識の一体型パイプライン
ocr = PaddleOCR(lang="japan", use_angle_cls=True)
result = ocr.ocr("document.jpg", cls=True)
for line in result:
for bbox, (text, score) in line:
# bbox は [左上, 右上, 右下, 左下] の4点座標
print("検出領域座標:", bbox)
print("認識文字列:", text)
print("スコア:", score)
print("------")
第3章 インストールと環境構築
PaddleOCR を使うには、まず Python 環境と必要なライブラリをインストールする必要があります。
多くの場合、pip コマンドで PaddleOCR と依存関係を一括インストールでき、GPU があればさらに高速に処理できるように CUDA や cuDNN をセットアップすることで大規模なバッチ処理にも対応できます。
# 仮想環境の作成と有効化(任意)
python -m venv venv
source venv/bin/activate # Windows の場合は venv\Scripts\activate
# PaddlePaddle(CPU版)のインストール
pip install "paddlepaddle==2.6.0" -i https://mirror.baidu.com/pypi/simple
# PaddleOCR 本体のインストール
pip install "paddleocr>=2.7"
# 動作確認用の簡単なスクリプト
python - << 'PY'
from paddleocr import PaddleOCR
ocr = PaddleOCR(lang="japan")
print("PaddleOCR が正しくインポートできました")
PY
第4章 はじめての文字認識 ― 画像から文字を読む
環境が整ったら、まずは一枚の画像から文字を読み取るシンプルな例に挑戦します。
画像ファイルのパスを指定して ocr.ocr() を呼び出すだけで、画像中のテキストごとに座標と文字列、信頼度スコアが返ってきて、その結果をループで表示すれば簡単なテキスト抽出ツールとしてすぐに利用できます。
from paddleocr import PaddleOCR
# 日本語対応 OCR インスタンスを作成
ocr = PaddleOCR(lang="japan", use_angle_cls=True)
# 解析したい画像
img_path = "signboard.jpg"
# OCR の実行(cls=True で向き補正も有効化)
result = ocr.ocr(img_path, cls=True)
texts = []
for line in result:
for box, (text, score) in line:
if score > 0.5: # 信頼度が一定以上のものだけを採用
texts.append(text)
print(f"{text} (score={score:.2f})")
print("結合したテキスト:")
print(" ".join(texts))
第5章 出力結果の構造とボックス座標の扱い
PaddleOCR の出力は入れ子構造のリストで、各要素には四角形の座標と文字列・スコアのペアが含まれます。
座標は画像内の 4 点(左上・右上・右下・左下)として返されるため、その値を利用して描画ライブラリ(Pillow や OpenCV)上にバウンディングボックスを描けば、どの位置でどの文字が認識されたかを視覚的に確認できます。
from paddleocr import PaddleOCR, draw_ocr
from PIL import Image
ocr = PaddleOCR(lang="japan", use_angle_cls=True)
img_path = "page.jpg"
result = ocr.ocr(img_path, cls=True)
# 画像の読み込み(Pillow)
image = Image.open(img_path).convert("RGB")
boxes = []
texts = []
scores = []
for line in result:
for box, (text, score) in line:
boxes.append(box)
texts.append(text)
scores.append(score)
# PaddleOCR 付属の描画ユーティリティで結果を描画
annotated_img = draw_ocr(image, boxes, texts, scores, font_path="path/to/japanese_font.ttf")
annotated_img.save("page_annotated.jpg")
第6章 日本語 OCR に特化した設定
PaddleOCR は 100 以上の言語に対応しており、日本語用には lang="japan" を指定します。
日本語モデルは縦書き・横書きや全角・半角の混在にも強く、use_angle_cls=True で文字列の向きを自動判定し、逆さ向きのテキストも正しい方向に補正してから認識するため、実務での書類スキャンや掲示物の読み取りに非常に適しています。
from paddleocr import PaddleOCR
# 日本語+英数字対応、向き判定つき
ocr = PaddleOCR(
lang="japan",
use_angle_cls=True, # 行の向きを補正
det=True, # テキスト検出を有効化(デフォルトで True)
rec=True # 文字認識を有効化
)
img_path = "receipt_jp.png"
result = ocr.ocr(img_path, cls=True)
for line in result:
for box, (text, score) in line:
print(f"{text}\t({score:.3f})")
第7章 PDF や複数ページ文書の読み取り
紙の書類をスキャンした PDF を処理したい場面では、ページごとに画像へ変換してから PaddleOCR で解析する流れが一般的です。
Python では pdf2image ライブラリを利用して PDF を画像に分解し、それぞれのページをループしながら OCR をかけてテキストをテキストファイルや CSV に保存することで、帳票やレポートを一括でデジタルデータに変換できます。
from paddleocr import PaddleOCR
from pdf2image import convert_from_path
import pathlib
ocr = PaddleOCR(lang="japan", use_angle_cls=True)
pdf_path = "report.pdf"
out_dir = pathlib.Path("pdf_images")
out_dir.mkdir(exist_ok=True)
# PDF をページごとに画像へ変換
pages = convert_from_path(pdf_path, dpi=200)
all_texts = []
for i, page in enumerate(pages):
img_path = out_dir / f"page_{i+1}.png"
page.save(img_path, "PNG")
result = ocr.ocr(str(img_path), cls=True)
page_texts = []
for line in result:
for _, (text, score) in line:
if score > 0.5:
page_texts.append(text)
all_texts.append("\n".join(page_texts))
with open("report_ocr.txt", "w", encoding="utf-8") as f:
f.write("\n\n---- Page Break ----\n\n".join(all_texts))
第8章 レイアウト解析とテーブル認識の活用
複雑な帳票や雑誌レイアウトを扱う場合、ページ全体の構造を理解する「レイアウト解析」や、表のセル構造を抽出する「テーブル構造認識」が重要になります。
PaddleOCR 3.0 系では、レイアウト検出モデルがページをテキスト・表・図・タイトルなどに分割し、さらにテーブル構造認識モデルがセルの行列関係を復元して Markdown や HTML 形式で出力できるため、BI ツールやデータ分析への橋渡しが容易になります。
from paddleocr import PaddleOCR
# レイアウト解析とテーブル検出を有効にした OCR
ocr = PaddleOCR(
lang="japan",
use_angle_cls=True,
layout=True, # レイアウト解析(対応バージョンで有効)
table=True # テーブル構造認識
)
img_path = "invoice_table.png"
result = ocr.ocr(img_path, cls=True)
# テーブル構造情報を含む結果を抽出(実際のキー名はバージョンによって異なる)
tables = []
for line in result:
for box, (text, score) in line:
# 本例では単純に全テキストを収集している
tables.append(text)
print("テーブルから抽出された文字列:")
print("\n".join(tables))
第9章 コマンドラインツールとして使う
PaddleOCR には Python API だけでなく、コマンドラインから実行できるスクリプトも用意されているため、簡単なバッチ処理やシェルスクリプトからの呼び出しにも向いています。
CLI 版では、モデルのダウンロードと推論を自動的に行い、入力画像と同じフォルダに結果のテキストや可視化画像を保存できるので、プログラミングに不慣れなメンバーともファイル単位で結果を共有しやすくなります。
# 画像一枚を日本語モデルで OCR し、結果を表示
paddleocr \
--image_dir ./sample.jpg \
--lang japan \
--use_angle_cls true \
--use_gpu false
# ディレクトリ内の複数画像を一括処理
for img in ./images/*.png; do
paddleocr --image_dir "$img" --lang japan --use_angle_cls true
done
第10章 速度と精度のチューニング
実運用では、「できるだけ速く処理したい」「でも精度も落としたくない」というトレードオフに向き合うことになります。
PaddleOCR では入力解像度・バッチサイズ・モデルサイズ(軽量版か高精度版か)・GPU 利用有無などを調整することで、数十ページの PDF をバッチ処理したり、リアルタイムにカメラ映像を解析したりと、要件に合わせたチューニングが可能です。
from paddleocr import PaddleOCR
# 軽量モデルを選び、バッチサイズを大きめにして高速化
ocr = PaddleOCR(
lang="japan",
use_angle_cls=True,
rec_batch_num=8, # 認識バッチサイズ
det_db_score_mode="fast"
)
img_paths = [f"frame_{i}.jpg" for i in range(1, 11)]
for img_path in img_paths:
result = ocr.ocr(img_path, cls=True)
print(f"{img_path} の文字数: {sum(len(line) for line in result)}")
第11章 エラー処理と例外への向き合い方
現場で運用すると、壊れた画像ファイル・読み込み権限のないパス・日本語フォント未設定など、さまざまなエラーに遭遇します。
try-except 構文でエラーを適切に捕捉し、問題のあったファイル名と原因をログに残しておくことで、バッチ処理中に一つの失敗が全体を止めてしまう事態を防ぎ、後から再処理や原因調査をしやすくなります。
from paddleocr import PaddleOCR
import logging
from pathlib import Path
logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
ocr = PaddleOCR(lang="japan", use_angle_cls=True)
image_dir = Path("batch_images")
for img_path in image_dir.glob("*.png"):
try:
logging.info(f"処理中: {img_path}")
result = ocr.ocr(str(img_path), cls=True)
# ここで結果を保存するなどの処理を書く
except Exception as e:
logging.error(f"失敗: {img_path} - 理由: {e}")
第12章 アプリケーションへの組み込み ― Flask による簡易 Web API
PaddleOCR をバックエンドとして、社内ツールや Web アプリから画像をアップロードして文字認識を行う API を提供することもできます。
Flask などの軽量 Web フレームワークと組み合わせれば、単一のサーバープロセスに OCR モデルをロードし続けておき、HTTP 経由のリクエストごとに画像を受け取りテキストを JSON で返す簡易 OCR サービスを短いコードで構築できます。
from flask import Flask, request, jsonify
from paddleocr import PaddleOCR
import tempfile
app = Flask(__name__)
ocr = PaddleOCR(lang="japan", use_angle_cls=True)
@app.route("/ocr", methods=["POST"])
def ocr_endpoint():
if "file" not in request.files:
return jsonify({"error": "file フィールドがありません"}), 400
file = request.files["file"]
with tempfile.NamedTemporaryFile(suffix=".png") as tmp:
file.save(tmp.name)
result = ocr.ocr(tmp.name, cls=True)
lines = []
for line in result:
for _, (text, score) in line:
lines.append({"text": text, "score": float(score)})
return jsonify({"results": lines})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
第13章 ONNX や他フレームワークとの連携
推論環境を軽量化したい場合や、既存の推論基盤に統一したい場合には、PaddleOCR モデルを ONNX 形式へ変換して利用するアプローチがあります。
ONNX Runtime を用いれば、Python 以外の言語やエッジデバイスでも同じモデルを実行できるようになり、Paddle 依存部分を排除したサンプルコードも公開されているため、組み込みや既存システムとの統合を検討しているチームにとって有力な選択肢となります。
import onnxruntime as ort
import numpy as np
import cv2
# 例: PaddleOCRv3 の検出モデルを ONNX 化したファイルを読み込む
det_session = ort.InferenceSession("det_model.onnx", providers=["CPUExecutionProvider"])
# 前処理(実際の前処理手順はモデルに依存)
img = cv2.imread("sample.jpg")
input_blob = cv2.resize(img, (960, 960))
input_blob = input_blob.transpose(2, 0, 1).astype("float32") / 255.0
input_blob = np.expand_dims(input_blob, axis=0)
# 推論実行
outputs = det_session.run(None, {"x": input_blob})
# outputs を解析してテキスト領域の座標を取得し、続けて認識モデルに渡す
print("検出モデルの出力数:", len(outputs))
第14章 事例で学ぶ ― 日本語 PDF レポートの自動集計
たとえば、毎月届く日本語の PDF レポートから売上表を抜き出して集計したい、という業務を考えてみましょう。
PaddleOCR の PDF 解析・テーブル認識・日本語モデルを組み合わせれば、レポートを自動的に画像化し、売上表だけを抽出して CSV に変換し、さらに pandas で月ごとの合計や平均を算出する一連の処理を完全自動化することができます。
from paddleocr import PaddleOCR
from pdf2image import convert_from_path
import csv
ocr = PaddleOCR(lang="japan", use_angle_cls=True, table=True)
pdf_path = "monthly_sales.pdf"
pages = convert_from_path(pdf_path, dpi=200)
rows = []
for i, page in enumerate(pages):
img_path = f"sales_page_{i+1}.png"
page.save(img_path, "PNG")
result = ocr.ocr(img_path, cls=True)
for line in result:
row = []
for _, (text, score) in line:
if score > 0.5:
row.append(text)
if row:
rows.append(row)
with open("monthly_sales.csv", "w", encoding="utf-8", newline="") as f:
writer = csv.writer(f)
writer.writerows(rows)
第15章 これからの PaddleOCR とドキュメント AI の世界
PaddleOCR 3.0 では、文書解析とテキストスポッティングに特化した PaddleOCR-VL-1.5 というビジョン・ランゲージモデルが加わり、図表や数式を含む複雑なドキュメントの理解力が大きく向上しています。
今後は OCR が単に文字を読むだけでなく、レイアウト構造や意味情報を踏まえて LLM と連携し、「請求書から支払期限と金額を抽出して自動登録する」といった高度なドキュメント AI へと発展していくことが期待されており、PaddleOCR はその土台となる重要なコンポーネントとして進化し続けています。
# 将来像のイメージコード(擬似的な例)
from paddleocr import PaddleOCR
from some_llm_client import ask_llm # 仮の LLM クライアント
ocr = PaddleOCR(lang="japan", use_angle_cls=True, layout=True, table=True)
img_path = "invoice_future.png"
result = ocr.ocr(img_path, cls=True)
texts = []
for line in result:
for _, (text, score) in line:
if score > 0.5:
texts.append(text)
prompt = """
以下は請求書から OCR で抽出したテキストです。
支払期日と税込み合計金額を JSON 形式で抽出してください。
""" + "\n".join(texts)
answer = ask_llm(prompt)
print(answer)