
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を画像に変換する方法をまとめています。これらの組み合わせでやれる幅も増えると思うので、参考にしてください。
コメント