Stoic Sounds 元はExtroseが運営する個人サイト名

プロフィール

顔写真(V)

Extrose
2002年頃から電脳海にいる。 制作ペースは激減したものの今でも現役の作曲者(自称)であり、機会があればBMSも作る。 が、最近はVを被ってゲーム実況に勤しんでいる。 興味があるものになんでも手を出すのでかなりの趣味を抱えている。

柊 雷夜
ユーチューブ地方で見かけるVのすがた (↑)。 たまに VRChat にも出る。 VRoid Studio 製。

リリース

個人活動

読み物

ITエンジニア関連 - 開発 - Python - PaddleOCR 高精度OCRを使う

概要

OCR (画像読み取ってテキストデータにする) の精度が高い PaddleOCR を使う

環境準備

Python のみでは不足する
Docker 環境の準備をおすすめする

OSコンポーネント側

個人的にDockerの「python:3.13-slim」を使っているため、その環境用
CentOS や Windows 向けにはうまくしてほしい

python:3.13-slim の構築から行う場合は下記の流れ

# ちなみに、Docker で python 3.13 を構築するのは下記コマンド
docker pull python:3.13-slim

# python:3.13-slim に bash で入るコマンド
# rm を入れているので、Ctrl+D などで抜けると対象コンテナは破棄される
docker run --rm -v ${PWD}:/app -w /app python:3.13-slim bash

# インストール前には update しないと中身が無い
apt update

必要コンポーネントの話は下記から

# paddleocr の動作に必要なコンポーネント
apt install -y libgl1 libglib2.0-0 libgomp1

# 無くても動作するが、あると良いもの
apt install -y ccache

# nVidia CUDA を使う場合はもう少し必要なものは多いはずだが、筆者環境はRadeonなので未検証

pip

# メインコンポーネント、PaddleOCR 最低要件
# paddlepaddle (paddleocrのコア部) は、記事執筆(2026/2/15) 時点では 3.0.0 が安定した
pip install paddleocr paddlepaddle==3.0.0

# 任意:応答に numpy 形式が返されるので、分析に必要
pip install numpy

OCRするだけのサンプル

from paddleocr import PaddleOCR

# PaddleOCR インスタンスの作成
ocr = PaddleOCR(
          use_textline_orientation=True,   # 傾き補正
          lang='japan',                    # 日本語文書
          device='cpu'                     # CPU / Radeon 環境で指定する
      )

# 結果を取得する
result = ocr.predict('./blah.jpg')

# テキストデータはrec_texts を参照する
for text in result[0]['rec_texts']:
    print(text)

初回実行時には様々なコンポーネントを入手する
裏では HuggingFaceからAIモデルを入手、生成AI分析をしている ちなみにローカル実行なので情報は収集されない

--rm 環境でも連続実行するときには初回ダウンロードは起きない

結果分析サンプル

# result の後の話
# * Gemini 3-Flash 製
# 先頭に np (numpy) の import を追記すること

# テキストと検出位置のデータを突き合わせる
# rec_texts が文字データ、検出位置が rec_polys に格納されている
# 構造上、データの個数/インデックスは必ず一致する
combined_data = []
for text, poly in zip (result[0]['rec_texts'], result[0]['rec_polys']):

    # 4角の座標の平均をとって、そのテキストの「中心点」を計算する
    center_x = np.mean(poly[:, 0])
    center_y = np.mean(poly[:, 1])

    combined_data.append({
        'text': text,
        'x': center_x,
        'y': center_y,
        'poly': poly
    })

# 座標でソートする(例:まずは上から下(y)、次に左から右(x))
# y座標に少し遊び を持たせる
# 30ピクセルを1行の許容範囲とする例
sorted_data = sorted(
                  combined_data,
                  key=lambda d: (d['y'] // 30, d['x'])
              ) 

# 結果の出力
for item in sorted_data:
    print(f"位置(x={item['x']:.0f}, y={item['y']:.0f}): {item['text']}")

rec_texts の結果は検出順であり、文書の位置で並んでいない
結果を見やすくするために、座標を用いてソートする

ここで numPy が必要となる

ちなみに、このソートが成立するのは文書が正しい向きの場合のみである

おまけ:これを実行する環境の Dockerfile サンプル

# バージョンはお好きに
FROM python:3.13-slim

WORKDIR /app

# レイヤー1: コンポーネントのインストール
# 残骸削除も行う
RUN apt-get update \
    && apt-get install -y libgl1 libglib2.0-0 libgomp1 ccache\
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# レイヤー2: pip install を行う
# 必要なら requirements.txt を持ってくること
RUN pip install paddleocr paddlepaddle==3.0.0 numpy

# レイヤー3: 初回実行させる、後述のスクリプトが必要
COPY paddleocr_init.py .
RUN python ./paddleocr_init.py

# 通常時のコマンド
# 作ったスクリプトに合わせて修正を
COPY main.py .
CMD ["python", "main.py"]

初回実行用ダミースクリプト
実行結果は問わないので、ファイル名は適当で良い

from paddleocr import PaddleOCR
ocr = PaddleOCR(device='cpu')
result = ocr.predict('./dummy')

ビルドは普通に

docker build -t paddleocr .

実行

# 実行するだけなら
docker run --rm paddleocr

# 最初のチェックをスルー
docker run --rm -e PADDLE_PDX_DISABLE_MODEL_SOURCE_CHECK=True paddleocr

# 通常、ocr元のファイルと、出力はマウントした方が良い
# マウント例は下記、スクリプトに合わせて変えること
nerdctl run --rm -v "${PWD}/input:/app/input" -v "${PWD}/output:/app/output" paddleocr