OCR(文字認識)というとTesseract OCRが有名ですが、Javascriptでも使用可能なTesseract.jsをご存知でしょうか。
この記事では、ReactでTesseract.jsを使用して文字認識を行う方法について解説を行います。
Tesseract.jsのインストール
初めにReactのプロジェクトにTesseract.jsをインストールします。
npm i tesseract.js
package.jsonのdependeciesに以下が追加されていればインストールは成功です。
(バージョンはその時の最新)
"tesseract.js": "^2.1.5",
Tesseract.jsで文字認識
Tesseract.jsのインストールが完了したら画像からの文字認識を行うコードを書いていきます。
JSXの記述
初めに、input要素や出力用の要素などをJSXで記述していきます。
今回は確認用なので全てAppコンポーネントの中に記載していきます。
function App() {
return (
<div className="App">
<div className="input-area">
<input type="file" />
</div>
<div className="output-area">
<div className="image">
<img alt="" />
</div>
<div className="result">
</div>
</div>
</div>
)
}
画像ファイルを選択するための「input要素」、読み込んだ画像を表示するための「img要素」、文字認識結果を表示するための「div要素(class名[result])」を配置します。
選択画像表示処理
続いてファイルを選択して画像を表示するまでの処理を記述します。
画像のsrc属性、認識結果の文字列は後程使用するためuseStateで保持しておくようにします。
import { useState } from 'react'
function App() {
const [src, setSrc] = useState(null)
const [result, setResult] = useState('')
const onChange = e => {
const file = e.target.files[0]
const reader = new FileReader()
reader.onload = e => {
setSrc(() => e.target.result)
}
reader.readAsDataURL(file)
}
return (
<div className="App">
<div className="input-area">
<input type="file" onChange={onChange} />
</div>
<div className="output-area">
<div className="image">
<img src={src} alt="" />
</div>
<div className="result">
{result}
</div>
</div>
</div>
)
}
ファイルが選択された際のイベント(onChange)を追加し、読み込まれたファイルを「img要素」に設定するコードを追加しました。
ファイルを選択して画像が表示されればOKです。
文字認識
読み込んだ画像に対して文字認識を行います。
始めにtesseract.jsからcreateWorkerをimportしておきます。
import { createWorker } from 'tesseract.js'
コンポーネント内で使用するためにcreateWorkerからworkerを取得します。
const worker = createWorker()
ここまでで文字認識を行うための準備ができたので、読み込んだsrcを使用して文字認識を行う関数を追加します。
const recognize = async(img) => {
await worker.load()
await worker.loadLanguage('jpn')
await worker.initialize('jpn')
const {data: {text}} = await worker.recognize(img)
setResult(() => text)
await worker.terminate()
}
「loadLanguage関数」「initialize関数」の引数に文字認識を行いたい言語を指定することで、指定した言語で認識を行なってくれるようになります。
最後に「onChange」関数の中の画像読み込み後に「recognize関数」にsrc(e.target.result)を渡せば文字認識を実行してくれます。
import { useState } from 'react'
import { createWorker } from 'tesseract.js'
function App() {
const [src, setSrc] = useState(null)
const [result, setResult] = useState('')
const worker = createWorker()
const onChange = e => {
const file = e.target.files[0]
const reader = new FileReader()
reader.onload = e => {
setSrc(() => e.target.result)
recognize(e.target.result)
}
reader.readAsDataURL(file)
}
const recognize = async(img) => {
await worker.load()
await worker.loadLanguage('jpn')
await worker.initialize('jpn')
const {data: {text}} = await worker.recognize(img)
setResult(() => text)
await worker.terminate()
}
return (
<div className="App">
<div className="input-area">
<input type="file" onChange={onChange} />
</div>
<div className="output-area">
<div className="image">
<img src={src} alt="" />
</div>
<div className="result">
{result}
</div>
</div>
</div>
)
}
文字認識を試してみる
適当な日本語を記述した画像を作成したのでこちらの画像を使用して文字認識を試してみます。
上記の画像を選択して2秒ほど待つと以下のように認識された結果が表示されます。
認識結果を確認すると「日本語文字認識のテストです。」と正しく認識されていることが確認できます。
あまり一般的ではないフォントであってもパソコンで作成した画像であればそれなりに認識精度は良さそうですね。
終わりに
ReactでTesseract.jsを使用して文字認識を行う方法について解説を行いました。
日本語であってもパソコンで作られた文字であればそれなりの認識精度なので実用性はありそうな気はしますが、画像が大きくなるにつれて処理時間が大きくなってしまうため、業務として使用するには無理がありそうですね。
ちなみに手書き文字や文字に背景が入っていたりする場合には認識精度が劇的に悪かったです。
今回の記事についてわからなかった点や誤っている点などありましたらコメントまでお願いいたします。
コメント