雛形に沿ったPDFファイルを読み込んで、特定の場所の文字列を文字認識で取得する。
というアプリケーションを作りたかったので、忘備録代わりに。
普通にググるとImageMagick+GhostScriptが大多数でした。
一度試してみましたが、OCR処理を通すために必要な解像度まで上げるとCPUが悲鳴を上げます。
今回はWebサービスへの組み込みも考えているので、もっと軽量にしたい・・・
なので、LinuxコンソールアプリのpdfimagesとGoogleオープンソースOCRエンジンのTesseract-OCRを組み合わせてみました。
環境
- centos6
- php
- composer
- imagemagick
- pdfimages
- Tesseract-OCR
準備
bash.sh
yum install imagemagick-devel poppler-utils tesseract-devel //要epel
composer require waarneembemiddeling/php-pdfimages@dev-master
composer require thiagoalessio/tesseract_ocr
コード
ocr.php
<?php
include "vendor/autoload.php";
use \TesseractOCR;
use Wb\PdfImages\PdfImages;
// `which pdfimages` でpdfimagesのフルパスを入れておく
$pdfImages = PdfImages::create(['pdfimages.binaries' => '/usr/bin/pdfimages']);
/*
* 1P目のPDF画像を指定する
* @var FilesystemIterator
*/
$file = $pdfImages->extractImages("PDFへのパス")->current();
// ImageMagickでクロップ処理
$image = new \Imagick;
$image->readImage($file->getPathName());
$image->setImageFormat('jpeg');
$image->setCompressionQuality(100);
$image->cropImage(300, 100, 390, 4593);
$image->writeImage("/tmp/crop.jpg");
//クロップ済み画像のパスを渡す
$ocr = new TesseractOCR("/tmp/crop.jpg");
//OCRで利用する言語を選択
$ocr->setLanguage("eng");
//OCR精度を上げる為にホワイトリストに文字を追加
$ocr->setWhitelist(range(0,9), array("+", "-", "."));
//文字列で帰ってくる
echo $ocr->recognize();
結果
単純な数字の文字認識だとかなりの精度で検出出来ました。
ホワイトリストで文字を縛れば縛る程効果が目に見えて大きかったです。
またImagemagick+GhostScriptだと10秒程cropに時間が掛かりましたが、200ms程で終了するので大幅に高速化出来ました。
日本語等の検出はまだ試していないので何ともいえませんが、単純な文字列の検出でしたらサクッと実装出来たのでオススメです。