【Python+EasyOCR】PDFからテキスト情報を抽出する方法について

OCR
スポンサーリンク
ピーター
ピーター

PythonとOCRを使って、PDFからテキスト情報を抽出してみたい!

今回はPythonとEasyOCRを使うことで、PDFからテキスト情報を抽出するための実装をしました。その手順について、備忘録として記載します。



実装で考えた方針

今まで紹介した内容を組み合わせて進めたいと思います。

  • pdf2image(PDFから画像に変換)
  • PILからnumpyへ変換(EasyOCRに入力するため)
  • EasyOCR(テキスト抽出)

この3つを組み合わせるだけで動かしていきます!

EasyOCRのreadtext関数はnumpyしか受け付けないため、PillowからOpenCVのための変換を加えています。

環境設定とサンプルコード

環境設定(インストール)

pipでインストールしている場合のコマンド

EasyOCRは対応しているOpenCVのバージョンに依存している可能性があります。

OpenCVを最新のものにしていると動かない可能性もあるため、インストールするバージョンは意識する必要が出てくることがあります。

### OpenCVのインストール
$ brew install opencv
$ pip install opencv-python==4.5.4.60

###  pdf2imageのインストール
$ pip install pdf2image
$ pip install poppler

###  EasyOCRのインストール
$ pip install easyocr==1.6.2

実際に環境構築していた際、このようなコメントが表示されましたので、OpenCV関係のバージョンは4.5.4.60に合わせています。

  SolverProblemError

  Because easyocr (1.6.2) depends on opencv-python-headless (<=4.5.4.60)
   and no versions of easyocr match >1.6.2,<2.0.0, easyocr (>=1.6.2,<2.0.0) requires opencv-python-headless (<=4.5.4.60).
  So, because image2txt-easyocr depends on both easyocr (^1.6.2) and opencv-python-headless (^4.7.0), version solving failed.

pdf2imageを利用したサンプルコード

特定ページのみ画像変換する場合の関数です

from pdf2image import convert_from_path

### 特定ページをPDF->画像変換する関数
def pdf2pil(in_pdf_path, page_num = 1, pdf_password = None, img_format = "png"):
    page = convert_from_path(
        pdf_path = in_pdf_path,
        dpi = 300,
        first_page = page_num,
        last_page = page_num,
        fmt = img_format,
        thread_count = 1,
        userpw = pdf_password,
        use_cropbox = False,
        strict = False,
    )
    return page[0]

Pillow→OpenCVのサンプルコード

import numpy as np
import cv2

### PIL型 => OpenCV型 の変換関数
def pil2opencv(in_image):
    out_image = np.array(in_image, dtype=np.uint8)
    if out_image.ndim == 2:
        pass
    elif out_image.shape[2] == 3:
        out_image = cv2.cvtColor(out_image, cv2.COLOR_RGB2BGR)
    return out_image

EasyOCRを使った最終サンプルコード

サンプルのPDFがなかったため、sample-files-for-demo-useさんのsample-pdf.pdfを利用しました!

1ページ目を変換するようにしていますが、for文を使うなどすることで、複数ページのテキスト抽出は可能です。

PDFのページ上下限値の動作など工夫は必要ですが、簡単にこれで動作することは可能です。

import cv2
import numpy as np
import easyocr
from pdf2image import convert_from_path

### 特定ページをPDF->画像変換する関数
def pdf2pil(in_pdf_path, page_num = 1, pdf_password = None, img_format = "png"):
    page = convert_from_path(
        pdf_path = in_pdf_path,
        dpi = 300,
        first_page = page_num,
        last_page = page_num,
        fmt = img_format,
        thread_count = 1,
        userpw = pdf_password,
        use_cropbox = False,
        strict = False,
    )
    return page[0]

### PIL型 => OpenCV型 の変換関数
def pil2opencv(in_image):
    out_image = np.array(in_image, dtype=np.uint8)
    if out_image.ndim == 2:
        pass
    elif out_image.shape[2] == 3:
        out_image = cv2.cvtColor(out_image, cv2.COLOR_RGB2BGR)
    return out_image

reader = easyocr.Reader(['ja', 'en'])     #日本語:ja, 英語:en
pil_img = pdf2pil("input/sample-pdf.pdf", 1)    # 1ページ目をPDF化
numpy_img  = pil2opencv(pil_img)
results = reader.readtext(numpy_img)
for result in results:
    print("text:", result[1], "confident Score:",result[2])

### text: サンプル提案書 [[622, 845], [2386, 845], [2386, 1118], [622, 1118]]
### text: サンプル株式会社 [[1098, 1330], [1903, 1330], [1903, 1453], [1098, 1453]]
### text: 試作 太郎 [[1279, 1480], [1716, 1480], [1716, 1601], [1279, 1601]]

まとめ

PDFもPythonを使うことでテキスト抽出することが可能になります。

PDFの場合、パスワード付きのPDFもあるので、その場合は修正が必要になりますが、基本的な動作を見るには十分だと思います。

ピーター
ピーター

PDFからテキスト抽出できるようになると色々便利になります!

その他の参考記事について

PDFから画像に変換する方法

PDFから文字情報を抽出したくて、色々実装を進めていました。

その流れでODFを画像に変換する方法をまとめています。これらの組み合わせでやれる幅も増えると思うので、参考にしてください。

コメント

ランキング

タイトルとURLをコピーしました