Ubuntu Weekly Recipe

第770回UbuntuとOCRmyPDFでスキャンした内容に対して自動的にOCRを実行する

今回はブラザーのスキャナーでスキャンした結果を自動的にOCRを実行します。SambaやOCRmyPDF、Tesseract OCRなど、オープンソースソフトウェアだけで構成します。

紙の書類をなんとかしたい

ペーパーレスなんて言葉はもう聞き飽きてしまいましたが、実際にペーパーレスが達成されたかというとそういうわけでもないことはみなさんも日々感じていることでしょう。

なにかのサービスに契約したらユーザー名とパスワードは郵送されてくるなんてことはむしろ最近増えています。本人確認のためには致し方ないところではありますが。

昔のWi-Fiルーターはメーカーによって初期ユーザー名とパスワードが決まっていましたが、セキュリティ的には問題しかありません。そのため最近はWi-Fiルーターの箱にユーザー名とパスワードが書かれた紙(某社だとシール)が入っています。たしかにこれだと安心ですが、こんなの失くすに決まっています。

ではどうすればいいのでしょうか。今どきだとスマートフォンで撮影してクラウドストレージにアップロードすると自動的にOCRにかけてくれるようになっていますが、本連載としてはUbuntuでなんとかしたいところです。

なぜOCRが必要なのかというと、たくさんの書類からお目当てのものを探すのは大変です。なのでOCR結果をPDFに埋め込み、全文検索をかければ簡単に探せるようにしたいからです。

紙のいいところは探しやすいところですが、スキャンとOCRと全文検索を組み合わせてデジタル化しても紙に似た探しやすさに近づけたいところです。

とはいえ、今回は全文検索に関してはあまり詳しく紹介しません。

使用するスキャナー

紙をスキャンするにはスキャナーが必要です。スキャナーは何でもいいですが、今回はブラザーのADS-1700Wを購入しました。

価格が安いこと、使用しないときは小さく折り畳めることが主な購入理由ですが、⁠スキャンtoネットワーク」という機能でスキャン結果を共有フォルダーに置くことができる機能もまた理由として挙げられます。この機能がついているスキャナーは、筆者の希望の価格帯ではブラザーの製品しか見つけられませんでした[1]

使用するUbuntu

今回使用するOCRmyPDFと、そのバックエンドのバージョンの都合で、使用するUbuntuのバージョンは23.04とします。22.04 LTSだとまた違った解説になるため、かならず23.04を使用してください。

なお、それ以降のバージョンでも同様に動作するはずです。

共有フォルダーの設定

22.04 LTSまでは「⁠ローカルネットワーク共有」がありましたが、第699回で紹介したように不具合があり、22.10からはデフォルトでインストールされなくなりました。

ちょうどその間に開発が再開されており、皮肉にも22.10からは動作するようになりました。

ホームフォルダー以下に「scanner」というフォルダーを作成し、右クリックから「共有フォルダーのオプション」をクリックし、共有フォルダーとします図1⁠。

図1 見覚えのある「フォルダーの共有」
図1

また、ホームフォルダーの所有者(ユーザー)にSambaへアクセスできるようにパスワードを付加しましょう。少なくともADS-1700W(と、おそらく同社の製品)ではパスワードなしの共有フォルダーにはアクセスできませんでした。

次のコマンドを実行してください。

$ sudo pdbedit -a $USER

スキャナーの設定

スキャン結果のPDFを共有フォルダーに置くため、スキャナーの設定を変更します。ADS-1700Wでは、Webインターフェースにログイン後パスワードを入力して管理者になります。

「スキャン」タブの「スキャン to FTP/SFTP/ネットワーク」をクリックし、追加するプロファイルのプロトコルを変更します。SMBの場合は「ネットワーク」になります図2⁠。

図2 ここでは「プロファイル1」「ネットワーク」に変更している
図2

「FTP/SFTP/ネットワークファイルスキャンプロファイル」をクリックし、先程変更したプロファイルの詳細な設定をします図3⁠。なおユーザー名とパスワードが間違っていてもドメインが違うというメッセージが表示されるので、エラーメッセージを過信しないように気をつけてください。

図3 プロファイルの設定例
図3

この段階でいったんスキャンを行い、正しく動作するか確認するといいでしょう。

図4 試しにスキャンしてみると、PDFが作成できた
図4

サンプルドキュメント

今回使用するサンプルドキュメントは、程々の長さかつポピュラーで読みやすく、誰でも知っていて著作権上の問題がないという理由から羅生門にしました。テキストファイルをLibreOffice Writerで読み込み、整形するとA4で3ページ版ほどの長さになりました。程々にちょうどいいです。

OCRmyPDFのインストール

OCRは、OCRmyPDFを使用します。OCRmyPDFは活発に開発されており、リリースも多いです。Ubuntu 23.04のリポジトリには14.0.1がありますが、本校の執筆段階での最新バージョンは14.3.0です。ちなみにSnapパッケージにもなっており、こちらのバージョンは14.2.1ですが、後述する理由により使用しません。

というわけでパッケージをインストールします。次のコマンドを実行してください。

$ sudo apt install ocrmypdf tesseract-ocr-jpn --no-install-recommends 

ここからもわかるとおり、OCRmyPDFのバックエンドはTesseract OCRです。

OCR試行錯誤

まずはラフにOCRを実行してみましょう。次のコマンドを実行してください。

$ cd ~/scanner
$ ocrmypdf -l jpn (スキャン済みPDF) (OCR実行後のPDF)

なお、今回はスキャン済みPDFのファイル名はE79228K2X112931_20230624_160419_000042.pdf、OCR実行後のPDFはE79228K2X112931_20230624_160419_000042-test.pdfとしています。

OCR実行後のPDFを開き、Ctrl+aキーで全選択してCtrl+cキーでコピーし、テキストエディターを起動して貼り付けると、OCR結果を簡単に確認できます5⁠⁠。

図5 OCR結果をテキストエディターに貼り付けたところ。そもそもタイトルが『維生門』になっている
図5

結果を見てみると、全然ダメで全く使い物になりません。OCRmyPDFのバックエンドであるTesseract OCRには多数のオプションがあるので、もう少しマシにならないか確認していきましょう。

OCR結果を見てみると、文字間にスペースが入っています。これだと全文検索が思うように実行できないので、なんとかしたいところです。

不具合報告を調査すると、Extra spaces in any output except txt for non space delimited languagesが見つかります。

これはどうにかするのが難しそうなので、別のアプローチを取ってみましょう。

Tesseract OCRのmanをよく読むと、OCR Engine Mode(OEM)が選べます。エンジンが替われば、別の結果になるかもしれません。

というわけで、0から3(デフォルト)まで試してみましょう。次のコマンドを実行してください。

$ ocrmypdf -l jpn --tesseract-oem 0 (スキャン済みPDF) (OCR実行後のPDF)

すると[tesseract] Error: Tesseract (legacy) engine requested, but components are not present in /usr/share/tesseract-ocr/5/tessdata/jpn.traineddata!!というエラーメッセージが表示されます、0のレガシーモードは、日本語データには対応していないようです。

どういうことかとよく調べてみると、Tesseractの言語データはtessdatatessdata_fasttessdata_bestの3つです。正確には今回は直接関係ないtessdata_contribもあります。

このうち、Ubuntuのリポジトリにあるのはtessdata_fastです。これはtesseract-ocr-jpnパッケージのchangelog.Debian.gzからわかります。

これをtessdataに置き換えればよさそうです。次のコマンドを実行してください。

$ wget https://github.com/tesseract-ocr/tessdata/archive/refs/tags/4.1.0.tar.gz
$ tar xf 4.1.0.tar.gz 
$ sudo cp tessdata-4.1.0/jpn.traineddata /usr/share/tesseract-ocr/5/tessdata/jpn.traineddata
$ rm -r 4.1.0.tar.gz tessdata-4.1.0/

あまりいいやりかたではありませんが、これでおおむね問題ないでしょう。Ubuntuを23.04から23.10にアップグレードする際などには、注意する必要がありますが。

Snapパッケージだと都合が悪いというのはこのあたりで、日本語データを置き換えることができません。

再び次のコマンドを実行して結果を確認してみましょう。

$ ocrmypdf -l jpn --tesseract-oem 0 (スキャン済みPDF) (OCR実行後のPDF)

精度が格段に向上しています図6⁠。日本語では少なくとも現状はレガシーモードを使用するのがよさそうです。

図6 そもそもタイトルが『羅生門』になっている
図6

必須ではありませんが、OCRを実行する前にページの可読性を向上させるオプションもあります。古い紙をスキャンするような場合には、有効にしておくといいでしょう。

次のコマンドを実行し、unpaperパッケージをインストールします。

$ sudo apt install unpaper --no-install-recommends

オプションを追加してOCRを実行します。

$ ocrmypdf -l jpn --tesseract-oem 0 --clean (スキャン済みPDF) (OCR実行後のPDF)

自動実行

手動ではうまくいくようになったので、残すは自動実行できるようにするだけです。OCRmyPDFのドキュメントにBatch processingがあるので、ここで紹介されているwatcher.pyを使わせてもらいましょう。

注意点としては、入力用フォルダーと出力用フォルダーを明確に分けないといけないところです。今回は入力用を~/scanner、出力用を~/scan-ocrとします。

次のコマンドを実行して、準備してください。

$ mkdir ~/.local/bin ~/scan-ocr
$ wget https://raw.githubusercontent.com/ocrmypdf/OCRmyPDF/master/misc/watcher.py -O ~/.local/bin/watcher.py

watcher.pyを起動します。次のコマンドを実行してください。

$ OCR_INPUT_DIRECTORY=~/scanner/ OCR_OUTPUT_DIRECTORY=~/scan-ocr/ OCR_POLL_NEW_FILE_SECONDS=5 OCR_ON_SUCCESS_DELETE=1 OCR_JSON_SETTINGS='{"language": "jpn", "tesseract-oem": "0", "clean": null}' python3 ~/.local/bin/watcher.py

詳細は前出のBatch processingのページを確認してほしいのですが、OCRmyPDFのオプションをJSONにしないといけません。OCR_POLL_NEW_FILE_SECONDSはファイルが作成されてからOCRを実行するまでの秒数です。今回の5秒は少ないページ数ではいいかもしれないものの、もっと長いページでは足りないかもしれません。適宜変更してください。

あとはこれをsystemdのユーザーセッションで自動実行するようにすればいいでしょう。次のコマンドを実行してください。

$ systemctl edit --user --full --force watcher.service

エディターが開くので、次の内容としてください。

[Unit]
Description=Watch a directory for new PDFs and OCR them

[Service]
Environment=OCR_INPUT_DIRECTORY=%h/scanner/
Environment=OCR_OUTPUT_DIRECTORY=%h/scan-ocr/
Environment=OCR_POLL_NEW_FILE_SECONDS=5
Environment=OCR_ON_SUCCESS_DELETE=1
Environment=OCR_JSON_SETTINGS='{"language": "jpn", "tesseract-oem": "0", "clean": null}'
WorkingDirectory=%h/scanner
ExecStart=/usr/bin/python3 %h/.local/bin/watcher.py

[Install]
WantedBy=default.target

あとは有効にするだけです。次のコマンドを実行してください。

$ systemctl enable --now --user watcher.service

この段階ではscan-ocrフォルダーは共有されていないので、必要であれば共有してください。

全文検索

全文検索に関しては、詳しくは紹介しません。Ubuntuということでデフォルトの全文検索エンジンであるTrackerを使用する場合は、⁠設定⁠⁠-⁠検索⁠⁠-⁠検索する場所」「その他」に対象のフォルダー(今回の例だとscan-ocrを追加します図7⁠。

図7 検索する場所を追加する
図7

あとは端末から検索します図8⁠。

図8 単語の検索くらいであれば実用できそうだ
図8

おすすめ記事

記事・ニュース一覧