Photoruction工事中!

Photoructionの開発ブログです!

光学文字認識(OCR)をフロントエンドで実装してみました

こんにちは。webチームのジョンです。

今回実装するのはクライアントサイドで走るOCRになります。

始める前にご注意を!

そのため、ライブラリーのパフォーマンスはクライアントのパソコンのスペック次第になります。 クライアント側のスペックがそこそこ必要なため、商用利用は非推奨です。

自分のサイトにまともなOCR機能を実装したい場合はバックエンドで走らせるか(今回使うライブラリーもバックエンドで走らせます)、他のサービス(Amazon TextractやGoogle Vision Apiなど)を使用するかをご検討してください。

光学文字認識 (OCR) とは

光学文字認識 (OCR) は簡単に説明しますとテキストの画像を機械で読み取り可能なテキスト形式に変換するプロセスです。

光学文字認識OCRは決して新しい技術ではありません。現代のスマホにも既にある機能です。iOS15からライブテキストという機能があり、iPhoneで取った写真のテキストを自動的に読み込まれます。スマホのアプリストアからも「ドキュメントスキャナー」などを検索すれば、いろんなOCRアプリが出てきます。

技術スタック

OCRブラウザーのクライアントサイドに走らせるため、Javascriptの知識は必須になります。

パッケージマネージャを使う場合はNodeJsの知識、少しでも必要になります。

さて、今回使うライブラリーはTesseract.jsというライブラリーになります。このライブラリーはTesseract OCRからJavascriptにポートされたライブラリーとなります。Tesseractは元々ヒューレット・パッカード(HP)が開発して2005年にオープンソースされたOCRエンジンです。2006年から2018年まではGoogleがメンテしていました。

インストール方法

インストール方法は2つあります。おすすめはパッケージマネージャを使ってインストールする方法です。でももしパッケージマネジャを使えないもしくはそもそも使っていない既存案件にインストールしたい場合はCDN URLからライブラリーを使えます。

CDN

<script src='https://cdnjs.cloudflare.com/ajax/libs/tesseract.js/3.0.3/tesseract.min.js'></script>

スクリプトタグを埋め込んだ後にTesseractというグローバル変数がアクセスできるようになります。

Tesseract.jsのGithubページでインストール方法のところにバージョン1とバージョン2のインストール方法しか書かれていないため、別のCDNを使いました。他のバージョンを使いたい場合はこちらから参照してください。

パッケージマネジャ

# For v3
npm install tesseract.js
yarn add tesseract.js

# For v2
npm install tesseract.js@2
yarn add tesseract.js@2

パッケージマネジャからインストールする場合はバージョン3がNodeJsバージョン14以上は必要になります。

使用方法

Tesseract.jsのGithubページではTesseract基本の使い方は2つ記載されています。Tesseract.recognize()ファンクションの使い方とウェブワーカーの使い方です。

import Tesseract from 'tesseract.js';

Tesseract.recognize(
    'https://tesseract.projectnaptha.com/img/eng_bw.png',
  'eng',
  { logger: m => console.log(m) }
).then(({ data: { text } }) => {
  console.log(text);
})
import { createWorker } from 'tesseract.js';

const worker = createWorker({
  logger: m => console.log(m)
});

(async () => {
  await worker.load();
  await worker.loadLanguage('eng');
  await worker.initialize('eng');
  const { data: { text } } = await worker.recognize('https://tesseract.projectnaptha.com/img/eng_bw.png');
  console.log(text);
  await worker.terminate();
})();

Tesseract.recognize()ファンクションの裏ではワーカーと同じ使い方になっているためどっちを使っても変わりがありません。

Tesseract.js

const createWorker = require('./createWorker');

const recognize = async (image, langs, options) => {
  const worker = createWorker(options);
  await worker.load();
  await worker.loadLanguage(langs);
  await worker.initialize(langs);
  return worker.recognize(image)
    .finally(async () => {
      await worker.terminate();
    });
};

file型のインプットから読み込みの例

<!DOCTYPE html>
<html lang="en">
<body>
    <input type="file" name="my_file" id="my-file">
    <script src="js/from_input.js"></script>
</body>
</html>
import Tesseract from 'tesseract.js';

const readImage = (imageUrl) => {
    Tesseract.recognize(imageUrl, 'jpn', { logger: m => console.log(m) }).then(({ data: { text } }) => {
        console.log(text);
    });
};

(() => {
    const fileInput = document.getElementById('my-file');

    fileInput.addEventListener('change', (e) => {
        const file = e.target.files[0];

        // fileインプットから選択した画像のデータURL発行
        let fileReader = new FileReader();
        fileReader.readAsDataURL(file);
        fileReader.onload = function () {
            readImage(fileReader.result); // 画像のデータURL
        }
    })
})();

日本語縦書きについて

パッケージマネジャを使っている場合は、デフォルトでサポートしている言語を簡単に確認することができます。下記のファイルにご参照して下さい。

node_modules/tesseract.js/src/constants/languages.js

TesseractOCRでは日本語縦書き用のjpn_vertという言語オプションはあります。でも上記のlanguages.jsファイルを確認しますとjpn_vertはありませんがjpn_vertをそのまま使えそうです。

Tesseract.recognize(
    'https://画像/URL/です.png',
  'jpn_vert',
  { logger: m => console.log(m) }
).then(({ data: { text } }) => {
  console.log(text);
})

IndexedDBを確認しますと、ちゃんと.traineddataがダウンロードされているようです。

自分でOCRを学習させたい場合

この記事のスコープ外になりますが、Tesseract.jsにも自分で学習させた.traineddataファイルを使えそうです。こちらにご参照ください。

実際に使ってみましょう!

上記file型のインプットから読み込みの例に書いている通りをCodepenに反映しました。

サンプル画像として簡単にGoogle文章画像をイメージ検索して下記のを取りました。自分が使えたい画像で試してもいいです。

test_image.png

Codepenを開いてConsoleを開いてください

上記のテスト画像を読み込みますと、下記のような結果を得られます。

アウトプットを見ますとほとんど合っていますが、間違っているところは3か所あります。

最後に

TesseractJsはそのまま使用することはできますが、場合によって予想している結果を得られない時もあります。もし、機械学習の経験があるなら、実際に使うデータによってTesseractを学習させた方が一番いいとは思います。

株式会社フォトラクションでは一緒に働く仲間を募集しています