2019/01/31

Excelで書類の発行元をロゴ画像認識により判定する実験

当社には、いろいろな書類が数多く届き、それを逐一スキャンして整理しているのだが、書類の数量が多すぎて仕分けが大変であるために、このような仕分けソフトを過去に作った。

不動産業で使える PDF文書の向き自動補正とTF-IDF×コサイン類似度によるPDF文書の自動仕分け


この書類仕分けソフトは、TFIDF×コサイン類似度というアルゴリズムで動いており、簡単にいえば自然言語解析をベースにしたものである。

最近は、この記事からさらなる改良を重ね、当社に届く業務書類であれば8割以上は正しく仕分けができるようになっている。

しかし、この仕分けソフト、その設計上、OCRした後の文字列のみを頼りに仕分けをしている。画像は一切見ていない。そうすると、銀行の振込伝票のように
・文字量が極端に少なく文字だけでは何の書類だか判別できない
・銀行名の印字もない(もしくは帳票がドロップアウト印刷のためOCRで正しく文字が読み取れていない)
・だが、銀行のロゴは出ているので人間が見れば一目瞭然
というような帳票はエラーになってしまい、がっかりする。
なので、今回は、ロゴが出ているならばそれを頼りに「銀行関連の書類」であると書類カテゴリを推定し、また、発行した銀行名を当ててみよう。という試みである。

では、どのようなロジックで認識するか。これが問題である。
Convolutional Neural Networkのような画像認識のロジックを作るどころか理解するのも困難であるため、ここは素直にOpenCVに依存しようと考え、
python+OpenCVでAKAZEなる認識を試したものの、思ったように精度が出なかった。


右にお手本となる某大企業のロゴがあり、書類上のロゴと結ばれるはずだったのだが、誤認識している。おそらくこれは認識ロジックがロゴに適していなかったのかな。という気もする。
それを差し引いても、OpenCVを操る面倒さと、思ったよりも期待した精度は簡単には出ないことを知っている人ならば、人工知能で人間の仕事がなくなるのは、もうしばらく先であることを理解できるだろう。

OpenCVでの物体認識は認識は引き続き研究するとして、単純明快に次のようなロジックを自作するのはどうだろうと試してみた。
・お手本ロゴと入力書類をモノクロBMP化する
・BMPから輝度の値(黒0~255白)を抜き出してExcel上に展開する
・色が全体的に薄い書類は、その書類の中で最も濃い色を真っ黒と見なして正規化する
・書類は1024×724=741,376の輝度の羅列。それをExcel上に展開する。ロゴも同様に輝度をExcel上に展開する。
・あとはロゴを1ピクセルずつ、縦と横に計約74万回スライド(スキャン)させていき差の絶対値を取得する
→差の絶対値の総和がゼロであれば、お手本ロゴとスキャンした範囲はぴったり同じである。なので、総和が小さい方がお手本との一致度が高い。
→二枚の紙を太陽に向けて透かして差分を目視するのと同じ原理。


モノクロ書類画像の輝度をExcel上に並べると書類を間近で見たのと同じ模様が浮かび上がる。銀行!


おもしろい。

さて、問題は、総当たりスキャンの計算量である。
書類のサイズ1024×724=741,376ピクセル そして、ロゴのサイズ44×38 = 1,672ピクセルをかけ算して、12億セルほどを計算しなければならない。VBAでループなどを作ってしまうと画像1枚で数十分ほどかかってしまう。ExcelのVBAは、うまく使わないと非常に遅い。極力、使わないほうが良い。このイメージが悪いためか、Excelは非常に遅いアプリだと思われがちだが、じつは関数による計算はとても速いのである。
なので、ここはCPUによる並列処理が可能な関数だけで、セル範囲の差の絶対値の総和を取得したいところである。調べたところ、次のような配列を使うととても良い。


指定した矩形範囲 vs 別の矩形範囲(当然に同セル数でなければならない)の差の絶対値の総和を計算してくれる。これのすごいのは、14億セル分の計算を10秒くらいで完了(i7-8700K)できる点である。非常に速い。正直、画像が認識できたことよりも、Excelがここまで高速であることに感動した。

さて、これを書類のサイズ1024×724=741,376セルのすべてに対して計算していくと、最も差の絶対値の総和が少ない点(お手本ロゴ画像を書類上で縦横無尽にスライドさせて照らし合わせたときに最も差異が小さいカ所)が上記の画像のように浮かび上がってきた。
実際、この番地を書類上で見てみると、ロゴの開始位置の左上端であり、正しく検出できている。(商標の関係で他社のロゴを出すわけにもいかないので話が分かりにくいかもしれないが、そのうち自社ロゴに差し替えて分かりやすい説明にしてみたい)

まだ実験段階ではあるが、このようにExcelでも書類上からロゴを検出するロジックは実用的に組める気がした。

完全一致のマッチングというアルゴリズムの性質上、ロバスト性はどうなのか。というのが気になるところ。
1ピクセルでもずれたらまったく一致しないかと思ったのだが、思ったよりも大丈夫そう。
どうやら入力画像の質が良いことが関係している。最近のスキャナはエッジをきれいに階調で読み込んでくれるので、真っ白の次に真っ黒が来ることはない。なんとなくグラデーションになっている。そのため、1-2ピクセルずれていても、都合良くマッチするのである。

ただ、拡大縮小に対しては耐性がゼロに近いので、100枚くらいロゴの拡大縮小を生成して準備する必要があるだろう。
そうすると書類1枚当たり10分以上かかってしまうが、夜間のバッチ処理であれば耐えうる速度ではある。
もしくは、投資家はコンピュータを買う金くらいはあるのだから素直に多コアのコンピュータやVMを買えばよいだろう。

この画像認識アルゴリズムは、近いうちに当社の書類仕分けシステムに実装していきたいと思っている。