掲載からしばらく経過したPythonを使って画像データからOCRを行う記事が、当ブログでは人気コンテンツの一つですが、その後の進捗として掲載するに至っておりませんでしたので、あらためて現状の進捗を整理しつつ投稿してみます。
画像形式データ(jpg,tif,png等)からOCRを行えることが確認できましたので、次のテーマとしは、大量に蓄積されている、光学スキャン画像のみで構成されているPDFのOCR情報埋め込み加工処理を目標としました。
紙資料の電子化、として複合機の機能によりPDFデータが容易に生成できるようになった以降、テキスト情報を含まない、A4マルチページ画像データのPDFファイルを保有しているユーザ様からの相談で、これらのファイルをOCR等を使って文字検索ができるようにできないだろうか、という課題にも通じます。
処理の流れは以下で検討してみました。
- 対象のPDFファイルをマルチページtiff形式に変換してみる
- 変換後のマルチページtiffファイルをtesseractでOCRしてpdfで保存
では、作業記録です。
まずは、Windowsで実行するPDF加工の必須環境としてので、Windows版のPopplerをダウンロードしてインストールします。
http://blog.alivate.com.au/poppler-windows/
私は Latest binary : poppler-0.68.0_x86 から入手しました。
Popplerはコマンドプロンプトで実行するタイプのフリーツール群だそうです。使い方を学ぶと、プログラムによりPDFファイルの操作が容易に実現できます。
anacondaプロンプトから、上記のPopplerを利用して、PDFから画像ファイルを生成するライブラリをインストールします。
pip install pdf2image
Popplerインストール後に、環境変数のPathにPopplerの導入先ディレクトリを追加しておかないと、pdf2imageからPopplerが見つけられずエラーが発生しますので忘れずに。
環境は整ったハズなのでサンプルプログラムと結果サンプルです。
from PIL import Image
import sys
import pyocr
import pyocr.builders
from pdf2image import convert_from_path
import re
import subprocess
import os
from pathlib import Path
tools = pyocr.get_available_tools()
tool = tools[0]
langs = tool.get_available_languages()
print("Available languages: %s" % ", ".join(langs))
lang = langs[1]
print("Will use lang '%s'" % (lang))
# 対象PDFファイル名
Nm='vyvo(raw)'
#配置先ディレクトリ
pdf_path = Path("./pdf_file/"+Nm+".pdf")
txt_path = Path("./txt_file/" +Nm + ".txt")
# PDF -> pagesにImageとして変換する(300dpi指定)
# dpiは無意味かも
pages = convert_from_path(str(pdf_path),300)
txt=''
for i, page in enumerate(pages):
txt = txt + tool.image_to_string(page,lang='jpn',builder=pyocr.builders.TextBuilder(tesseract_layout=6))
txt = re.sub('([あ-んア-ン一-龥ー])\s+((?=[あ-んア-ン一-龥ー]))',r'\1\2', txt)
#テキストファイル出力
s = txt
with open(txt_path, mode='w') as f:
f.write(s)
#マルチページのTIFFとして保存する
image_dir = Path("./image_file")
tiff_name = pdf_path.stem + ".tif"
image_path = image_dir / tiff_name
pages[0].save(str(image_path), "TIFF", compression="tiff_deflate", save_all=True, append_images=pages[1:])
# tesseractで生成できるPDFは入力のImageに比例するので、tiff変換で入力より巨大PDFになる可能性高!
cmd = 'tesseract -c include_page_breaks=1 -c page_separator="[PAGE SEPRATOR]" ' + str(image_path) + ' ' + Nm +'_ocr -l jpn pdf'
returncode = subprocess.Popen(cmd)
感想
試行錯誤して何とか動くコードになりましたが、 実験的には成功したものの、 このファイルサイズではとても実用的ではありません。
次回は、入力PDFのサイズにテキスト情報分のファイルサイズ増加程度の結果になる事を目標にしてコードを改良してみます。