LoginSignup
10
11

More than 3 years have passed since last update.

コマンドラインでPDFにOCRを掛ける on Linux(Ubuntu)

Last updated at Posted at 2019-12-16

コマンドラインでPDFファイルにOCR掛けたくなったので、OCR用にocrizeというファイル名でbashスクリプトを書きました。

ocrizeを使われる方は事前に以下のコマンドを実行して、必要なパッケージをインストールして下さい。

$ sudo apt install tesseract-ocr-jpn imagemagick
# 縦書き日本語PDFにOCRを掛けるにはtesseract-ocr-jpn-vertが必要。

ocrizeの実行は次のように行います(事前にchmodで実行可能にして下さい)。

$ ./ocrize input.pdf
# or
$ ocrize input.pdf # 例えば、/usr/local/bin等、パスの通った場所にocrizeを置いた場合。

以下では、コマンドラインでPDFファイルinput.pdfにOCRを掛ける手順を解説します。

Step.0 事前準備

input.pdfにOCRを掛ける前に、ファイル名を変数に格納して、一次保存用ディレクトリを作製しておきます。

$ stem="input" # 拡張子無しのファイル名。
$ dir="${file}.temp"
$ mkdir ${dir} # input.tempディレクトリが作られます。

Step.1 PDFファイルを画像ファイルに分割

ImageMagickのconvertコマンドを使って、input.pdfを画像ファイルに分割しましょう。

$ convert -density 300 -geometry 1000 ${stem}.pdf ${dir}/${stem}.png

オプション-densityの値を大きくするほど画質が良くなりますが、大きい値を指定する場合、ImageMagickのresourceを変更する必要があります。

上のコマンドを実行すると、以下のように、input.pdfをページ毎に分割してPNGに変換したファイルがinput.tempディレクトリ以下に出力されます。

$ ls ${dir}
input-0.png   input-1.png   input-2.png  input-3.png

convertコマンドで以下のエラーが出た場合は、ImageMagickのpolicy.xmlを修正しましょう(私の環境の場合、policy.xmlは/etc/ImageMagick-6直下にありました)。

Error.1 convert: not authorized

PDFの読み込み書き込みが出来るように、domainがcoder、patternがPDFであるpolicyタグのrightを以下のように修正しましょう。

<policy domain="coder" rights="read|write" pattern="PDF" />

Error.2 convert-im6.q16: cache resources exhausted

メモリーが不足しているので、domainがresourceのpolicyタグを修正しましょう。私の場合、nameがmemoryとdiskの箇所を修正しました。

<policy domain="resource" name="memory" value="1GiB"/>
<policy domain="resource" name="disk" value="2GiB"/>

resourceは次のコマンドで確認できます。

$  identify -list resource
# or
$  identify -list Resource

Step.2 画像ファイルからOCRを掛けたPDFを作る

input.tempディレクトリ以下の画像ファイルそれぞれに対してOCRを施します。

$ N=$(ls ${dir} | grep -c '' | awk '{printf "%d", $1-1}')
$ for n in $(seq 0 ${N}); do tesseract -l jpn+eng ${dir}/${stem}-${n}.png ${dir}/${stem}-${n} pdf; done

オプション-lで認識言語を指定しています。第一優先に日本語、次に英語で認識したい場合、jpn+engと指定します。

Step.3 OCRが掛かったPDFファイルを1つにまとめる

複数のPDFファイルを1つにまとめるのにpdfuniteコマンドを使います。

$ pdfunite $(for n in $(seq 0 ${N}); do echo ${dir}/${stem}-${n}.pdf; done) ocrized-${stem}.pdf

ページの順番が崩れないようにforでPDFファイルをページ順に出力しています。実行後、input.pdfにOCRを掛けたocrized-input.pdfがカレントディレクトリ直下に作製されます。

最後に、input.tempディレクトリを削除して終わりです!

$ rm -r ${dir}

ocrize

以下が、以上の内容をまとめたbashスクリプトです。ファイル名ocrizeで保存して使って下さい。

#! /bin/bash

if [ $# -eq 1 ]; then
    file=$1
    ext=$(echo ${file} | rev | cut -d '.' -f 1 | rev)
    dir=${file}.temp
    if [ -d ${dir} ]; then
        echo "${dir} allready exists. Please remove this directory."
        exit 1
    fi
    if [ ${ext} = "pdf" -o ${ext} = "PDF" ]; then
        if [ ! -f ${file} ]; then
            echo "${file} dose not exist."
            exit 1
        fi
        stem=$(echo ${file} | rev | cut -c 5- | rev)
        mkdir ${dir}
        echo "1: Converting PDF to PNG."
        convert -density 300 -geometry 1000 ${file} ${dir}/${stem}.png
        echo "1: Finished."
        N=$(ls ${dir} | grep -c '' | awk '{printf "%d", $1-1}')
        echo "2: OCRizing."
        for n in $(seq 0 ${N}); do
            p=$(echo "${n} ${N}" | awk '{printf "%5.1f", ($1+1)/($2+1)*100}')
            echo -ne "Progress: [${p} %]\r"
            tesseract -l jpn+eng ${dir}/${stem}-${n}.png ${dir}/${stem}-${n} pdf >& /dev/null
            rm ${dir}/${stem}-${n}.png
        done
        echo "2: Finished.        "
        echo "3: Merging PDF files."
        #pdftk $(for n in $(seq 0 ${N}); do echo ${dir}/${stem}-${n}.pdf; done) output ocrized-${pdffile}
        pdfunite $(for n in $(seq 0 ${N}); do echo ${dir}/${stem}-${n}.pdf; done) ocrized-${file}
        echo "3: Finished."
        rm -r ${dir}
    else
        echo "Extension must be pdf or PDF."
        exit 1
    fi
else
    echo "Usage: $ ocrize input.pdf"
    exit 1
fi

ocrizeを実行すると、以下のようにスクリプトが走ります。

$ ./ocrize input.pdf
1: Converting PDF to PNG.
convert-im6.q16: profile 'icc': 'RGB ': RGB color space not permitted on grayscale PNG `input.pdf.temp/input.png' @ warning/png.c/MagickPNGWarningHandler/1654.
1: Finished.
2: OCRizing.
Progress: [ 84.4 %]

数秒後、

1: Converting PDF to PNG.
convert-im6.q16: profile 'icc': 'RGB ': RGB color space not permitted on grayscale PNG `input.pdf.temp/input.png' @ warning/png.c/MagickPNGWarningHandler/1654.
1: Finished.
2: OCRizing.
2: Finished.        
3: Merging PDF files.
3: Finished.

参考URL

10
11
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
11