日本語OCRツールとして
- ndlocr-lite(国立国会図書館)
- pytesseract(Tesseract)
を比較しました。
どちらも GPU不要で動作する軽量OCRであり、一般的なPCでも実行可能です。
今回は 縦書き日本語文書を対象に、実際のOCR結果を比較してみます。
比較対象
| ツール | 概要 |
|---|---|
| ndlocr-lite | 国立国会図書館が公開している軽量OCR |
| pytesseract | GoogleのTesseractをPythonから利用するラッパー |
ndlocr-lite
NDLOCR-Liteは国立国会図書館が公開しているOCRツールです。
旧NDLOCRはGPUが必要でしたが、
ndlocr-liteはCPUのみで動作する軽量版として開発されています。
GitHub
https://github.com/ndl-lab/ndlocr-lite
インストール(Ubuntu 24.04)
# リポジトリ取得
git clone https://github.com/ndl-lab/ndlocr-lite
cd ndlocr-lite
# 仮想環境作成
python3 -m venv .venv
source .venv/bin/activate
# 依存パッケージ
pip install -r requirements.txt
pytesseract
pytesseractはGoogleが開発したOCRエンジン Tesseract
をPythonから利用するライブラリです。
Ubuntu24.04での導入は次のとおりです。
sudo apt install tesseract-ocr # tesseract-ocrをインストール
# 仮想環境を設置
python3 -m venv .venv
source .venv/bin/activate
# pytesseractとpillowをpipでインストール
pip install pytesseract
pip install pillow
OCRの実行
# ndlocr-lite
python3 -m venv .venv
source .venv/bin/activate
mkdir text
python src/ocr.py --sourcedir pic --output text
# pytesseract
python3 -m venv .venv
source .venv/bin/activate
python OCRpytesseract.py --input pic --output output
pytesseract ではこれを実行するためのpythonプログラム(OCRpytesseract.py)を別途書いています。OCRpytesseract.pyの中身は付録で紹介します。
OCR結果
今回読み込んだ画像はこちらの『厚沢部町史桜鳥1巻』です。
ndlocr-lite
この年間には久遠 (大成) 方面の場所で、 海産干場を利用しての野菜畑が作られていたという。
正徳年間(一七一一~一五)
将軍職を家継がついだ。新井白石の「読史余論」、わが国最初の百科辞書ともいうべき「和漢三才図絵」などが著
わされた。
ロシヤが千島に入り一島を占拠するという北辺の風雲が起こりはじめていた。(のち赤蝦夷禍が世論をわかし、外
交問題になっていくのであった。)
亀田の赤川に三鳥神社が建ち、木ノ子に稲荷社、上ノ国に観音堂・弁才天社、江差の五勝手に観音堂・神明社・庚
申塚、田沢に観音堂・稲荷社が建てられた。
享保年間(一七一六~三五)
目名・えぞ村の堂社
第八代将軍に御三家の紀伊家出の吉宗がなり、将軍家宣・家継によってなし得なかった諸般に
当路部落誕生
わたる改善を断行した。いわゆる享保の改革である。行政・財政・文教・生産増強など各般にわ
たり刷新が試みられた。同十八年正月に米価が上り貧民約千七百人が江戸日本橋の御用米商の高間伝兵衛宅へ押し寄
せ、打ちこわしを行なったが、将軍のお膝元の江戸市中ではじめてのことであっただけに大騒ぎであった。
同五、六年江戸に大火があり、延焼一里以上におよんで十四万戸を焼失するという大損害をうけ十六年、いろは四
七組の町消防を強化した。
松前地方には同二年幕府の巡検使有馬内膳・小笠原三右衛門・高城孫四郎一行が派遣され巡視した。このときの
「享保二年御巡検使御下向申合覚」には「あっさふ夷村」は元禄の郷帳を提出後にできた村と記してある。すでに述
べたように「松前島郷帳」には「目名沢村」より記してない。ところが延宝六年の檜山解放のとき制札をえぞ村に建
てたとの記録があり、また、「津軽一航志」には「しゃも狄入りまじり」と記してあるのでアイヌたちも相当数いた
ことが明らかであるが、郷帳提出後のものとするえぞ村については疑問がある。それは巡検使の応答に対して善処す
るためのことであったかも知れないが、とにかくえぞ村が公書に明記されたのである。
享保二年御巡検使を迎えたときの「申合覚書」によると、領内の和人地の戸口はつぎのとおり記されている。
一、西在郷村数四十一ケ村
此家数千三百八十一軒
人数男女六千九百四十九人
一、東在郷村数三十六ケ村
此家数 八百五十六軒
人数 男女 四千八百六人
、(城下)町数十七ケ町
侍屋舗寺社共に七百二十六軒(内当分空屋舗百一軒)
人数男女三千七百七十五人
これによると西在(松前福山より西方)は東在より村数・戸口が多いこと、城下は東西の要衝の地として人口が密
であったことがわかる。同書に、
、とよべ内沢拾四年已前、鉛山見立、一両年少々鑿し処、是も米払底、殊に其所川水出し而相止申候
とあり、当時江差豊部内の鉛山が、米の不足や、降雨の被害をうけて中止したことを明らかにしている。
四、ヒノキ山開発からの歩み
pytesseract
この年間には久遠(大成)方面の場所で、海産干場を利用しての野菜畑が作られていたという。正徳年-間(一セー一一五)将軍職を家継がついだ。新井白石の「読史余論」、わが国最初の百科辞書ともいうべき「和漢三才図絵」]などが著みされた。
ョシヤが千島に入り一島を占拠するという北辺の風雲が起こりはじめていた。(のお赤昌夷神が世論をわかし、外交問題になっていくのであった。)申塚、田沢に観音堂・稲荷社が巡てられた。享保年間(一セー六ー三五)目名・えぞ村の堂社。第八代将軍に御三家の紀伊家出の吉宗がなり、将軍家官・家継によってなし得なかった庄般に当路部落誕生わたる改善を断行した。
いわゆる事保の改革である。行政・財政・文教・生産増強など各般にわたり股新が試みられた。同十八年正月に米価が上り負民約千百人が江戸日本橋の御用米商の高問伝兵衛宅へ押し寄せ、打ちこわしを行なったが、将軍のお膝元の江戸市中ではじめてのことであっただけに大服ぎであった。同五、六年江戸に大火があり、延焼一里以上におよんで十四万戸を焼失するという大損害をうけ十六年、いろは四寸組の町消防を強化した。松前地方には同二年幕府の巡検使有馬内膳・小笠原三右衛門・高城孫四郎一行が派遣され巡視した。このときの「享保二年御巡検使御下向申合覚」には「あっさよふ夷村」は元禄の郷帳を提出後にできた村と記してある。すでに述べたように「松前島郷帳」には「目名沢村」より記してない。ところが延宝六年の檜山解放のとき制札をえぞ村に建てたとの記録があり、また、「津軽一航志」には「しゃも多入りまじり」と記してあるのでアイヌたちくも相当数いたことが明らかであるが、導帳提出後のものとするえぞ村については疑問がある。それは巡検使の応答に対して善処するためのことであったかも知れわないが、とにかくえぞ村が公書に明記されたのである。享保二年御巡検使を迎えたときの「申合覚書」によると、領内の和人地の戸口はつっぎのとぁり記されている、一、西在郷村数四十一ヶ村此家数千三百八十一軒人数男女六千九百四十九人一、東在郷村数三十六ヶ村此家数八百五十六町.人数男女四千八百六人っ一、(城下)町数十ヒケ町っさむらちいやしきからやしき侍屋舗寺社共に七百二十六軒(内当分空屋結百一軒)人数男女三千七百七十五人これによると西在(松前福山より西方)は東在より村数・戸口が多いこと、城下は東西の要竹の地として人口が密であったことがわかる。同書に、ないいきんみたてほりよふつてい_でやゃやめ一、とよべ内沢拾四年己前、鉛山見立、一両年少し処、是も米払底、殊に其所川水出し面相止申修とあり、当時江差豊部内の鉛山が、米の不足や、降雨の被害をうけて中止したことを明らかにしている。四、ヒノキ山開発からの歩み才
感想
本文内容をみていくと、要所要所でndlocr-liteに軍配が上がるようです。
やはり、縦書き原稿は ndlocr に一日の長があるといえるでしょうか?
比較まとめ
| 項目 | ndlocr-lite | pytesseract |
|---|---|---|
| 導入 | やや手間 | 非常に簡単 |
| OCR精度 | 高い | 普通 |
| 縦書き対応 | 強い | やや弱い |
| 汎用性 | 日本語特化 | 多言語対応 |
縦書き日本語文書のOCRではndlocr-liteの方が精度が高いという結果になりました。
付録:pytesseract用OCRスクリプト
import os
import glob
import argparse
from PIL import Image
import pytesseract
import re
# --- コマンドライン引数の解析 ---
parser = argparse.ArgumentParser(description="OCR処理スクリプト")
parser.add_argument("--input", "-i", type=str, default="pic02", help="入力ディレクトリ (デフォルト: pic02)")
parser.add_argument("--output", "-o", type=str, default="output02", help="出力ディレクトリ (デフォルト: output02)")
args = parser.parse_args()
INPUT_DIR = args.input
OUTPUT_DIR = args.output
LANG = "jpn_vert" # 縦書き日本語モデル(要インストール)
# --- 出力先フォルダを作成 ---
os.makedirs(OUTPUT_DIR, exist_ok=True)
# --- JPGおよびPNGファイル一覧取得(拡張子大小どちらも) ---
img_files = glob.glob(os.path.join(INPUT_DIR, "*.jpg")) + \
glob.glob(os.path.join(INPUT_DIR, "*.JPG")) + \
glob.glob(os.path.join(INPUT_DIR, "*.png")) + \
glob.glob(os.path.join(INPUT_DIR, "*.PNG"))
# --- OCR実行 ---
for img_path in img_files:
try:
# 画像読み込み
img = Image.open(img_path)
# OCR実行(縦書き日本語モデル)
text = pytesseract.image_to_string(img, lang=LANG)
# 出力ファイル名決定
base = os.path.basename(img_path)
name, _ = os.path.splitext(base)
out_path = os.path.join(OUTPUT_DIR, f"{name}.txt")
# テキスト保存
# 余分なスペースを削除(日本語最適化)
# 日本語文字同士の間のスペースをすべて削除
text_cleaned = re.sub(r'([ぁ-ん一-龥々〆〤])\s+([ぁ-ん一-龥々〆〤])', r'\1\2', text)
# 数字・記号と日本語の間のスペースも削除
text_cleaned = re.sub(r'([ぁ-ん一-龥々〆〤])\s+', r'\1', text_cleaned)
text_cleaned = re.sub(r'\s+([ぁ-ん一-龥々〆〤])', r'\1', text_cleaned)
# 空行削除
lines = text_cleaned.split('\n')
text_cleaned = '\n'.join(line for line in lines if line.strip())
with open(out_path, "w", encoding="utf-8") as f:
f.write(text_cleaned)
print(f"[OK] {img_path} → {out_path}")
except Exception as e:
print(f"[ERROR] {img_path}: {e}")
