OCR_pdf.py 技術ドキュメント

プログラムの動作

OCR_pdf.py は、PDFファイルから光学文字認識(OCR)を実行し、そのテキストコンテンツを抽出するPythonスクリプトです。このプログラムは、スキャンされたPDFやテキストを選択・コピーできない画像ベースのPDFから、検索可能なテキストを効率的に抽出することを目的としています。

主な機能は以下の通りです。

  • 指定されたPDFファイルの各ページを、一時的に高解像度(デフォルト300DPI)のPNG画像としてレンダリングし、保存します。

  • 保存された一時画像に対してTesseract OCRエンジンを使用して文字認識を実行し、テキストを抽出します。

  • OCR処理が完了した後、ディスクから一時画像を自動的に削除します。

  • 抽出されたすべてのテキストを結合し、標準出力に表示します。

このプログラムは、PDFからテキストデータを取得する必要があるが、既存のテキスト抽出ツールでは対応できない場合に有用です。

原理

このプログラムは、以下のライブラリとアルゴリズムを組み合わせてPDFからのOCRを実現します。

  1. PDFページの画像化: PyMuPDF (ライブラリ名 fitz) を使用して、PDFの各ページを画像としてレンダリングします。具体的には、page.get_pixmap() メソッドが用いられます。OCRの精度を向上させるため、レンダリング時に高解像度を設定しています。デフォルトのPDF解像度72 DPIに対し、300 DPIで画像化するために変換行列 fitz.Matrix(300/72, 300/72) を適用しています。これは、水平・垂直方向の拡大率 \(s\) を以下のように計算して適用することに相当します。

    \[s = \frac{\text{ターゲットDPI}}{\text{デフォルトDPI}} = \frac{300}{72}\]

    この拡大された画像データ(ピックスマップ)は、PNG形式で一時ファイルとして保存されます。

  2. 画像からのOCR: 保存された一時画像は、Pillow (PIL) ライブラリによって読み込まれ、pytesseract ライブラリを介してTesseract OCRエンジンに渡されます。Tesseract OCRは、高度な画像処理とパターン認識アルゴリズムを使用して、画像内の文字を識別し、対応するデジタルテキストに変換します。pytesseract.image_to_string() 関数がこの処理を担い、認識する言語 (lang) を指定することで、特定の言語に最適化された認識を行うことができます。

  3. 一時ファイルの管理: OCR処理の完了後、生成された一時画像ファイルは os.remove() 関数によって直ちに削除されます。また、一時画像を保存するために作成されたディレクトリも、プログラムの finally ブロック内で、内部が空になった場合は os.rmdir() によって削除され、システムのクリーンアップを保証します。

必要な非標準ライブラリとインストール方法

このプログラムを実行するためには、以下のPython非標準ライブラリと、OCRエンジン本体が必要です。

  • Pythonライブラリ:

    • Pillow: 画像処理ライブラリ。

    • PyMuPDF (インストール名 PyMuPDF, import名 fitz): PDFドキュメントを処理するためのライブラリ。

    • pytesseract: Tesseract OCRエンジンのPythonラッパー。

    これらのPythonライブラリは、pip コマンドでインストールできます。

    pip install Pillow PyMuPDF pytesseract
    
  • Tesseract OCRエンジン本体: pytesseract はTesseract OCRエンジンのフロントエンドであるため、Tesseract OCR本体がシステムにインストールされている必要があります。Windows版のTesseract OCRは以下の公式ダウンロードページから入手できます。

    https://tesseract-ocr.github.io/tessdoc/Downloads.html

    インストーラーを実行し、Tesseract OCRをシステムにインストールしてください。通常、インストーラーは実行ファイルのパスを環境変数に追加しますが、追加されない場合は手動で環境変数 PATH にTesseractの実行ファイル(例: C:\Program Files\Tesseract-OCR)のパスを追加する必要がある場合があります。

必要な入力ファイル

プログラムは、OCRを実行するPDFファイルを必要とします。

  • PDFファイル: スクリプトの冒頭で pdf_file = "peak_fit.pdf" と定義されており、デフォルトでは peak_fit.pdf という名前のファイルが期待されます。プログラムを実行するディレクトリにこのファイルが存在している必要があります。 もし指定されたPDFファイルが存在しない場合、__name__ == "__main__" ブロック内で簡単なダミーPDFファイルが作成されます。ただし、これはテスト用であり、実際のOCR処理にはユーザーが用意したPDFファイルを使用することが推奨されます。

生成される出力ファイル

OCR_pdf.py は、PDFからテキストを抽出するために一時ファイルを生成しますが、最終的な出力は標準出力に表示されるテキストデータであり、ファイルとしては保存されません。

  • 一時画像ファイル: OCR処理の過程で、PDFの各ページは一時的にPNG画像として保存されます。これらの画像ファイルは、output_dir 引数(デフォルトは 'pdf_images')で指定されたディレクトリ内に、page_1.png, page_2.png のような命名規則で作成されます。 これらのファイルはOCR処理後に自動的に削除されます。

  • 一時ディレクトリ: 一時画像ファイルを格納するために作成されたディレクトリ(デフォルトは pdf_images)も、プログラムの実行完了後、またはエラー発生時であっても、内部のファイルが全て削除され空になった場合に自動的に削除されます。

  • 最終出力: プログラムの実行結果として、抽出されたテキストが標準出力(コンソール)に表示されます。各ページからのOCR結果は、--- ページ N のOCR結果 --- という見出しとともに連結され、出力されます。

コマンドラインでの使用例 (Usage)

OCR_pdf.py は、引数なしで実行するとスクリプト内部で定義されているデフォルトのPDFファイルに対してOCR処理を行います。現在のコードでは、コマンドライン引数で直接PDFパスや言語を指定する機能は実装されていません。

基本的な実行コマンドは以下の通りです。

python OCR_pdf.py

OCR_pdf.py は、ocr_from_pdf 関数を呼び出して処理を実行します。この関数の引数を変更することで、処理対象のPDFファイルやOCR言語をカスタマイズできます。

  • pdf_path: OCRを実行するPDFファイルのパス。

  • lang: OCRの認識言語。例: 'jpn' (日本語), 'eng' (英語), 'jpn+eng' (日本語と英語の両方)。

  • output_dir: 一時画像を保存するディレクトリ名。

例えば、__name__ == "__main__" ブロック内の以下の行を変更することで、OCR言語をカスタマイズできます。

    extracted_text_pdf = ocr_from_pdf(pdf_file, lang='jpn+eng')

この部分の pdf_file 変数を別のパスに、または lang'eng' などに変更することで、異なる設定で実行できます。

コマンドラインでの具体的な使用例

ここでは、OCR_pdf.py をコマンドラインから実行した場合の具体的な例と、その実行結果を説明します。

  1. OCR_pdf.py を実行するディレクトリにpeak_fit.pdfが存在しない場合

    python OCR_pdf.py
    

    実行結果 (例):

    ダミーPDF 'peak_fit.pdf' を作成しました。
    
    --- PDFファイル 'peak_fit.pdf' のOCR結果 ---
    PDFファイル 'peak_fit.pdf' のページ数: 1
      ページ 1 を 'pdf_images\page_1.png' として保存しました。
      一時画像 'pdf_images\page_1.png' を削除しました。
    
    --- ページ 1 のOCR結果 ---
    これはテストPDFです。
    PDF OCRの例。
    

    解説: この例では、スクリプト実行時にデフォルトのPDFファイル peak_fit.pdf が見つからなかったため、プログラムが自動的にシンプルな内容のダミーPDFを作成します。その後、作成されたダミーPDFに対してOCR処理が実行されます。pdf_images ディレクトリが一時的に作成され、画像が保存・削除された後、ディレクトリも削除されます。最終的に、ダミーPDFから抽出されたテキストがコンソールに出力されます。

  2. OCR_pdf.py を実行するディレクトリに既存のPDFファイル my_document.pdf があり、そのファイルに対してOCRを実行したい場合

    この場合、OCR_pdf.py ソースコード内の pdf_file 変数を編集する必要があります。

    # 変更前
    pdf_file = "peak_fit.pdf"
    
    # 変更後
    pdf_file = "my_document.pdf" # 既存のPDFファイル名に変更
    

    ソースコードを保存した後、コマンドラインから実行します。

    python OCR_pdf.py
    

    実行結果 (例):

    (ここでは my_document.pdf が2ページで構成されており、1ページ目に「Hello World」、2ページ目に「Python OCR」というテキストがあると仮定します。)

    --- PDFファイル 'my_document.pdf' のOCR結果 ---
    PDFファイル 'my_document.pdf' のページ数: 2
      ページ 1 を 'pdf_images\page_1.png' として保存しました。
      一時画像 'pdf_images\page_1.png' を削除しました。
      ページ 2 を 'pdf_images\page_2.png' として保存しました。
      一時画像 'pdf_images\page_2.png' を削除しました。
    
    --- ページ 1 のOCR結果 ---
    Hello World
    
    --- ページ 2 のOCR結果 ---
    Python OCR
    

    解説: pdf_file 変数を編集することで、my_document.pdf がOCRの対象となります。プログラムは指定されたPDFを処理し、各ページの画像化とOCR、一時ファイルの削除を行い、最終的に抽出されたテキストをページごとに区切って標準出力に表示します。一時ディレクトリ pdf_images は処理後に削除されます。