Python、機械学習

【Python】pdfファイルから文字起こしをしてテキストに変換する方法(tesseract-OCR、pyocr、pdf2image、poppler)

自分のメモや文献をスキャナでpdfファイルにして保存している方、多いと思います。

こういったpdfファイルから文字起こしできると、いろいろ便利だと思いませんか?

有料のAdobe Acrobatであれば、テキスト認識できるpdfファイルを作ることができます。しかしながら、大半のpdfファイルはテキスト認識できない完全埋め込み型だと思います。

こちらの記事にて、画像ファイルから文字起こしする方法を書きましたが、pdfファイルについても同じことができないのでしょうか?

【Python】画像から文字起こししてテキストに変換する方法(tesseract-OCR、pyocr)画像から文字起こしができると、業務効率化など様々な場面に応用できて便利です。 幸いなことに、それを可能にするオープンツールがあります。...

pdfファイルはtesseract-OCRで取り扱えない

tesseract-OCRでは、pdfファイルからテキストに文字起こしすることはできません。

pdfファイルの場合、プリントスクリーンで表示画面をキャプチャ→ペイントに貼る→画像ファイルとして保存、という手もありますが、pdfのページがたくさんあると面倒です。

やるなら、pdfファイルを一旦画像ファイルに変換してからtesseract-OCRの処理にかけます。

以下、その具体的な方法を記載します。

pdfファイル→画像ファイルの変換をする

pdf2imageをインストールする

まずは、pdf2imageをインストールします。

pip install pdf2image

popplerをインストールする

ダウンロード

こちらのURLにアクセスし、DownloadのところのLatest binaryに記載されているpopplerをクリックすればOKです。

2019年7月時点ですと、poppler-0.68.0_x86がLatest binaryに記載されていますのでこれをクリックします。
Poppler for Window

解凍

7zという拡張子で圧縮されたファイルが得られますので解凍します。

7zの圧縮ファイルが解凍できない場合は、7zに対応している解凍ソフト:7z1900をインストールし、7z1900を使ってpopplerの7z圧縮ファイルを解凍します。

インストール

出てきたexeファイルをクリックしてインストールします。

インストールが完了すると「poppler」フォルダができますので、これをC:¥Program Filesの中に移動します。

popplerフォルダにPath(パス)を通す

このpopplerフォルダにPathを通します。

WindowsマークのボタンとPAUSE/BREAKのボタンを同時に押すと、システムの画面が立ち上がります。

左側の「システムの詳細設定」をクリックし、「環境変数」をクリックします。システム環境変数の中にPathという変数がありますのでクリックします。

右上の「新規」をクリックし、「C:¥Program Files¥poppler¥bin」と記入します。OKをクリックします。

この設定を反映させるため、パソコンを再起動します。

コードを作成する

ベースのPythonコードは冒頭に貼った記事をご覧いただければと思います。ここでは、ベースのPythonコードに対して2つの改良を加えました。

1)pdfファイル、画像ファイル(png, jpeg等)の両方に対応できるようにする
2)複数のページ数をもつpdfファイルに対応できるようにする

具体的な改良方法は以下の通りです。

1)→if文を使って、pdfかそれ以外かの場合分けをする。

2)→pdfファイルを画像ファイルに変換するとページごとに画像ファイルが生成されるため、for文でpdfのページごとに画像ファイル変換。そこから文字起こしたテキストをtextsリストに追加。最後に、textsリストに含まれるテキスト毎に文字スペース削減、改行削減を行い、printで表示。

以下、Pythonコードです。

from PIL import Image
import sys

import pyocr
import pyocr.builders

from pdf2image import convert_from_path
import re

tools = pyocr.get_available_tools()
if len(tools) == 0:
    print("No OCR tool found")
    sys.exit(1)

tool = tools[0]
print("Will use tool '%s'" % (tool.get_name()))

langs = tool.get_available_languages()
print("Available languages: %s" % ", ".join(langs))
lang = langs
print("Will use lang '%s'" % (lang))

input_file = input('ファイルのパスを入力してください。')

texts = []
if '.pdf' in input_file:
    pages = convert_from_path(input_file)
    for page in pages:
        txt = tool.image_to_string(
            page,
            lang=lang,
            builder=pyocr.builders.TextBuilder(tesseract_layout=3)
        )
        texts.append(txt)
else:
    txt = tool.image_to_string(
        Image.open(input_file),
        lang=lang,
        builder=pyocr.builders.TextBuilder(tesseract_layout=3)
        )
    texts.append(txt)

for txt in texts:
    txt = re.sub('([あ-んア-ン一-龥ー])\s+((?=[あ-んア-ン一-龥ー]))',
    r'\1\2', txt)
    print(''*40)
    print( txt )
    print('-'*40)