光学文字認識(OCR:Optical Character Recognition)って?

f:id:ts0818:20201010165229j:plain

光学(こうがく、英語optics)は、の振舞いと性質および光と物質相互作用について研究する、物理学のひとつの部門。光学現象を説明し、またそれによって裏付けられる。

光学で通常扱うのは、電磁波のうち光と呼ばれる波長域(可視光、あるいはより広く赤外線から紫外線まで)である。光は電磁波の一種であるため、光学は電磁気学の一部門でもあり、電波X線マイクロ波などと類似の現象がみられる。光の量子的性質による光学現象もあり、量子力学に関連するそのような分野は量子光学と呼ばれる。

光学 - Wikipedia

⇧ 「光」についての研究が「光学」ということですが、

「光」という漢字の成り立ちが、

japanknowledge.com

人の頭の上に火の光を書き、神聖な(神のように尊い)火を強調してみせている字です。古代の人びとにとって火は非常に神聖なものでしたから、火を守って神に仕える人がいました。光の字はそのような火を扱う聖職者を示しています。
のち火の「ひかり」そのものを光といい、光を出して美しく見えることから「かがやく」の意味となり、その意味を人に使って「ほまれ」(よい評判。名誉)という意味にも使います。

第13回 人の形から生まれた文字〔1〕 人を横から見た形(4) | 親子で学ぼう!漢字の成り立ち

⇧ 「人」を元にしてるところが意外と言うか...

常住坐臥、ネガティブキャンペーン中、いつかはポジティブな人間になりたい、どうもボクです。

と言うわけで、今回は、「OCR(Optical Character Recognition)」について調べてみました。レッツトライ~。

 

OCR(Optical Character Recognition)って?

まぁ、Wikipediaさんに聞いてみる。 

光学文字認識(こうがくもじにんしき、Optical character recognition)は、活字の文書の画像(通常イメージスキャナーで取り込まれる)を文字コードの列に変換するソフトウェアである。一般にOCRと略記される。OCRは、人工知能マシンビジョンの研究分野として始まった。研究は続けられているが、OCRの中心はその実装と応用に移っている。紙に印刷された文書をデジタイズし、よりコンパクトな形で記録するのに必要とされる。さらに、文字コードに変換することで機械翻訳音声合成の入力にも使えるようになり、テキストマイニングも可能となる。研究分野としては、パターン認識人工知能コンピュータビジョンが対応する。

光学文字認識 - Wikipedia

⇧ ってな感じで、「画像」から「文字コード」に変換してくれるソフトウェアが「OCR(Optical Character Recognition)」ですと。

(鏡やレンズといった光学技術を使った)光学文字認識と(スキャナーとアルゴリズムによる)デジタル文字認識は本来別の領域と考えられていた。光学技術として生き残った部分が非常に少ないため、光学文字認識という言葉は現在ではデジタル文字認識を含むものとみなされている。

光学文字認識 - Wikipedia

⇧ う、う~ん...「OCR(Optical Character Recognition)」とは言うものの、「光学」の部分の面影がほぼ無くなってきてるらしいですと。

歴史はかなり古く、

光学文字認識の原点は、電信技術の拡張と視覚障害者が文字を読むための機械の開発という2つの問題にまつわる活動である。1914年エマニュエル・ゴールドバーグは、文字列を読み取り電信符号に変換する機械を開発した[要出典]。同じころエドマンド・フルニエ・ダルベ英語版オプトフォン英語版という携帯型スキャナを開発した。これを印刷物のページ上ですべらせると、文字の形状によって異なる音を発する。

光学文字認識 - Wikipedia

⇧ いま、2020年だから、100年以上研究が続けられてるみたい。

日本だと、

なお、日本では漢字の読み取りが難しいため、1968年7月1日に郵便番号が導入され、手書きの数字である郵便番号をOCRシステムで読み取って並べかえていた。1998年に郵便番号の7桁化がなされてからはOCRで読み取った際にアメリカのようにバーコード(ただしこちらは可視光では無色なインクを使用)を印刷するようになった。

光学文字認識 - Wikipedia

⇧ ってな具合に、「郵便番号」で初めて「OCR(Optical Character Recognition)」が導入されたっぽい。

ちなみに、

オンライン文字認識光学文字認識と混同されることがある手書き文字認識参照)。OCRは基本的にオフラインの文字認識であり、純粋に文字の静的な形状を認識する。一方オンライン文字認識は、文字が書かれる動的な過程を認識する。例えば、PenPoint OS やタブレットコンピュータなどがジェスチャーを認識するのもオンライン認識の一種であり、ペンがどういう方向にどれだけ動いたかを認識する。オンライン手書き文字認識を知的文字認識英語版 (ICR) とも呼ぶ。

光学文字認識 - Wikipedia

⇧ ってな具合に、

以下のように分類できますと。

項目
 オフラインの文字認識  光学文字認識
 OCR(Optical Character Recognition)
 オンライン文字認識  手書き文字認識(知的文字認識)
 ICR( Intelligent Character Recognition

で、この「手書き文字認識」ってのがなかなか厄介らしく、特にデジタル化されていない、紙媒体に直接描かれた文字については、

一方、紙に書かれた手書き文字を認識するソフトウェアには上記の利点が無いため、識字率はいまだ十分とは言えない。きれいに書かれた手書き文字でも識字率は80%から90%であり、1ページにつき数十個の認識不能文字が出現することになる。これは非常に限られた分野でしか実用化できないレベルである。

光学文字認識 - Wikipedia

⇧ かなり厳しい状況と言えそう。

筆記体になると、

筆記体文書の認識は研究が盛んであるが、識字率はさらに低い。筆記体の文字認識の識字率を高めるには、文脈や文法の情報を使わなければならない。例えば、辞書の単語を認識するのは、手書き原稿の個々の文字を認識するよりも簡単である。小切手に書かれた数字の列は小さな辞書を使えばいいので識字率を上げることができる。スキャンしている文書の言語の文法に関する知識があれば、単語が名詞なのか動詞なのかを判別することが可能となり識字率を上げることができる。手書き文字の形だけでは正確な認識(一般に98%以上)は不可能といってよい。

光学文字認識 - Wikipedia

⇧さらに絶望的らしい。

日本だと、「書道」の文化があるけれど、「識字率」はどうなっちゃうんでしょうね...

shodo-kanji.com

⇧ 「草書」とかになってくると、「達筆」であればあるほど、認識が難しそう...

 

OCR(Optical Character Recognition)が活用される分野って?

100年以上の研究の歴史があり、未だ解決できない課題を抱え発展途上ではある「OCR(Optical Character Recognition)」 ですが、どんな分野で活躍しているのか?

scansnap.fujitsu.com

OCRとは画像の中から文字を見つけ出して、文字データに変換する技術です。
単純にスキャンした場合、書類などは画像として読み込まれます。でも、OCR処理をすることで画像の中にあるテキスト部分を数字や文字として読み込むことが可能になります。読み込まれたテキストは、パソコンに入力した文字と同じようにコピー&ペーストしたり、検索をかけることができます。郵便番号や銀行の振込用紙の読み取りなど、身近な所にもOCR技術が使用されています。

OCR(文字認識)するときに注意したいポイント!

⇧ 皆々様、ご推察の通り、「郵便番号」「銀行の振込用紙」など、「紙文化」のあるところ「OCR(Optical Character Recognition)」あり、と言った感じでしょうか。

 

AI OCR とは?

文字通り、

「AI(Artificial Intelligence)」+「OCR(Optical Character Recognition)」 

ってな感じで、「OCR(Optical Character Recognition)」 に「AI」を導入したものらしいですと。

www.ricoh.co.jp

技術開発や製造の現場だけではなく、最近ではスマートフォンの機能や自動運転技術などにも活用されていることで知名度が高まったAI(人工知能)は、あらゆる分野での活躍が期待されています。

その1つとして挙げられるのが、OCRとAIを融合させた「AI OCR」です。

「AI OCR」とは~OCRとの違いと3つのメリット | リコー

様々な帳票に記載された項目の自動抽出ができる「AI OCR」は、従来手作業で行っていた伝票入力作業を効率化することができ、生産性を高めるツールとして、注目されています。

「AI OCR」とは~OCRとの違いと3つのメリット | リコー

⇧ ってな感じで、「AI」導入により「自動化」できる部分がでてきますと。

とは言え、

cweb.canon.jp

重要なのは、「AI OCR=すべてを任せっきりにできる」という発想は捨てること。読み取り精度ばかりにとらわれず、AI OCRは不完全なものだと認識した上で、ベストな付き合い方を見つけることが大切なのです。すなわち、AI OCRを利用する際には必ず人間によるチェック&修正作業が不可欠になりますが、そうした手間を加味しても業務効率化や費用対効果につながるかどうか、まずは慎重に見極める必要があります。

だんだん明らかになってきたAI OCRの限界―業務全体を今一度見直すことが成功のポイント:キヤノン

⇧ 「AI OCR」でもできないことは当然でてきますと。

 

「RICHO」さんも「Canon」さんも、「画像認識」系に強いイメージですが、「AI」で補えない部分は「RPA(Robotic Process Automation)」と連携させるという点は共通してそうです。

 

OCR(Optical Character Recognition) のアーキテクチャって?

まぁ、「画像」を「文字コード」に変換できる 「OCR(Optical Character Recognition)」ということですが、どんな「アーキテクチャ」なんだと?

⇧ だったり、

medium.com

⇧ だったり、全体の仕組みとしては、「画像」を「インプット」にして「テキスト」を「アウトプット」するってことみたいですと。

一般的な「OCR(Optical Character Recognition)」の「アーキテクチャ」は、

www.researchgate.net

⇧ ってな感じで、

工程 内容
 Pre-Processing  画像として読み込んだデータを編集できるようにする
 Segmentation  画像を分割された分類可能なオブジェクトに編集する
 Feature Extraction  分割された分類可能なオブジェクトをベクトル化する
 Classification  ベクトル化されたオブジェクトを分類
 Post Processing  機械語のドキュメントに変換

の5つの処理を経て、「マシン」が解釈できる形に変換されるらしい。 

 

en.wikipedia.org

⇧ 英語版の「OCR(Optical Character Recognition)」のWikipediaの「Techniques」にどんな処理を経るのか記載されてますかね。

 

JavaOCR(Optical character recognition)

そんじゃ、実際にプログラミングで「OCR(Optical Character Recognition)」っぽいことしてみますか。

「AI OCR」とか出てきてるから、Python とかを利用したほうが良いのかもしらんけれど、Java で実装していきたいと思います。

で、Javaで「OCR(Optical Character Recognition)」を実現するライブラリとしては、

mslabo.sakura.ne.jp

Tesseract OCRは元々C++用のライブラリなのですが、これをJavaから利用できるようにしたTess4Jが、以下のサイト様で公開されています。

 

OCRを実現するには | 自己啓発。人生について考える

⇧ 上記サイト様によりますと、「Tess4J」ってものが有名らしい。

 

と言うわけで、「Tess4J」を使ってみようということで、今回は、「ビルドツール」に「Maven」を使用していこうと思うので、

mvnrepository.com

Maven Repository からライブラリをインストールするということで。「Tess4J」のバージョンは「4.5.3」を選択することにします。

 

そんでは、Eclipseを起動して、「ファイル(F)」>「新規(N)」>「Maven プロジェクト」を選択。

f:id:ts0818:20201010133650p:plain

f:id:ts0818:20201010133817p:plain

今回は「アーティファクトId」が「maven-archetype-profiles」ってのを選択しました。「次へ(N)>」で。

f:id:ts0818:20201010134850p:plain

アーティファクトId」を適当に入力し「完了(F)」で。

f:id:ts0818:20201010134134p:plain

Mavenプロジェクト」が作成されます。

f:id:ts0818:20201010135108p:plain

そしたら、「pom.xml」に「Tess4J」の依存関係を追加します。

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>ts0818</groupId>
  <artifactId>ocr</artifactId>
  <packaging>jar</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>Maven Quick Start Archetype</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/net.sourceforge.tess4j/tess4j -->
    <dependency>
      <groupId>net.sourceforge.tess4j</groupId>
      <artifactId>tess4j</artifactId>
      <version>4.5.3</version>
    </dependency>
  </dependencies>
</project>

んで、「pom.xml」を保存すると、「Maven 依存関係」に「Tess4J」に関連したライブラリ群が追加されます。

f:id:ts0818:20201010140223p:plain

あとは、「日本語」を解析できるように、

github.com

⇧ 上記から「jpn.traineddata」を選択して、ダウンロードしておきます。

f:id:ts0818:20201010153440p:plain


「Tess4J」が使えるように、実装してみます。

今回は、「Mavenプロジェクト」を作成した時にデフォルトで作成された「App.java」にコーディングします。

f:id:ts0818:20201010140511p:plain

その前に、OCROCR(Optical Character Recognition))を実施する対象を「Mavenプロジェクト」に配置するために、適当なフォルダを作ります。

その前に、Eclipseの「パースペクティブ」を「Java EE」に切り替えます。

以下の赤枠で囲んだ部分をクリック。

f:id:ts0818:20201010141355p:plain

Java EE」を選択し、「開く(O)」で。

f:id:ts0818:20201010141452p:plain

「プロジェクト・エクスプローラー」の以下の赤枠で囲んだ部分をクリックし、「フィルターおよびカスタマイズ(F)...」を選択。

f:id:ts0818:20201010141715p:plain

「.*リソース」にチェックが付いているので、

f:id:ts0818:20201010142047p:plain

「.*リソース」のチェックを外して「OK」。

f:id:ts0818:20201010142136p:plain

「プロジェクト・エクスプローラー」に「.classpath」ファイルなどが表示されればOK。 

f:id:ts0818:20201010142238p:plain

そんでは、OCROCR(Optical Character Recognition))を実施する対象を配置するためのフォルダを作成します。

まずは、「リソース」用のフォルダを作成で。(今回で言うと、「Java」以外のファイルを配置する用途)

「プロジェクトルート」のフォルダを選択し右クリックし、「新規(N)」>「ソース・フォルダー」を選択。

f:id:ts0818:20201010142510p:plain

「フォルダー名(D):」を「src/main/resources」で「完了(F)」で。

f:id:ts0818:20201010142705p:plain

「src/main/resources」が作成されました。

f:id:ts0818:20201010142737p:plain

「ソース・フォルダー」を作成した場合、「.classpath」ファイルに追記されるようです。今回は、以下が追記されてました。

<classpathentry kind="src" path="src/main/resources"/>

そんでは、さらに「フォルダ」を作成で。

f:id:ts0818:20201010144804p:plain

「一般」>「フォルダー」を選択し「次へ(N)>」を押下。

f:id:ts0818:20201010144850p:plain

「フォルダー名(N):」を適当に入力し、「完了(F)」を押下。

f:id:ts0818:20201010145105p:plain

フォルダが作成できました。

f:id:ts0818:20201010145250p:plain

それでは、OCR(Optical Character Recognition)を実施する対象を配置していきたいと思いますが、今回は、PDFで試してみようかと。

PDF文書は1以上のページで構成され、各ページにはテキスト画像図形が含まれる。

Portable Document Format - Wikipedia

⇧ ってあるように、「テキスト」「画像」「図形」すべて試すことができそうなので。

 

あと、「日本語」が解析できるように、ダウンロードしておいた「jpn.traineddata」も配置しておきます。(「プロジェクト・エクスプローラー」上の該当するフォルダにドラッグ&ドロップすればOK)

f:id:ts0818:20201010153727p:plain

んで、「App.java」を編集していきます。

f:id:ts0818:20201010155124p:plain

package ts0818.ocr;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;

import javax.imageio.ImageIO;

import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;

/**
 * Hello world!
 *
 */
public class App
{
    public static void main( String[] args ) throws TesseractException, IOException
    {
    	final String FILEPATH = "src/main/resources/file/";
    	final String FILENAME_TARGET_OCR = "稼働報告テスト.pdf";

    	Path path = Paths.get(FILEPATH + FILENAME_TARGET_OCR);
        // 画像を読み込む
        File file = path.toFile();
        BufferedImage img = ImageIO.read(file);

        ITesseract tesseract = new Tesseract();
        tesseract.setDatapath(Paths.get(FILEPATH).toString()); // 言語ファイル(jpn.traineddata)の場所を指定
        tesseract.setLanguage("jpn"); // 解析言語は「日本語」を指定

        // 解析
        String str = tesseract.doOCR(img);

        // 結果
        System.out.println(str);
    }
}

んで、実行してみる。

f:id:ts0818:20201010155503p:plain

エラーになったんだが...

f:id:ts0818:20201010160210p:plain

どうやら、ファイルの拡張子が画像に関連するものじゃないとエラーになるらしい...
で、以下の画像(「稼働.JPG」)を読み込んでみたところ、

f:id:ts0818:20201010161033p:plain

頑張ったのかもしれんけど、壊滅状態...

f:id:ts0818:20201010161146p:plain

 

試しに、以下のWikipediaをキャプチャした画像に変えて実施したところ、

f:id:ts0818:20201010161535p:plain

だいぶまともにはなったけど。

f:id:ts0818:20201010161653p:plain

最終的にいろいろ試したけど、

f:id:ts0818:20201010162759p:plain

テキストだけの画像じゃないと、上手いこと認識されなさそうなのかね。 

package ts0818.ocr;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;

import javax.imageio.ImageIO;

import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;

/**
 * Hello world!
 *
 */
public class App
{
    public static void main( String[] args ) throws TesseractException, IOException
    {
    	final String FILEPATH = "src/main/resources/file/";
    	final String FILENAME_TARGET_OCR = "ocr_description.JPG";

    	Path path = Paths.get(FILEPATH + FILENAME_TARGET_OCR);
        // 画像を読み込む
        File file = path.toFile();
        BufferedImage img = ImageIO.read(file);

        ITesseract tesseract = new Tesseract();
        tesseract.setDatapath(Paths.get(FILEPATH).toString()); // 言語ファイル(jpn.traineddata)の場所を指定
        tesseract.setLanguage("jpn"); // 解析言語は「日本語」を指定

        // 解析
        String str = tesseract.doOCR(img);

        // 結果
        System.out.println(str);
    }
}

 

しっかりした素材を準備してあげないと駄目みたいね...

う~ん...使い方で変わってくるのかも知らんけど、実用には厳しい感じがしてならないかな...

2020年10月12日(月)追記:↓ ここから

Google Cloud Vision API」 ってものを使えば、

techracho.bpsinc.jp

特に表形式ですと罫線が認識されてしまい、除外したりするのがとても難しかったです。逆に、難しいだろうと思っていた日本語の方が精度が高く、2文字以上になるとほとんど読み取ってくれたのには驚きました。

Rails+Google Cloud Vision APIで文字認識を実装してみた|TechRacho(テックラッチョ)〜エンジニアの「?」を「!」に〜|BPS株式会社

⇧ 「罫線を含む画像」でも問題なく読み取れると仰る人もおり、

a244.hateblo.jp

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

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

tesseract

⇧ と仰る人もおり、「Google Cloud Vision API」 を使う場合は、

  • TEXT_DETECTION
  • DOCUMENT_TEXT_DETECTION

ってのを使えば「罫線」を上手いこと回避してくれるのか分からんのだけど、参考サイトのRubyソースコードの結果を見る限り、「日本語2文字」の時だけ精度が良かったみたい...

Googleさんでも厳しいのね...

ちなみに「Google Cloud Vision API」の説明では、

cloud.google.com

Vision API では、画像からテキストを検出、抽出できます。光学式文字認識(OCR)をサポートするアノテーション機能が 2 つあります。

  • TEXT_DETECTION は、任意の画像からテキストを検出、抽出します。たとえば、写真に道路名や交通標識が写っていれば、抽出された文字列全体、個々の単語、それらの境界ボックスが JSON レスポンスに含まれます。

  • DOCUMENT_TEXT_DETECTION も画像からテキストを抽出しますが、高密度のテキストやドキュメントに応じてレスポンスが最適化され、ページ、ブロック、段落、単語、改行の情報が JSON に含まれます。

画像内のテキストを検出する  |  Cloud Vision API  |  Google Cloud

⇧ ってなことらしい。

100年以上の研究の歴史はあれど、OCR はまだまだ発展途上ということでしょうかね。

AIの技術革新が進んではおりますが、結局のところ、まだマンパワーでどうにしかせざるを得ない領域というのは無くならないのね(涙)。

凸版印刷株式会社」が令和2年3月18日に、最新のOCR技術について調査した結果のPDFを公開してくれているようです。

レイアウト解析の精度に関しては、文字認識精度による限界、書誌項目名の表記揺れの問題等があるため、自動認識処理では実用精度に達しない可能性がある点にも留意する必要がある。

https://www.jpo.go.jp/system/laws/sesaku/kikaihonyaku/document/kikai_honyaku/r01_02.pdf

また、本事業の目的である機械翻訳における使用について考察すると、高精度な機械翻訳を可能とするためには、平均的な文字認識率の向上に加えて、以下の自動翻訳特有の課題が想定される。
1)行のつながりを正しく推定すること。
OCR のレイアウト認識の際、行矩形の認識に成功したとしても、行矩形間のつながり方の推定に失敗すると、正しい機械翻訳の結果は得られない。
2)文・文節の区切りを正しく識別すること。
OCR は単純な記号の識別に失敗する傾向があるが、句読点の識別に失敗すると、
文・文節の区切りの判断ができず、正しい翻訳翻訳の結果は得られない。

https://www.jpo.go.jp/system/laws/sesaku/kikaihonyaku/document/kikai_honyaku/r01_02.pdf

⇧ ってな感じで、「罫線の含まれる画像」の認識についての問題を上手いこと乗り越えられれば、AI OCR の課題解決にもつながりそうな部分もありそうな。

う~ん、もう100年ぐらいかかるのかしら...

2020年10月12日(月)追記:↑ ここまで

今回はこのへんで。