はじめに
「画像から文字を抽出したい」という要件、意外とよくありませんか。
個人的には、領収書のスキャンデータを整理したいとか、スクリーンショットからテキストをコピーしたいとか、ちょっとした場面で「OCRがあれば...」と思うことが何度もあったんですよね。
で、調べてみたらTesseract.jsというライブラリがかなり良さそうだったので、今回はこれを紹介します。GitHubスター数は37,700以上、11年以上メンテナンスが続いている安定したプロジェクトです。
Tesseract.jsとは
Tesseract.jsは、ブラウザとNode.jsの両方で動作するJavaScript製のOCR(光学文字認識)ライブラリです。
もともとGoogleが開発していたTesseract OCRエンジンをWebAssemblyでラップしたもので、サーバーサイドに依存せずにブラウザ内だけで文字認識ができるという、なかなか画期的なやつです。
特徴・メリット
100言語以上に対応
日本語はもちろん、英語、中国語、韓国語など主要な言語は一通りカバーしています。多言語サイトを運営していたり、海外の資料を扱う機会がある人には嬉しいポイントですね。
ブラウザだけで完結する
これ、意外とすごいことで。従来のOCRって、サーバー側で処理するか、デスクトップアプリを使うかの二択だったんですよ。Tesseract.jsならWebアプリとして提供できるので、ユーザーにインストールを求める必要がない。
軽量化が進んでいる
バージョン5以降で大幅にファイルサイズが削減されました。英語で54%、中国語に至っては73%も軽くなっているとのこと。モバイル環境でも実用的なレベルになってきています。
Apache License 2.0
商用利用も問題なし。業務システムに組み込むハードルが低いのは助かります。
インストール方法
npm/yarn の場合
npm install tesseract.js
# または
yarn add tesseract.js
CDNで使う場合
手軽に試したいなら、CDNから読み込むのが一番早いです。
<script src='https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js'></script>
基本的な使い方
シンプルな例
まずは最もシンプルな使い方から。
import { createWorker } from 'tesseract.js';
(async () => {
// 英語用のワーカーを作成
const worker = await createWorker('eng');
// 画像からテキストを認識
const result = await worker.recognize('image.png');
console.log(result.data.text);
// 後片付け
await worker.terminate();
})();
正直なところ、こんなに簡単でいいのかと思うレベルです。
日本語を認識する場合
日本語の場合は、言語コードをjpnに変更するだけ。
import { createWorker } from 'tesseract.js';
(async () => {
// 日本語用のワーカーを作成
const worker = await createWorker('jpn');
const result = await worker.recognize('japanese_text.png');
console.log(result.data.text);
await worker.terminate();
})();
複数画像を処理する場合
ここ、ちょっとしたポイントがあります。複数の画像を処理するときは、ワーカーを使い回すのが効率的です。
import { createWorker } from 'tesseract.js';
(async () => {
const worker = await createWorker('jpn');
const images = ['image1.png', 'image2.png', 'image3.png'];
for (const image of images) {
const result = await worker.recognize(image);
console.log(`${image}: ${result.data.text}`);
}
// 全部終わってからterminate
await worker.terminate();
})();
画像ごとにワーカーを作り直すと、その都度言語データのロードが走って遅くなるんですよね。
並列処理でさらに高速化
大量の画像を処理するなら、スケジューラーを使った並列処理が便利です。
import { createScheduler, createWorker } from 'tesseract.js';
(async () => {
const scheduler = createScheduler();
// 4つのワーカーを並列で動かす
for (let i = 0; i < 4; i++) {
const worker = await createWorker('jpn');
scheduler.addWorker(worker);
}
const images = ['img1.png', 'img2.png', 'img3.png', 'img4.png'];
const results = await Promise.all(
images.map(img => scheduler.addJob('recognize', img))
);
results.forEach((result, i) => {
console.log(`${images[i]}: ${result.data.text}`);
});
await scheduler.terminate();
})();
実践的なユースケース
領収書・請求書の自動読み取り
経費精算システムとか、会計ソフトとの連携で使えそうですね。撮影した領収書から金額や日付を抽出して、自動入力するイメージ。
名刺管理アプリ
スマホで名刺を撮影して、連絡先情報を自動抽出。既存の名刺管理サービスと同じようなことが、自前で実装できます。
スクリーンショットからのテキスト抽出
画像化されたテキスト(PDFのスキャン画像とか)からテキストを抜き出すツール。社内システムで「この画像からテキストをコピーしたい」という要望、結構あるんですよね。
多言語ドキュメントの翻訳前処理
海外の資料をOCRで読み取って、翻訳APIに投げる。手作業で打ち直す時代は終わりました。
注意点
認識精度は画像品質に依存する
当たり前といえば当たり前ですが、ぼやけた画像や手書き文字の認識精度はそこまで高くないです。きれいに印刷された文字なら問題ないですが、癖のある手書きは厳しい。
初回ロードに時間がかかる
言語データをダウンロードするため、初回の実行には数秒かかります。UXを考えるなら、ローディング表示は必須ですね。
日本語は英語より精度が落ちる
これはTesseract全般の話ですが、ラテン文字に比べると日本語の認識精度は若干落ちます。とはいえ、実用レベルではあります。
まとめ
Tesseract.jsは、ブラウザ内で完結するOCR処理を実現できる貴重なライブラリです。
- 100言語以上対応
- ブラウザ・Node.js両対応
- インストールが簡単
- Apache License 2.0で商用利用OK
個人的には、ちょっとした社内ツールを作るときに重宝しそうだなと思っています。サーバーサイドを用意しなくていいのが、地味に嬉しいポイントですね。
興味があれば、まずはCDNから読み込んで試してみてください。思った以上に簡単に動きますよ。