今日も微速転進

ここではないどこかへ

財務省の公開した交渉記録PDFをいじる その1(目次のPDF編)

自分でモロに忘れそうなので備忘録として。

一時ファイルがじわじわと増殖するのでもっとスマートに行きたいところです。

作戦というか方針

まずは目次のPDFファイルから。

  1. 目次のPDFから交渉記録(応接記録)を機械可読(Computer Readable)な形式に変換
  2. マスク無しのPDFを画像化、再度PDFに変換して過去記事で紹介したAPIOCR
  3. 目次のページ番号から必要なページを割り出して、OCR結果を分割、どうにして添付資料のページを除去
  4. どうにかしてMarkdown
  5. 静的ページジェネレーターでWebページ化

この記事では「1. 」の部分。

問題は黒塗り部分。特定の操作で外せるのはいいけど、外してからOCRして明らかにやばい部分だけ伏せ字にする?

とりあえずやっていきます。

データの入手

財務省のWebサイトから、といいたいところですがそこはやはりWebアーカイブから黒塗りの外せる方を。

srad.jp

  • 20180523p-1.pdf
  • 20180523p-2.pdf
  • 20180523p-3.pdf
  • 20180523p-4.pdf

目次のOCR処理

目次のデータは素直に財務省のページから。

a244.hateblo.jp

20180523p-0.pdfというファイルです。

目次ファイル

一応、目次のPDFファイルについてもGoogle Cloud Vision OCROCRしてみました。残念ながら罫線が邪魔なのか、OCR結果がいまいち。通し番号の列が認識できていない。また、右端のページ番号も認識に失敗している。

水平方向の行を列ごとに細切れにされて出力されて扱いにくい。

Web APIでいくならMicrosoftAPIの法が良いかも。画像を切り出してTesseractでOCRしてみます。

このファイル、不思議なことに各ページが横に長い短冊状の画像が縦に37個結合したPDFになっていて理解不能。 何これ一体?

ファイルサイズを小さくしたかったの?

何はともあれ、表の罫線があるとGoogleOCR API、Tesseract両者とも結果がイマイチであるという点を考慮し、画像をぶった切ってTesseractでOCRする方向で。

本気で行くなら罫線と文字は接触していないので、ハフ変換で直線検出してやればいいのかな。

ちなみに"OpenCV line remove"でググると結構ヒットする。

罫線(水平線)の除去についてはLeptonicaによるサンプルがあります。

Removing dark lines from a light pencil drawing — Leptonica Documentation v1.68 documentation

画像の切り出し

まず目次のPDFから各ページを画像に変換。

$ mutool draw -o "index_page_%d.png" -r 300  pdf_masked/20180523p-0.pdf

-oで出力ファイルを指定。%dはページ番号が入ります。

GUIでやってもいいですが、表紙を除いた合計8ページから日付の列とページ番号の列を切り出せばよいのでコマンドで。

300dpiで画像化した場合、3ページ目以降は表の上端までの距離が概ね150ピクセル、表の見出しを含めると250ピクセルぐらい。

ものすごくざっくり欲しい列の位置を図で示しておく*1

f:id:atuyosi:20180602180107p:plain:w480

カラープロファイルを指定しないと下記のエラーが出るので、+profile "icc"オプションを追加。-noiseオプションでノイズ除去。

convert: profile 'icc': 'RGB ': RGB color space not permitted on grayscale PNG `output2_1.png' @ warning/png.c/MagickPNGWarningHandler/1744.

参考:ImageMagick で PNG の形式を変換 - awm-Tech

左側の日付の列を切り出す。

$ convert masked/index_page_2.png +profile "icc" -noise 4   -crop "480x2980+500+410" output2_1.png

同じように右側の列。

$ convert masked/index_page_2.png +profile "icc" -noise 4 -crop "180x2980+2000+410" output2_2.png

-cropオプションの引数は、切り抜くサイズ(横、縦)とx座標のオフセット、y座標のオフセット。

f:id:atuyosi:20180602204910p:plain f:id:atuyosi:20180602204916p:plain

理想を言えば罫線を除去したいところだがまあ妥協。

3ページ目以降。

$ convert masked/index_page_3.png +profile "icc" -noise 4 -crop "480x3100+500+280" output3_1.png
$ convert masked/index_page_3.png +profile "icc" -noise 4 -crop "180x3100+2000+280" output3_2.png

もう少し範囲を絞って縦の罫線をきっちり除去すべきだったか。

ImageMagick逆引きコマンドリファレンス

ImageMagick逆引きコマンドリファレンス

ImageMagickの日本語の本、あったのか(絶版)。

Tesseract 4.x

ビルドに必要なライブラリのインストール。

$ brew install --only-dependencies tesseract

最新版をソースからビルドしようかと一瞬だけ思いましたが、地味に面倒なので中途半端ですがHomebrew経由で最新版を。要するに4.x系でやりたかったというだけです。

Tesseract本体(開発版)。

$ brew install tesseract  --HEAD

学習用のツールはインストールせず。

現状のHomebrewパッケージの場合、--HEADオプションを付けると全言語の言語別データをダウンロードする。その際、ダウンロードされるのは以下のリポジトリのデータとなるので注意。

github.com

現状、tessdataは無印(3.0x用のデータを含む)、tessdata_fasttessdata_bestの3系統。

なお、Tesseract tessdata downloaderという補助ツールも提供されている。

github.com

4.x系向けのデータはengとかjpnのデータと、script(書字系?)別のデータ(EnglishとかJapaneseとか)で2種類ある。

現状、Japanese.traineddataなどscriptフォルダ直下のデータはそのままでは読み込まれないので、tessdataフォルダにコピーするかシンボリックリンクを作成する必要がるので注意。

今回の画像データで試した範囲ではjpn..traineddataで十分かな。Japanese.traineddataでは半角数字の前後で余計な空白が入る。

目次のOCR

$ tesseract output2_1.png ocr_text  -l jpn

引数は、

tesseract 画像ファイル 出力ファイルの接頭辞 オプション

出力ファイル名にstdoutを指定すると標準出力(つまりコンソール画面)に結果を出力する。

認識結果の例

$ tesseract output2_1.png stdout  -l jpn --psm 6
Warning. Invalid resolution 0 dpi. Using 70 instead.
平成25年6月28日
平成25年7月8日
平成25年7月25日
平成25年8月1日
平成25年8月13日
平成25年8月21日
平成25年9月2日
平成25年9月12日
平成25年10月4日
平成25年10月24日
平成25年10月27日
平成25年10月30日
平成25年11月4日
平成25年11月19日
平成26年12月16日
平成25年12月26日
平成25年12月27日
平成26年1月9日
平成26年1月27日
平成26年1月28日
平成26年1月31日
平成26年2月3日
平成26年2月13日
平成26年3月4日
平成26年3月6日
平成26年3月2日
平成26年4月15日

大変結構。

$ tesseract output2_2.png stdout -l jpn --psm 6 --oem 3
Warning. Invalid resolution 0 dpi. Using 70 instead.
]
18
19
19
22
24
26
27
35
36
42
44
46
47
50
53
55
56
63
64
73
75
77
78
81
84
87

数字の"1"の認識ミスは許容範囲内。

--psm (page segmentation mode)の値によっては最初の”1"を取りこぼすか、余計な空行が入ったりする。古いバージョンのTesseractのほうが数字の認識に関しては優秀だろうと思う。面倒なので試していない。

やはり面倒なのでスクリプトで一括。

#! /usr/local/bin/bash


convert masked/index_page_2.png +profile "icc" -noise 4   -crop "480x2980+500+410" cropped_2_1.png
convert masked/index_page_2.png +profile "icc" -noise 4 -crop "180x2980+2000+410" cropped_2_2.png

for i in `seq 3 9` ; do
    convert masked/index_page_${i}.png +profile "icc" -noise 4   -crop "480x3100+500+280" cropped_${i}_1.png
    convert masked/index_page_${i}.png +profile "icc" -noise 4 -crop "180x3100+2000+280" cropped_${i}_2.png
done


for j in `seq 2 9`; do
    echo "first ${j}"
    tesseract cropped_${j}_1.png ocr_text_${j}_1  -l jpn --psm 6 
    echo "2nd ${j}"
    tesseract cropped_${j}_2.png ocr_text_${j}_2  -l jpn --psm 6 
done

認識ミスは以下の通り。

  • 1ページ目 数字の"1"の認識ミス
  • 3ページ目 「平成26年6月17晶」。末尾の「日」を認識できず。
  • 4ページ目 末尾の「日」の認識ミス。余計な文字「|」
  • 5ページ目 末尾に余計な文字「409 .」
  • 6ページ目 余計な文字「征」「 .」。末尾の「日」の認識ミス。
  • 7ページ目 余計な文字「|」
  • 8ページ目。なぜか"810"が脱落。

あとは「日」が「昌」になったり「目」になっている箇所がいくつか。画像を拡大する処理が必要だったかな。

まあ手作業で修正できる範囲です。

末尾に^L(Form Feed: \f)がくっついているので後で除去する。

OCR結果のテキストファイルの結合

結合するファイル同士の行数が同じであるという前提で、pasteコマンドを使う。

#! /usr/local/bin/bash

for j in `seq 2 9`; do
    echo "target ${j}"
    paste ocr_text_${j}_1.txt  ocr_text_${j}_2.txt >> ocr_result_${j}.tsv 
done

前述の邪魔な^Lを除去する。

$ cat $(ls *.tsv) | tr -d '\f' | sed '/^[[:blank:]]*$/d' > page_list.tsv

参考:Linux パターン別ファイルの空行削除(除外)方法 | 俺的備忘録 〜なんかいろいろ〜

完成品:財務省の公開した国有地の取引に関する交渉記録の目次PDFから抜き出した日付とページ番号の対応表(2018年5月)

※ 不備があったので更新しています。

まとめ

とりあえず目次データをTSV化するところまで。

Tesseractのドキュメント構造解析処理がアレなのはともく、GoogleAPIも罫線入りの表が苦手だとはさすがに意外。

Cloud Vision APIの方は"TEXT_DETECTION"の方を試すのもありかもしれないですがそれはまた別の機会に。

次は本文データ(OCR済み)に挑みます。

続きます。

詳解 OpenCV 3 ―コンピュータビジョンライブラリを使った画像処理・認識

詳解 OpenCV 3 ―コンピュータビジョンライブラリを使った画像処理・認識

シェルプログラミング実用テクニック

シェルプログラミング実用テクニック

*1:いかにもやっつけ仕事

Tesseract OCR 3.05 のインストールと新機能

2月16日付でオープンソースOCRエンジンである Tesseract OCR の3.05がリリースされています。

2月中に記事にしようと思いつつ結局3月になってしまいました。

github.com

Ubuntu 17.04 の Feature Freeze に間に合わせたいという要望が出た結果、唐突にリリースされたようです*1

実際のところ、Ubuntu 17.04 に採用されるのかどうかは不明です。

変更点

ざっくりいうと一番のメインはTSV出力。あとは諸々のバグ修正。HTML形式の出力*2についても改善しているようです。あとはバグ対応など。

以下、リリースノートからのざっくり訳。

  • hOCR 出力 における改善(微調整)
  • 新しい出力オプションとしてTSVを追加
  • バージョン 3.04.00における AnalyseLayout()メソッドのABI非互換を修正
  • text2image tool : すべてのOpenType リガチャが有効に(この機能にはPango 1.38以降が必要)
  • Training tools : assert関数をtprintf()exit(1)に置き換え
  • Cygwin 環境における互換性問題を修正
  • マルチページのTIFFファイル処理の改善
  • 埋め込みpdfフォントについての改善 (pdf.ttf)
  • コマンドラインからOCRエンジンモード指定するオプションを追加(--oemオプションの追加))
  • tesseractコマンドの、オプション指定形式を ‘-psm’ から ‘–psm’ (ハイフン2つ)に変更
  • 新しいC APIの追加と古いAPIの削除( for orientation and script detection )
  • ビルドに必要なautoconf のバージョンを 2.59 に変更
  • 不要なコードの削除
  • 多数のコンパイラの警告に対処
  • メモリリークおよびリソースリーク*3を修正
  • ‘Cube’ OCR エンジンのバグ修正
  • openCL 関連のバグを修正
  • CMake によるビルドに対応
  • Windows環境向けに CPPAN supportを追加

オプションの指定方法ですが、従来と同じく-psmでもエラーにはなりません。将来的には--psmのようにハイフン2つに移行するはず。

また、--psm オプション*4に指定できる値が追加されています(詳細はtesseract -hで確認)。

text2imageコマンドのmac環境におけるバグは修正されたかと思いきや、4系からのバックポートの余波でリグレッションしているので要注意*5

各種ラッパーの対応状況

すんなり対応したのはJava/Android 系ぐらいで全然進んでいないようです。TSV出力を使わないのであれば、tesseractコマンドを呼び出すタイプのライブラリは普通に動くと思います。

新機能

新機能であるTSV出力を試してみます。認識結果をタブ区切りテキストとして出力する機能という認識です。普通の文書よりは表とか本の目次のような画像データ向き。

$ tesseract -v
tesseract 3.05.00
 leptonica-1.74.1
  libjpeg 8d : libpng 1.6.28 : libtiff 4.0.7 : zlib 1.2.8

手頃な画像が見つからないので適当な画像で試します。

f:id:atuyosi:20170308033249p:plain

電子書籍版の『[改訂第7版]LaTeX2ε美文書作成入門』のp.225の表の一部を切り抜いたもの(実際は幅640pxに拡大)。

実際にtesseractコマンドで試すには、コマンドラインの末尾にtsvを追加して実行。

$ tesseract -l eng resize_table.tiff  stdout tsv 2> /dev/null
level   page_num    block_num   par_num line_num    word_num    left    top width   height  conf    text
1   1   0   0   0   0   0   0   640 146 -1
2   1   1   0   0   0   55  11  30  119 -1
3   1   1   1   0   0   55  11  30  119 -1
4   1   1   1   1   0   55  11  30  16  -1
5   1   1   1   1   1   55  11  30  16  79  pbk
4   1   1   1   2   0   55  45  30  16  -1
5   1   1   1   2   1   55  45  30  16  79  pbk
4   1   1   1   3   0   55  79  30  17  -1
5   1   1   1   3   1   55  79  30  17  78  phk
4   1   1   1   4   0   55  113 30  17  -1
5   1   1   1   4   1   55  113 30  17  79  pbk
2   1   2   0   0   0   220 45  18  12  -1
3   1   2   1   0   0   220 45  18  12  -1
4   1   2   1   1   0   220 45  18  12  -1
5   1   2   1   1   1   220 45  18  12  66  it
2   1   3   0   0   0   220 113 18  12  -1
3   1   3   1   0   0   220 113 18  12  -1
4   1   3   1   1   0   220 113 18  12  -1
5   1   3   1   1   1   220 113 18  12  79  it
2   1   4   0   0   0   303 8   209 118 -1
3   1   4   1   0   0   303 8   209 118 -1
4   1   4   1   1   0   303 8   147 20  -1
5   1   4   1   1   1   303 8   97  15  78  Bookman—
5   1   4   1   1   2   402 8   48  20  74  Light
4   1   4   1   2   0   303 43  186 18  -1
5   1   4   1   2   1   303 43  186 18  75  Bookman—Lighfltalic
4   1   4   1   3   0   303 76  155 15  -1
5   1   4   1   3   1   303 76  155 15  67  Baum-Dem!
4   1   4   1   4   0   303 110 209 16  -1
5   1   4   1   4   1   303 110 209 16  72  Boahmul-Dzmfltaflc

ちょっと認識ミスト取りこぼしが発生してますが、一列目の一行目のセルから順に出力されています(最後の列が認識したテキスト)。 拡大倍率としきい値処理をちゃんとやればちゃんと認識してくれるはずですが、とりあえず確かこんな感じだったはず。

それぞれの列ですが、levelpar_numというのはよくわかりませんが、ヘッダのconfは確からしさ、あとはそのまま。

TSV出力させるために必要なのはtessedit_create_tsvというパラメータなので、さらに挙動をコントロールすることも可能です。

上記のコマンドラインで指定しているtsvの実態は、tessdata/configsディレクトリ配下にあるtsvという設定ファイルです。

$ cat /usr/local/share/tessdata/configs/tsv
tessedit_create_tsv 1
tessedit_pageseg_mode 1

ある程度複雑なレイアウトの画像からテキストを認識する場合に有効だと思います。

各種OS向けパッケージ

Linux

Arch Linux はすでにパッケージが提供されています。

githubのリリースページで配布されているアーカイブは以前と異なり、configureスクリプトが含まれないので./autogen.shを実行する必要がある点に注意。もしくはcmakeを使うことも可能。

Ubuntu 17.04 に採用されるのかと思いきや、17.04 Beta 1 の時点では3.04系のままのようです。

Arch Linux

記憶違いでなければ新バージョンリリースの翌日だか翌々日にはパッケージが提供されていたはず。

$ sudo paceman -S tesseract
$ sudo paceman -S tesseract-data-{eng,jpn}

他の言語についてはpacman -Ss tesseract-dataで検索してインストール。なお、向き判定のosd.traineddataファイルは(Arch Linux のパッケージの場合)、本体と一緒に/usr/share/tessdataにインストールされる。

Ubuntu 16.04

バイナリパッケージは提供されていないのでソースからインストール。 Leptonica についてはバージョン 1.74系が必要です。

まずは必要なライブラリを一式インストールする。

sudo apt install autoconf automake libtool
sudo apt install autoconf-archive
sudo apt install pkg-config
sudo apt install libpng12-dev
sudo apt install libjpeg8-dev
sudo apt install libtiff5-dev
sudo apt install zlib1g-dev
sudo apt install libleptonica-dev

学習用のツールが必要なら下記もインストールしておく。

sudo apt install libicu-dev
sudo apt install libpango1.0-dev
sudo apt install libcairo2-dev

せっかくなのでcmakeを使いたいところだが、CMakeLists.txtというファイルにinstallターゲット用の記述がないのでmake installできない……。

Leptonica のインストール

Ubuntu 17.04用のパッケージをビルドし直すのもありかもしれないが、上書きしてほしくはないのでソースコードからビルドする。

ソースアーカイブgithubから入手する。

Releases · DanBloomberg/leptonica · GitHub

$ tar zxf leptonica-1.74.1.tar.gz 
$ cd leptonica-1.74.1/

ソースアーカイブを展開すると、`autobuild`というスクリプトがあるのでまずこいつを実行。

$ ./autobuild
$ ./configure
$ make -j2
$ sudo make install
$ sudo ldconfig

/usr/local配下にインストールされるはず。

Tesseract のインストール
$ tar zxf tesseract-3.05.00.tar.gz
$ cd tesseract-3.05.00.tar.gz

以前は不要だったような気がするが、./autogen.shを実行してconfigureスクリプトを生成。

$ ./autogen.sh
$ LDFLAGS="-L/usr/local/lib" CFLAGS="-I/usr/local/include" ./configure --with-training-tools
$ make
$ sudo make install
$ sudo ldconfig

学習用のツールが不要な場合はconfigureスクリプトの、--with-training-toolsは必要ない。

$ tesseract --version
tesseract 3.05.00
 leptonica-1.74.1
 libjpeg 8d (libjpeg-turbo 1.4.2) : libpng 1.2.54 : libtiff 4.0.6 : zlib 1.2.8

macOS

Homebrew はプルリク投げてみた結果、コメントを削除してマージされた。MacPports は3.04のまま。

以下はHomebrew の場合。

$ brew update
$ brew install  tesseract --with-training-tools

既存の学習済みの言語データしか使わないのであれば--with-training-toolsは不要。

途中でglibがらみでエラーになる場合は、表示されるメッセージの通りにする。

Error: You must `brew link glib` before tesseract can be installed

以下のようにbrew linkコマンドを実行してから上記のコマンドを再度実行する。

$ brew link glib

標準では英語とテキストの方向判別データしかダウンロードされないので、/usr/local/share/tessdata配下にそれぞれの言語別のデータファイルを(3.04用)ダウンロードしてコピーする(後述)。

このパッケージではtesstrain.sh関連ファイルはインストールされないので必要であればソースアーカイブから適当な場所にコピーする。

バグ対策

mac環境固有のバグ対策。
text2imageを実行する、あるいはtesstrain.shを使う場合は、環境変数PANGOCAIRO_BACKENDに値としてfcをセットする。

export コマンドでもいいし、コマンドの先頭にPANGOCAIRO_BACKEND=fcを付加していい。

参考:

$ PANGOCAIRO_BACKEND=fc ./training/tesstrain.sh --lang jpn --langdata_dir ../github_tesseract/langdata/  --training_text ../github_tesseract/langdata/jpn/jpn.training_text --fonts_dir /Library/Fonts/

それぞれのファイルのパスは環境に応じて修正。

なお、mac環境ではtesstrain.shをエディタで編集してmktempgmktempに置き換える必要あり。

Windows

公式ページからリンクされているのは今のところアルファ版であるバージョン4.0になっています。

ドイツの大学の方がビルドしたWindows 向けの開発版バイナリが以下より入手できるようです(3.05devと4.0dev)。ご利用は自己責任で。

github.com

“training tool"に関してはビルドした張本人がWindowsバイナリを使用していないようなので他の環境で。

Cygwin 版の方がトータルで見るとまともかもしれません。

Cygwin Package Search

それぞれの言語別のデータファイル

パッケージ管理ツール経由で取得できる場合はそちらから入手。Homebrew の場合は全部まとめてダウンロードするか、英語と向き判別用のデータだけの2択…。

[2017/03/11 追記]

公式ページに各バージョン(3.03rcを除く)向けのダウンロード用のリンクが記載されたページがあるので必要ならそこからダウンロード。

Data Files · tesseract-ocr/tesseract Wiki · GitHub

[追記ここまで]

GitHub - tesseract-ocr/tessdata at 3.04.00

リポジトリにある最新版は4.00用のファイルなので、3.04.00タグのツリーから取得する。

f:id:atuyosi:20170307165236p:plain

あるいは、言語コードが明らかな場合はwgetでURL直打ち。

$ wget https://github.com/tesseract-ocr/tessdata/raw/3.04.00/jpn.traineddata

jpnの部分を必要な言語に置き換えれば他の言語も取得できます。

ソースからビルドした場合は、/usr/local/share/tessdataにコピー。それ以外の場合はおそらく/usr/share/tessdata*6。 もしくは、環境変数 TESSDATA_PREFIXtessdataディレクトリの一つ上の階層のディレクトリを指定する。

まとめ

もう少しまともな検証用の画像を用意してみたいと思いますがひとまずここまで。

認識精度については3.04系と比較して特に改善していない印象です。バージョン4系に期待しましょうとしか。


何はともあれiOS向けのラッパーの安定板が新規リリースされて欲しいと思う今日この頃です。

それではまた。

*1:非互換云々とメンテナの労力を問題にしていたのは一体なんだったのか

*2:使っていないのでよくわかりません

*3:ファイルハンドラなどの解放もれ

*4: Page Segmentation mode

*5:環境変数ひとつで回避可能

*6:Ubuntuの公式パッケージは違う配置だったはず('/usr/share/tesseract-ocr/tessdata/‘)

開発版のTesseract 4.0 alpha をためしてみる その2

前回に引き続き、開発版のTesseract 4.0alpha ネタです。大した内容はありません。

a244.hateblo.jp

やったこと

前回の続きとして、新しいjpn.trainneddataファイルをバラして内容を確認してみます。

ファイルが混ざると面倒なので作業ディレクトリを2つ作ります。

$ mkdir 4.0a
$ mkdir 3.04

まず新しい方のjpn.traineddata。パスは Homebrew で開発版をインストールした場合した関係で、/usr/local/Cellar/tesseract/配下の'HEAD-'で始まるディレクトリ(フォルダ)になります。

$ combine_tessdata -u /usr/local/Cellar/tesseract/HEAD-23e420a_2/share/tessdata/jpn.traineddata 4.0a/jpn.
Wrote 4.0a/jpn.config
Wrote 4.0a/jpn.unicharset
Wrote 4.0a/jpn.unicharambigs
Wrote 4.0a/jpn.inttemp
Wrote 4.0a/jpn.pffmtable
Wrote 4.0a/jpn.normproto
Wrote 4.0a/jpn.punc-dawg
Wrote 4.0a/jpn.word-dawg
Wrote 4.0a/jpn.number-dawg
Wrote 4.0a/jpn.freq-dawg
Wrote 4.0a/jpn.shapetable
Wrote 4.0a/jpn.params-model
Wrote 4.0a/jpn.lstm
Wrote 4.0a/jpn.lstm-punc-dawg
Wrote 4.0a/jpn.lstm-word-dawg

以前と比較して、さりげなくファイルが増えています。

  • jpn.lstm
  • jpn.lstm-punc-dawg
  • jpn.lstm-word-dawg

dawgというのはデータ構造の名称の方(directed acyclic word graph : DAWG)のことでで、要は辞書データです。新しいlstmエンジン用の記号(句読点、Punctuation)辞書(punc-dawg)と、単語辞書(word-dawg)かと思います。

DAWGに関する参考ページ

tesstrain.shおよび、tesstrain_utils.shの修正内容からすると、既存コマンドのいくつかが新しく生成するファイルをリネームしているようです。

いつの間にかlstmtrainingというコマンドが追加されていますが、このコマンドが直接呼び出されている箇所は見つけられず。


比較対象のバージョン3.04用のjpn.trainneddataは以下の通り。

$ combine_tessdata -u ~/workspace/github_tesseract/tessdata/jpn.traineddata 3.04/jpn.
Extracting tessdata components from /Users/atuyosi/workspace/github_tesseract/tessdata/jpn.traineddata
Wrote 3.04/jpn.config
Wrote 3.04/jpn.unicharset
Wrote 3.04/jpn.unicharambigs
Wrote 3.04/jpn.inttemp
Wrote 3.04/jpn.pffmtable
Wrote 3.04/jpn.normproto
Wrote 3.04/jpn.punc-dawg
Wrote 3.04/jpn.word-dawg
Wrote 3.04/jpn.number-dawg
Wrote 3.04/jpn.freq-dawg
Wrote 3.04/jpn.shapetable
Wrote 3.04/jpn.params-model

md5チェックサムを比較すると新しく増えたファイル以外は全く同一でした。langdataリポジトリにはまだ更新はないみたいなので妥当といえば妥当です。


ついでなのでjpn.lstm-word-dawg を元のテキストに戻してみます。下記のコマンドでtemp.txtにdawg形式に変換される前の状態に戻せるはず。

$ dawg2wordlist 4.0a/jpn.unicharset 4.0a/jpn.lstm-word-dawg temp.txt
Loading word list from 4.0a/jpn.lstm-word-dawg
Reading squished dawg
Word list loaded.

中身を見ると理解不能な単語の羅列になっているようです。

$ wc -l temp.txt
  110077 temp.txt

先頭だけ抜粋。正直、何これというのが感想。

$ head -n 10 temp.txt
ワ
ワマ
ワマ想プ
ワマ想プナク燻ーア
ワマ想プナク燻ーア信
ワマ想プナク燻ーアな
ワマ想プKク燻ーア
ワマ想プケク燻ーア
ワマ想プれマ
ワマ想想|ナ

単語辞書をニューラルネットワークで自動生成したのでしょうかね? それともn-gram データから文字列生成したとか?


[2016/12/04 追記]

上記の件はバグかも。あるいは新しいエンジンは単語辞書を必要としないのか。

参考:LSTM: traineddata seem to be missing the lstm version of unicharset · Issue #527 · tesseract-ocr/tesseract · GitHub

jpn.unicharsetというファイルじゃなくて、専用のファイルがいるのか云々というのがIssueの内容。

まあ要調査ということで。

追記

OCRエンジンの再学習(トレーニング)について、公式Wiki に情報が記載されています*1

github.com

ざっくりいうと、以下のような感じ。

  • 学習プロセスの基本的な流れは同じだが、細部で変化している
  • 以前より遥かに時間がかかる
  • 完全に再学習させなくても良くなった
  • どこまで再学習させるかによって、いくつかの方法を選べる
  • これまでとは違い、非常に時間のかかるプロセスが存在するので完全に再学習プロセスを自動化できない

完全に再学習させない場合については以前より便利になると考えて良さそう。例えば書体の追加だけ、とか。


ざっと見たところ、変更点は以下。

  • 従来の.trファイルに変わり、.lstmfというファイルを修正する
  • .boxファイル(学習用の画像の、文字の位置と幅・高さ情報を記録したファイル)の書式の簡略化(行についての情報だけいいと書いてある)
  • これまでと異なり、同一画像内に複数のフォントが混在していても問題ない
  • クラスタ化ステップ(mftraining、cntraining, shapeclustering)にlstmtraining が使用される(と、書いてある)
  • たとえ新しいOCRエンジンしか使わないとしても、combine_tessdataコマンドは従来式のOCRエンジン用のファイルを要求する*2

新しいjpn.traineddataファイルが追加されたファイルを除いて以前とほとんど同じなのは、結局、追加されたファイル以外は従来式のOCRエンジン用ということで良さそう。

上記のWikiを見る限りjpn.lstm-number-dawgファイルが存在してもおかしくないはずだけど、そもそも生成元のファイルが空だったような気がするので当然か。

まとめ

ひとまずファイルが増えているということまでは確認しました。

それとlstmtrainingという思わせぶりなコマンドが追加されているようです。

以上です。

*1:二日前とか書いてあるし

*2:この点については将来改善予定と書いてある

開発版のTesseract 4.0 alphaをためしてみる(macOS)

この記事は開発中のアルファ版を対象にしてます。その点には十分注意してください。要するに自己責任でどうぞって話です*1

github.com

微妙に出遅れている感じがありますが……。

11月中旬ごろからメイン開発者のRay Smith氏によるバージョン 4.x のコードがgithubにコミットされています。

2、3日前からで各言語のXXX.traineddataファイルもアップロードされており*2ひとまず試せる状態。

まだ全ての言語が出揃っていませんが、英語などの主要言語はアップロードされているようです。

日本語用の言語別のデータもアップロードされています。


正式リリースがいつになるのかは不透明ですが、バージョン4.x の最大の特徴は今流行りのニューラルネットワーク技術の採用とのことです。 要するに深層学習とか強化学習とか言ってるアレ。

Long short-term memory(LSTM)による新認識エンジン*3

参考:4.0 with LSTM · tesseract-ocr/tesseract Wiki · GitHub

Ray Smithの講演資料:docs/das_tutorial2016 at master · tesseract-ocr/docs · GitHub

そもそもLSTM自体の仕組みがよくわかっていないので、OCR処理のどの部分にどういう形で組み込まれているのかはよくわかりません。


もう一つの新機能はTSV出力。地味だけど表形式のデータを読み取る場合には便利なはず。一応3.05ブランチ*4で入った新機能。

ただし、3.05というバージョンは今のところリリースされていません。されるかどうかは不明です。

macOS へのインストール

横着ですがHomebrew でインストールします。ビルドツールとして今までのautoconfとは別にcmakeも使えるようです。

依存ライブラリとしてOpenMPが必要になっています。そのため何も考えずに開発版をインストールしようとすると余裕で失敗します。

$ brew install tesseract --HEAD --with-training-tools
<skip>
lstm.cpp:22:10: fatal error: 'omp.h' file not found
#include <omp.h>
         ^
1 error generated.
make[2]: *** [lstm.lo] Error 1
make[2]: *** Waiting for unfinished jobs....
<skip>

ヘッダファイルが見つからないというエラーですが、そもそもmacOS 付属のllvmOpenMPに対応していないようです。
対処法は、ビルド用のコンパイラとしてgccをインストールするか、llvmの最新版をインストールするか、です*5

Homebrew で使用するコンパイラを切り替える最も簡単な方法として、--ccオプションにコンパイラのパッケージ名を指定する方法を利用します。

パッケージ名としてllvmを指定しても受け付けてくれないのでgcc6をインストールしました。本来であれば、brew edit tesseractするか、横着せずにgit cloneしてビルドする方が望ましいはずですが、面倒なので……。

$ brew install homebrew/versions/gcc6

非常に時間がかかります。泣きたくなります。バージョン番号なしのgccパッケージの場合、brewコマンド側がパッケージ名として認識しないので苦肉の策です。

依存ライブラリだけHomebrewでインストールして、コンパイラ環境変数CCとかCXX)で切り替える方が短時間で済んだような気もします。


さて本命。

$ brew install tesseract --HEAD --with-training-tools --cc=gcc-6

ビルドにさほど時間はかからないはずですが、--HEADを指定すると各言語用のデータを全部ダウンロードする*6のでそれなりに時間がかかります。

バージョンの確認

お約束。

$ tesseract -v
tesseract 4.00.00alpha
 leptonica-1.73
  libjpeg 8d : libpng 1.6.26 : libtiff 4.0.7 : zlib 1.2.8

やたらゼロの数が多い。


オプションを眺めてみる。

$ tesseract -h
Usage:
  tesseract --help | --help-psm | --help-oem | --version
  tesseract --list-langs [--tessdata-dir PATH]
  tesseract --print-parameters [options...] [configfile...]
  tesseract imagename|stdin outputbase|stdout [options...] [configfile...]

OCR options:
  --tessdata-dir PATH   Specify the location of tessdata path.
  --user-words PATH     Specify the location of user words file.
  --user-patterns PATH  Specify the location of user patterns file.
  -l LANG[+LANG]        Specify language(s) used for OCR.
  -c VAR=VALUE          Set value for config variables.
                        Multiple -c arguments are allowed.
  -psm NUM              Specify page segmentation mode.
  -oem NUM              Specify OCR Engine mode.
NOTE: These options must occur before any configfile.

Page segmentation modes:
  0    Orientation and script detection (OSD) only.
  1    Automatic page segmentation with OSD.
  2    Automatic page segmentation, but no OSD, or OCR.
  3    Fully automatic page segmentation, but no OSD. (Default)
  4    Assume a single column of text of variable sizes.
  5    Assume a single uniform block of vertically aligned text.
  6    Assume a single uniform block of text.
  7    Treat the image as a single text line.
  8    Treat the image as a single word.
  9    Treat the image as a single word in a circle.
 10    Treat the image as a single character.
 11    Sparse text. Find as much text as possible in no particular order.
 12    Sparse text with OSD.
 13    Raw line. Treat the image as a single text line,
            bypassing hacks that are Tesseract-specific.
OCR Engine modes:
  0    Original Tesseract only.
  1    Cube only.
  2    Tesseract + cube.
  3    Default, based on what is available.
  4    Neural nets (LSTM) only.

Single options:
  -h, --help            Show this help message.
  --help-psm            Show page segmentation modes.
  --help-oem            Show OCR Engine modes.
  -v, --version         Show version information.
  --list-langs          List available languages for tesseract engine.
  --print-parameters    Print tesseract parameters to stdout.

Page segmentation mode(psm)として11、12、13が追加されています。11と12は以前から存在したみたいです(ドキュメント未記載の隠しオプション扱い)。Sparse text と言われてもピンと来ませんが、文字(文章)がページ内に散らばっているイメージだと思います*7

特筆すべきは-oemオプションの方。

$ tesseract --help-oem
OCR Engine modes:
  0    Original Tesseract only.
  1    Cube only.
  2    Tesseract + cube.
  3    Default, based on what is available.
  4    Neural nets (LSTM) only.

ただし、Cubeエンジンは日本語非対応です。Cubeエンジンは将来廃止するという話だったはずですが、どうなるのかはわかりません。

お試し

まだアルファ版なので旧バージョンとの比較は先送りにします。

画像は過去記事から流用。

その1

f:id:atuyosi:20161201000524j:plain

その2

f:id:atuyosi:20161201003810j:plain

従来の認識エンジン

$ tesseract -oem 0 -psm 6  -l jpn image.jpg default_output
Tesseract Open Source OCR Engine v4.00.00alpha with Leptonica

最後の引数は出力ファイルの接頭辞です。この記事を書いている最中に思い出しましたが、ファイル名の接頭辞を指定する代わりにstdoutを指定すると標準出力に結果を出力してくれます……。

なお、設定を切り替えたい場合はコマンドライン引数の最後に指定できます(ドキュメント参照)。

$ cat default_output.txt
こ れは 日本語の文章です。 随 ヽろ はに ほへ と

まあ、平常運転です。サボらずに画像を拡大すべきです。-psmは6ではなくて7の方がベターかも。

その2

$ tesseract -oem 0 -psm 6  -l jpn image2.jpg default_output2
Tesseract Open Source OCR Engine v4.00.00alpha with Leptonica
$ cat default_output2.txt
オープンソースの光学文字認識ライブラリを試してみます。 )
Tesseractー〇CR は600gーeの資金援助宣受けてゝ開発されてしヽるりししヽです。
英数字の認識率は97%とか。漢字や平仮名はどっでしよつか。

画像を拡大すればもっと良くなったはず。

新しい認識エンジン

$ tesseract -oem 4 -psm 6  -l jpn image.jpg lstm_output
Tesseract Open Source OCR Engine v4.00.00alpha with Leptonica
Warning in pixWriteMemPng: work-around: writing to a temp file
Warning in pixReadMemPng: work-around: writing to a temp file

警告メッセージから見ると、一時ファイルに書き出して読み込んでる?

結果その1

$cat lstm_output.txt
これ は 日本 語 の 文章 で す 。 いろは に ほ へ と

結果その2

$ tesseract -oem 4 -psm 6  -l jpn image2.jpg lstm_output2
Tesseract Open Source OCR Engine v4.00.00alpha with Leptonica
Warning in pixWriteMemPng: work-around: writing to a temp file
Warning in pixReadMemPng: work-around: writing to a temp file
Warning in pixWriteMemPng: work-around: writing to a temp file
Warning in pixReadMemPng: work-around: writing to a temp file
Warning in pixWriteMemPng: work-around: writing to a temp file
Warning in pixReadMemPng: work-around: writing to a temp file

認識対象の行数が増えると警告メッセージの行数も増えるの?

$ cat lstm_output2.txt
オープン ソ ー ス の 光 学 文 字 認 識 ラ イブ ラ リ を 試し て み ま す 。 。 _
TesseractLOCR は Google の 賄 金 援 助 を 受 け て 開発 され て いる ら し いで す 。
英 数 字 の 認 識 率 は 9700 と か 。 漆 字 や 平仮名 は どう で しょ うか 。

文字間のスペースが気になりますが、許容範囲でしょう。2行目は格段に良くなっているように見えます。3行目は"%"と”漢”を ミスってます。

いままでイマイチだった日本語中の英単語の認識率が改善しているかも。

警告メッセージが気になりますが、認識率自体は改善しそうです。


せっかくなので画像を拡大してみます。

$ convert -geometry 120% image.jpg image2_large.jpg
$ tesseract -oem 4 -psm 6  -l jpn image2_large.jpg lstm_output2
Tesseract Open Source OCR Engine v4.00.00alpha with Leptonica
Warning in pixWriteMemPng: work-around: writing to a temp file
Warning in pixReadMemPng: work-around: writing to a temp file
Warning in pixWriteMemPng: work-around: writing to a temp file
Warning in pixReadMemPng: work-around: writing to a temp file
Warning in pixWriteMemPng: work-around: writing to a temp file
Warning in pixReadMemPng: work-around: writing to a temp file

さて、結果はどうか。

$ cat lstm_output3.txt
オ ー プ ブ プ ブン ソース の 光 学 文字 認識 ラ イ ブラ リ を 試し て み ます 。 。 __
TesseracrOCR は Google の 賞 金 援 助 を 受 け て 開発 され て いる らし い です 。
英 数字 の 認識 率 は 979%% と か 。 漢 字 や 平仮名 は ど う でしょ うか 。

1行目と3行目が不思議な出力になっています……。Google 翻訳も謎の文字列の繰り返しを出力するケースがあるので同じようなもの?


他にも試したいことはありますが、ひとまずここまで。

追記

tesseractコマンドのオプション形式が変化するようです。

Support standard parameter form --oem, --psm for tesseract executable by stweil · Pull Request #515 · tesseract-ocr/tesseract · GitHub

当面は 従来と同じ形式も使用できるようですが、今後は-psm(ハイフンは1つ)から--psm(ハイフンは2つ)になるようです。

一般的なGNUのコマンドと形式を合わせましょう、という変更です。影響の大きい変更はメジャーバージョンアップの時にやった方がいいよねとかなんとか。

まとめ

新しいOCRエンジンはこれまでよりは期待できるのではないでしょうか。

Google group のやり取りを読む限りでは従来の認識エンジンをどうするか、とか、メジャー番号が上がるついでに互換性のない変更を入れようとか色々と議論がされいます。

バージョン 4.0の前に3.05 をリリースするとかしないとか。

個人的にはTSVファイル出力機能だけでいいので3.05がリリースされる方がいいと思っています。


githubwikiにはSSE命令がどうのこうのという記述があるのでiOS用のライブラリへの移植は時間がかかりそうな雰囲気。

かなり適当なエントリになってますが以上です。

*1:安定版リリースだろうと転んでも泣かないのがOSS

*2:tessdata リポジトリの方を参照

*3:ニューラルネットワーク関連の技術を活用したということしか理解していないです

*4:いつのまにか3.05devから3.05にリネームされてる

*5:llvm の clang 3.9 からOpenMPに対応したとのこと

*6:tesseractのFormulaがそうなっているせいです

*7:試してないです

Tesseractの各言語のラッパーいろいろ(随時更新)

TesseractというのはGoogleが開発を支援しているオープンソースOCRエンジンです。

Tesseract本体のインストールについては公式のWikiを参照。もしくはググって下さい。

github.com

TesseractのC/C++APIを使用するタイプと、tesseractコマンドを呼び出すタイプの2系統があります。

Web APIなどの形式で使う場合、tesseractコマンドを呼び出すタイプはリクエストの度にプロセスを生成することになるので好ましくないかと。

続きを読む

広告