OCRの仕組みをわかりやすく解説
OCRエンジンの中で何が起きているのかを、画像の補正からニューラルネットワークによる認識までやさしく解説。0とOを取り違える理由もわかります。
更新日
OCR(光学文字認識)は、画像を見て、そこにどんな文字が含まれているかを割り出すソフトウェアです。簡単そうに聞こえますが、画像の正体を思い出してください。画像は色の付いた点が格子状に並んだものにすぎません。ファイルのどこにも「これはAという文字」「この行はあの行より前」とは書かれていません。そのすべてを推測で導き出す必要があります。
このガイドでは、現在のOCRエンジンが行っている処理を、Tesseractを例に順を追って説明します。Tesseractは広く使われているオープンソースのエンジンで、もともとHewlett-Packardで開発され、のちにGoogleの支援のもとで保守されてきました。Image to Text Appがブラウザ内で動かしているのもこのエンジンです。ほかのエンジンでは細部が異なりますが、処理の段階はほぼ同じです。
処理の流れ
- 文字が目立つように画像を補正する。
- レイアウトを解析し、テキストのまとまりとその順序を見つける。
- まとまりを行に、行を単語に分ける。
- 各行の文字を認識する。
- 言語の知識を使って、ありそうな読み方の中から選ぶ。
- 単語ごとの信頼度を計算し、結果を出力する。
画像の補正
認識がもっともうまくいくのは、無地の明るい背景にくっきりした濃い文字が載っている状態です。そこで最初の仕事は、画像をできるだけその状態に近づけることです。
二値化は、ピクセル一つひとつがインクか紙かを判定し、画像を純粋な白と黒に変換します。古典的な手法である大津の二値化は、画像全体の明るさの分布を見て、2つのグループをもっともよく分けられるしきい値を1つ選びます。きれいなスキャン画像ならこれでうまくいきます。ところが、片隅に影が落ちたスマートフォンの写真では、しきい値が1つだけだと失敗します。影の部分が真っ黒になるか、明るい部分の薄い文字が消えてしまうのです。適応的な手法は、各ピクセルをページ全体ではなく周囲の領域と比べることで、この問題を解決します。
傾き補正は、テキストの行が傾いているかどうかを検出し、行が水平になるように画像を回転させます。わずか数度の傾きでも、行が上の行に入り込んでしまい、その後の処理が台無しになることがあります。
ほかにも、細かな点やスキャナーのほこりを取り除く、文字に十分なピクセル数を確保するためにごく小さな文字を拡大する、暗い背景の明るい文字を反転する、といった補正があります。Tesseractのドキュメントでは、現在のバージョンには明るい背景に濃い文字が推奨されています。多くのツールがダークモードのスクリーンショットを読み取る前に反転するのはそのためです。
レイアウトの解析
次にエンジンは、ページに何があるかを割り出します。テキストのまとまり、画像、罫線、段組みなどです。読む順番も決めなければなりません。
この段階は、特にわかりにくい誤りの原因になります。2つの段のあいだの余白を見落とすと、エンジンは両方の段を横にまっすぐ読んでしまい、それぞれの文の切れ端が混ざります。キャプションがその下の段落とくっついてしまうこともあります。表が、おおよそ正しい順番に並んだ単語の寄せ集めになってしまうこともあります。
エンジンは通常、呼び出す側のソフトウェアが、ページ全体、1つのまとまり、1行、散らばったテキストなど、入力の種類を指定できるようになっています。この指定は重要です。レシートを本のページのように読むと、散らばったテキストとして読む場合より結果が悪くなることがあります。
行と単語の検出
各まとまりの中で、エンジンはテキストの行を見つけます。共通のベースライン上に並んだインクの列を探し、行の比率を測ります。xのような小文字の高さや、アセンダー(b、d、h)やディセンダー(g、p、y)がどこまで伸びているかです。
単語は間隔から判断されます。単語と単語のあいだの空白は、ふつう文字と文字のあいだより広くなっています。文字間が詰まっていると2つの単語が1つにくっつき、両端揃えで間隔が広がった文章では1つの単語が2つに分かれることがあります。
文字の認識
バージョン3までのTesseractを含む古いOCRエンジンは、各単語を1文字ずつに切り分け、それぞれの形を学習済みの形と比べていました。この方法は、にじんだ「rn」のように文字同士がくっついている場合や、かすれた印刷で文字がバラバラになっている場合にうまくいきません。
2018年にリリースされたTesseract 4では、LSTM(長短期記憶)ニューラルネットワークに基づく認識器が加わりました。文字を切り出すのではなく、1行のテキスト全体を連続したものとして読み、行に沿って進みながら、各位置であらゆる文字の可能性を見積もります。ネットワークは行に沿って情報を持ち越すので、ある文字の前後の形を手がかりにその文字を判断できます。にじんだ文字を、隣の文字を見て読み解くのと同じです。
ネットワークは実例から学習します。Tesseractの公式モデルは、さまざまなフォントで描画された大量のテキストで学習しており、言語や文字体系ごとに別々のモデルがあります。正しい言語を選ぶことが大切なのはそのためです。英語で学習したモデルはデーヴァナーガリー文字がどんな形か知りませんし、éやñのようなアクセント付きの文字を想定していないこともあります。
言語の知識と辞書
認識器が出すのは1つの答えではありません。各行について、ありそうな読み方を、それぞれの確からしさとともにたくさん出します。そのあと探索によって最善のものが選ばれます。このとき、単語リストや、その言語でよく使われる文字の組み合わせについての知識が判断を後押しします。
この後押しで多くの誤りが直ります。ぼやけた「tbe」は、「the」が単語で「tbe」は単語ではないので「the」になります。ただし、これが裏目に出ることもあります。製品コード、名字、略語、別の言語の単語は単語リストにないため、エンジンが得られる手助けが少なく、誤読しやすくなります。
信頼度スコア
エンジンは単語ごとに、どのくらい確信があるかも報告します。これは、第一候補の読み方がほかの候補をどれだけ大きく上回ったかに基づいています。ツールはこれを使って、確認してほしい単語に印を付けます。
信頼度はあくまでヒントであり、保証ではありません。スコアが低ければ、たいてい何かが間違っています。スコアが高ければ、たいてい正しいのですが、エンジンが自信満々に間違えることもあります。本来はゼロであるべきシリアル番号の中のくっきりした「O」は、エンジンにはまったく問題なく見えるのです。
誤りが起きる理由
OCRの誤りの多くは、いくつかのパターンに分けられます。
- 形の似た文字。 0とO、1とlとI、5とS、8とB。多くのサンセリフ体では、大文字のIと小文字のlがまったく同じ形なので、人間でも文脈が必要です。
- 形の似た文字の組み合わせ。 「rn」が「m」に、「cl」が「d」に、「vv」が「w」に読まれる、またはその逆。
- 句読点。 カンマやピリオドはとても小さいので、ほこりがピリオドになったり、薄い小数点が消えたりします。
- 頼れる文脈がない。 コード、ID、電話番号、メールアドレスの周りには辞書にある単語がないため、1文字1文字が孤立しています。
- レイアウトの誤り。 段組みを横に読む、キャプションが本文と混ざる、表の行が入れ替わる。
- モデルが学習していない文字。 装飾的なフォント、デザインされたロゴ、縦書きのテキスト、そして特に手書き文字。
これらのほとんどは、画像をより鮮明に、より大きく、よりまっすぐにするだけで大幅に減ります。何を変えればよいかはOCRの精度を上げる方法で紹介しています。
認識のあとに行われること
エンジンがそのまま出力するのは単語のリストで、各単語には画像上の位置と信頼度スコアが付いています。アプリはこの位置情報から構造を組み立てます。縦の列にそろって並んだ単語は表になります。詳しくは画像から表を抽出する方法で説明しています。ラベルのあとに日付や合計が続く行はレシートの項目になります。各行の左端からの距離は、コードのインデントになります。
OCR、ICR、HTR、AIモデル
関連する用語をいくつか目にすることがあるかもしれません。従来、OCRは印刷された文字を指します。ICR(インテリジェント文字認識)は、手書きの活字体の文字、典型的には申込書の枠に1文字ずつ書かれた文字を読むことを指します。HTR(手書きテキスト認識)は、続けて書かれた手書き文字を読むことを指し、ふつうは手書きのサンプルで学習したニューラルネットワークを使います。実際の違いについては手書きメモをテキストに変換する方法で紹介しています。
新しいAIシステムの中には、大規模言語モデルを使って画像からテキストを生成することで文字を読むものもあります。乱雑な入力にもうまく対応できますが、流暢な文章を生成するため、誤りが、画像には存在しないもっともらしい単語に見えてしまうことがあります。どの種類のシステムを使う場合でも、重要な部分は元の画像と照らし合わせて確認してください。