NDLOCR-Lite は、国立国会図書館が公開している日本語OCRです。図書・雑誌等のデジタル化画像からテキストを抽出でき、レイアウト認識(DEIM)と文字認識(PARSeq)を組み合わせた構成になっています。
ndlocr-lite コマンドでCLIから使えますが、バッチ処理パイプラインに組み込んだり、認識結果をプログラム内で直接扱いたい場合には、Pythonからライブラリとして呼び出す方がやりやすいです。
ただし、NDLOCR-Lite はライブラリとしてのAPIが公開されておらず、CLIのエントリポイントを内部的に呼び出す形になります。この記事ではその方法を記録します。
環境構築
Python 3.10 以上が必要です。macOS の場合、システムの Python は 3.9 系のことがあるため、Homebrew 等で 3.12 をインストールしておきます。
brew install python@3.12
pip でのインストール時に externally-managed-environment エラーが出るため、venv 環境を使います。
python3.12 -m venv venv
source venv/bin/activate
pip install git+https://github.com/ndl-lab/ndlocr-lite.git
初回インストール時に ONNX モデル(約160MB)も含めてダウンロードされます。
CLIの構造
NDLOCR-Lite のCLIエントリポイント(ndlocr-lite コマンド)は、内部的には ocr.main() を呼んでいます。main() は argparse で引数をパースし、ocr.process(args) に渡すだけのラッパーです。
ndlocr-lite コマンド
→ ocr.main()
→ argparse で Namespace を構築
→ ocr.process(args) を実行
つまり、argparse.Namespace を自前で組み立てれば、ocr.process() を直接呼び出せます。
スクリプトからの呼び出し
import argparse
import os
from pathlib import Path
import ocr
def run(image_path: str, output_dir: str, viz: bool = False):
base_dir = Path(ocr.__file__).parent
args = argparse.Namespace(
sourcedir=None,
sourceimg=image_path,
output=output_dir,
viz=viz,
det_weights=str(base_dir / "model" / "deim-s-1024x1024.onnx"),
det_classes=str(base_dir / "config" / "ndl.yaml"),
det_score_threshold=0.2,
det_conf_threshold=0.25,
det_iou_threshold=0.2,
simple_mode=False,
rec_weights30=str(base_dir / "model" / "parseq-ndl-16x256-30-tiny-192epoch-tegaki3.onnx"),
rec_weights50=str(base_dir / "model" / "parseq-ndl-16x384-50-tiny-146epoch-tegaki2.onnx"),
rec_weights=str(base_dir / "model" / "parseq-ndl-16x768-100-tiny-165epoch-tegaki2.onnx"),
rec_classes=str(base_dir / "config" / "NDLmoji.yaml"),
device="cpu",
)
ocr.process(args)
if __name__ == "__main__":
os.makedirs("output", exist_ok=True)
run("input.jpg", "output")
モデルや設定ファイルのパスは、ocr.__file__(パッケージのインストール先)を起点に解決しています。これにより、venv の場所に依存しません。
出力ファイル
入力画像のファイル名が input.jpg の場合、出力ディレクトリに以下のファイルが生成されます。
| ファイル | 内容 |
|---|---|
input.txt | 認識テキスト(行ごとに改行区切り) |
input.xml | レイアウト構造付きXML(バウンディングボックス、クラス情報、認識テキスト) |
input.json | JSON形式(バウンディングボックス座標、テキスト、信頼度、縦書き判定フラグ) |
viz=True にすると、検出領域を青枠で重ねた可視化画像 viz_input.jpg も出力されます。
JSON の構造は以下のようになっています。
{
"contents": [
{
"boundingBox": [x1, y1, x2, y2],
"text": "認識されたテキスト",
"confidence": 0.95,
"isVertical": true
}
],
"imginfo": {
"img_width": 1024,
"img_height": 768,
"img_path": "input.jpg"
}
}
バッチ処理で結果を後続のプログラムに渡す場合は、JSON 出力を読み込むのが扱いやすいです。
引数のカスタマイズ
主要な引数は以下の通りです。
| 引数 | デフォルト | 説明 |
|---|---|---|
sourceimg | — | 単一画像のパス |
sourcedir | — | 画像ディレクトリのパス(配下の画像を一括処理) |
output | — | 出力ディレクトリ |
viz | False | 可視化画像の出力 |
device | "cpu" | "cuda" でGPU推論(要 onnxruntime-gpu) |
simple_mode | False | 単一モデルでの認識(通常は文字数に応じて3モデルを切り替え) |
det_score_threshold | 0.2 | 検出スコアの閾値 |
sourcedir を指定すると、ディレクトリ内の画像(jpg, png, tiff, jp2, bmp)をまとめて処理できます。その場合 sourceimg は None にします。
注意点
ocr.process()は公開APIではなく、内部実装に依存した呼び出し方です。NDLOCR-Lite のバージョンアップで引数の構成が変わる可能性があります- テキスト出力(
.txt)は、縦書き行が50%を超える場合に行順が反転される処理が入っています - 文字認識は、予測される文字数に応じて30文字・50文字・100文字用の3つのモデルが自動的に切り替わります(
simple_mode=Trueで単一モデルに固定可能)