ブラウザでTesseract.js使ってOCRしてみた

# 概要
少し前にOCRという存在を知り、実際に触ってみたいなと思ってはや2ヶ月。。。。
やっとこさっと重い腰を上げてブラウザで機能するOCRライブラリがないかなと探していたところ、、、、
OSSで`Tesseract.js`を見つけて少し使ってみたので紹介したいと思います。

## そもそもOCRってなんぞや
OCRは、Optical Character Reader/Recognitionの略で、
画像データのテキスト部分を認識して、文字データに変換する光学文字認識機能のことを意味します。

これを活用すると、データ入力という非常に効率の悪い作業をなくすことができます。
最近だと、QRコードのOCRもあるのでなかなか面白い技術になってきています。

## Tesseract.jsで簡単OCR
早速`Tesseract.js`を使ってブラウザでできるOCRを実装してみましょう。
今回はReactを使います。

```shell
$ npx create-react-app sample-ocr
$ cd sample-ocr
// Tesseract.jsをインストール
$ yarn add tesseract.js
```
これで実装の準備は整いました。
今回は必要最低限の実装しかしません。
あくまで、 `Tesseract.js`を使う為だけのものです。

```jsx:App.js
import React, { useState } from 'react';
import { createWorker } from 'tesseract.js';
import './App.css';

function App() {
  const [file, setFile] = useState();
  const [textOcr, setTextOcr] = useState('');
  const worker = createWorker({
    logger: m => console.log(m)
  })

  const tryOcr = async() => {
    await worker.load();
    await worker.loadLanguage('eng');
    await worker.initialize('eng');
    const { data: { text } } = await worker.recognize(file);
    setTextOcr(text);
    await worker.terminate();
  }

  // fileData 取得
  const handleChange = (e) => {
    console.log(e.target.files[0]);
    setFile(e.target.files[0])
  }

  const handleClick = async() => {
    if (!file) return
    setTextOcr('Recognizing...')
    await tryOcr();
  }

  return (
    <div className="App">
      <input type="file" onChange={handleChange} /><br />
      <button className="button" onClick={handleClick}>Try OCR</button>
      <div>
        {textOcr}
      </div>
    </div>
  );
}

export default App;
```
さぁ早速英語の画像を上げてみよう
![sample.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165705/6c3bec00-474d-bc2b-a79a-8d489fcd260a.jpeg)

結果↓↓
![スクリーンショット 2020-09-07 0.11.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165705/9c09175e-f72f-0992-d73a-b39f658b95a6.png)

なんとか読み取れたみたい＞＜

次は日本語で読み取ってみよう
下記の箇所を変える必要があるので注意！！

```js
await worker.loadLanguage('eng');
await worker.initialize('eng');
↓↓↓
await worker.loadLanguage('jpn');
await worker.initialize('jpn');
```

読み取る画像はこれ
![sample.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165705/0b6631ee-3e06-a373-bdeb-5a6ee5f7a61a.jpeg)

結果↓↓
![スクリーンショット 2020-09-07 0.20.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165705/34991567-eda2-c64d-39ce-4310afcd052c.png)

このくらい綺麗な画像で、短文だとしっかり読み込めるということがわかりました。

少し長文
![スクリーンショット 2020-09-07 0.20.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165705/c994694c-57ee-4e13-cc0e-a1599c89b556.png)

結果↓↓
![スクリーンショット 2020-09-07 0.45.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165705/4e56028c-a8b2-a9c3-935d-c40f0b6439ef.png)
すごい！！　解析できてる！！

手書きは??
![iOS の画像.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165705/37415bb5-f8c6-9f67-2496-49265a6ea4bf.jpeg)

結果↓↓
![スクリーンショット 2020-09-07 0.52.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165705/1019b471-9e01-d85c-7be0-85835ea5b7fb.png)
あれれ＞＜

## まとめ
ブラウザでもOCRは結構簡単に実現できました。
精度の面で言うと画像が綺麗だと解析結果は良い気はしましたが、
縦文字や、手書きの解析の精度が低いような気がしました。（英語だと精度高いのかな？？）
今回は`Tesseract.js`の最低限の機能しか使ってないので、何かしらのオプション機能などを使えばもう少し精度を上げることはできそうだ。
実際の公式githubには、リアルタイムで打った文字を解析してくれるサンプルもあ流ので興味ある方は少し触ってみるといいかと思います！

## 参照
[Tesseract.js 公式](https://github.com/naptha/tesseract.js)