ExcaliburによるPDFテーブルデータ抽出を動かしてみる

R&D チームの徳田(@dakuton)です。
前回、2値化画像処理の論文(+実装)について紹介しましたが、今回はこういった2値化の応用例としてExcalibur(PDFからテーブルデータを抽出するためのWeb UIベースのツール)を紹介します。
本記事はOPTiM TECH BLOG Advent Calendar 2020 12/7 の記事としてお送りします。

前回記事はこちら。
tech-blog.optim.co.jp

動かしてみる

インストール

# https://camelot-py.readthedocs.io/en/master/user/install-deps.html#macos]
brew install ghostscript tcl-tk

pip install excalibur-py
excalibur initdb

実行結果

今回もこちら(Rustの全マクロ種別が分かったつもりになれる話!)のスライドを用いました。

excalibur webserverにて起動、上記スライドの22ページ目をアップロード後Autodetect Tablesを実行した結果が下記です。自動だと少し位置がずれてしまっていますが、画面中央のプレビュー選択範囲(点線表示エリア)を手動補正することでテーブルとして検出する範囲を補正可能です。 https://cdn-ak.f.st-hatena.com/images/fotolife/o/optim-tech/20201204/20201204092934.png

手動にてテーブル外の「手続きマクロだけを〜」を含めないように補正した場合のテーブルプレビュー結果はこちら。この画面からCSV等でファイルエクスポート利用可能です。 https://cdn-ak.f.st-hatena.com/images/fotolife/o/optim-tech/20201204/20201204092926.png

検出ロジック解説

バックエンドとして利用しているCamelotをもとに、どのようにテーブルエリアを検出しているか?簡単に紹介します。
画像処理(Latticeモード)にて検出する場合は、以下の流れでテーブルエリアを検出していることが実装からわかります。

  1. 2値化処理(今回は大津の2値化ではなくcv2.ADAPTIVE_THRESH_GAUSSIAN_Cを利用)
  2. 垂直線の検出(cv2.getStructuringElement)
  3. 水平線の検出(cv2.getStructuringElement)
  4. 2,3の論理和による矩形の検出(cv2.findContours, cv2.approxPolyDP, cv2.boundingRect)
  5. 2,3の交点数(np.multiply)を評価し不要矩形を破棄、残ったエリアを採用
  6. PDFプレビュー時のテキスト座標(PyPDF, PDFMiner.six利用)と5までの結果を照合しテーブルとして出力

これとは別途、画像処理を用いず、テキスト間の空白区間の関係から検出するモード(Streamモード)も利用可能です。罫線がなくLatticeモードでのテーブル位置検出に失敗する場合は、こちらのモードで対応できることがあります。
なお、このツールはテキストとして読み込めるタイプのPDFのみをサポートしており、OCRが必要な場合(画像をPDFに変換した場合)はエクスポートに失敗します。

おわりに

Deep Learning的な要素は特にありませんが、OpenCVで用意されている画像処理をテキスト解析の補助データとして上手く組み合わせればそれなりに検出できることがわかりました。

オプティムでは実現手法とらわれず、使える手法を選択できるエンジニアを募集しています。 www.optim.co.jp