コマンドラインで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
- How to use OCR from the command line in Linux? - Unix & Linux Stack Exchange
- Tesseract OCR loading a language - Japanese - Stack Overflow
- tesseractコマンドの使い方(Tesseract OCR 4.x) | テクノロジーで楽がしたい
- Warning. Invalid resolution 0 dpi. Using 70 instead. · Issue #1702 · tesseract-ocr/tesseract
- Tesseract Image Issue - Stack Overflow
- linux - Merge / convert multiple PDF files into one PDF - Stack Overflow
- convertに関して – kondolab
- Memory issues · Issue #396 · ImageMagick/ImageMagick