end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

paddleocr for python による ai ocr

GitHub - PaddlePaddle/PaddleOCR: Turn any PDF or image document into structured data for your AI. A powerful, lightweight OCR toolkit that bridges the gap between images/PDFs and LLMs. Supports 100+ languages. · GitHub

MinerU、chandra に続く、ai ocr。

使いやすさや精度は、paddleocrが最も良い気がします

目次

pip install

OCRライブラリ本体(paddleocr)と、推論エンジン(paddlepaddle-gpu)をinstall

CMD> python3.12\python.exe -m pip install paddleocr
CMD> python3.12\python.exe -m pip install paddlepaddle-gpu==3.3.1 -i https://www.paddlepaddle.org.cn/packages/stable/cu118/
CMD> python3.12\python.exe -m pip install "paddlex[ocr]==3.7.2"

gpuの接続確認

import paddle
paddle.utils.run_check()               # "PaddlePaddle works well on N GPUs" と出ればOK
print(paddle.device.get_device())      # "gpu:0" のように表示される
print(paddle.is_compiled_with_cuda())  # True

↑こうかくと、↓こう表示

C:\Users\end0t\tmp\PADDLE_OCR>python3.12\python.exe chk_gpu.py
Running verify PaddlePaddle program ...
C:\Users\end0t\tmp\PADDLE_OCR\python3.12\Lib\site-packages\paddle\pir\math_op_patch.py:241:
UserWarning: Tensor do not have 'place' interface for pir graph mode, try not to use it.
None will be returned.

  warnings.warn(
I0829 15:04:05.538084 27788 pir_interpreter.cc:1529] New Executor is Running ...
WARNING: Logging before InitGoogleLogging() is written to STDERR
W0829 15:04:05.538084 27788 gpu_resources.cc:116] Please NOTE: device: 0,
  GPU Compute Capability: 8.9, Driver API Version: 13.0, Runtime API Version: 11.8
I0829 15:04:05.768106 27788 pir_interpreter.cc:1552]
  pir interpreter is running by multi-thread mode ...
  
PaddlePaddle works well on 1 GPU.
PaddlePaddle is installed successfully! Let's start deep learning with PaddlePaddle now.
gpu:0  ★
True   ★

PaddleOCR - text抽出のみ

import sys
import time
from paddleocr import PaddleOCR

# Windowsコンソール(cp932)の文字化け対策:標準出力をUTF-8にする
sys.stdout.reconfigure(encoding="utf-8")

# device="gpu:0" でGPU使用(PaddleOCR 3.x系)
ocr = PaddleOCR(lang="japan", device="gpu:0")

img = "sample.png"   # ← 手元の画像パスに変更

t0 = time.time()
result = ocr.predict(img)      # 3.x は predict()
print(f"処理時間: {time.time()-t0:.2f}秒")

# 結果表示(3.x の戻り値形式)
for res in result:
    # テキストとスコアだけを見やすく表示
    for text, score in zip(res["rec_texts"], res["rec_scores"]):
        print(f"{score:.2f}  {text}")

    # 可視化画像は「フォルダ」を指定(複数画像が出力される)
    res.save_to_img("output")
    # 認識結果はJSON(UTF-8)で保存
    res.save_to_json("output")

PPStructureV3 - 文章・図・表の混在文書

from paddleocr import PPStructureV3

pipeline = PPStructureV3(
    lang="japan",
    device="gpu:0",
    use_formula_recognition=False,       # 数式が無い文書なら切る
    use_table_recognition=True,          # 表は使う
    use_doc_orientation_classify=False,  # 傾き分類(不要なら切って高速化)
    use_doc_unwarping=False,             # 歪み補正(不要なら切って高速化)
)

results = pipeline.predict("sample.png")
for res in results:
    res.save_to_markdown("output_structure")  # 表はHTML、図は画像で埋込
    res.save_to_img("output_structure")       # レイアウト枠の可視化
    res.save_to_json("output_structure")      # 全構造データ

PPStructureV3が内部で使うmodel

predict()の初回実行時に以下が自動的にダウンロード

役割 モデル
レイアウト検出 PP-DocLayout_plus-L
テキスト検出/認識 PP-OCRv5_server_det / _rec
表の有線/無線判定 PP-LCNet_x1_0_table_cls
表構造復元 SLANeXt_wired / SLANet_plus
表セル検出 RT-DETR-L_wired/wireless_table_cell_det
数式認識 PP-FormulaNet_plus-L

上記により出力される結果file群

ファイル 内容
sample.md 本命の成果物。表は html table、図はimgs/へ切り出してで埋込
imgs/ 図・表の切り出し画像
sample_layout_det_res.png 領域分割の可視化(先ほど送った画像)
sample_layout_order_res.png 読み取り順序(reading order)
sample_table_cell_img.png 表セル検出の可視化
sample_res.json 全領域の種別・座標・テキスト・表HTML

表のhtmlのみ出力する場合

for res in results:
    for block in res["parsing_res_list"]:
        if block["block_label"] == "table":
            print(block["block_content"])   # 表のHTML

markdownのみ出力する場合

from paddleocr import PPStructureV3
from pathlib import Path
import glob

def main():
    # https://www.paddleocr.ai/main/en/version3.x/pipeline_usage/PP-StructureV3.html
    pipeline = PPStructureV3(
        lang  ="japan",
        device="gpu:0",
        use_formula_recognition     =False,     # 数式
        use_table_recognition       =True,      # 表
        use_doc_orientation_classify=False,     # 傾き分類
        use_doc_unwarping           =False,     # 歪み補正
        # 解析結果に含まれるblock内容を、markdownなどへ出力しやすい様、整形
        format_block_content=True,

        # markdownから除外する要素
        markdown_ignore_labels=[
            "image","figure","header_image","footer_image"],
    )

    Path("output_md").mkdir(exist_ok=True)

    for i, png_path in enumerate(glob.glob("input_trim_png/*.png")):

        basename = Path(png_path).stem
        out_path = Path("output_md") / f"{basename}.md"
        
        print(i, png_path, out_path)
        
        results = pipeline.predict(png_path) # layout解析実行
        markdown_list = []

        for res in results:
            # PPStructureV3が生成したMarkdownを取得
            md_info = res.markdown
            markdown_text = md_info.get("markdown_texts", "")

            markdown_list.append(markdown_text)

        out_path.write_text( "\n\n".join(markdown_list),
                             encoding="utf-8" )


if __name__ == "__main__":
    main()

PaddleOCRVL - 文章・図・表の混在文書 (その2)

PaddleOCRVLの方が高精度版らしいが、私はPPStructureV3の方が高精度に感じました

import sys
import time
from paddleocr import PaddleOCRVL

# Windowsコンソール(cp932)の文字化け対策
sys.stdout.reconfigure(encoding="utf-8")

# VLM(Vision-Languageモデル)ベースの文書パーサ
#   レイアウト検出 + PaddleOCR-VL による認識で、図表・数式込みのMarkdownを生成
pipeline = PaddleOCRVL()

img = "sample.png"

t0 = time.time()
results = pipeline.predict(img)
print(f"処理時間: {time.time()-t0:.2f}秒")

for res in results:
    res.save_to_markdown("output_vl")  # 図表・数式込みのMarkdown
    res.save_to_json("output_vl")      # 構造データ