Node.jsでLINE BRAIN OCR APIを使う #linebrain #ood2019


先日のLINE DEVDAYでbeta公開されていたLINE BRAIN COR APIをNode.jsで利用してみます。

> [Node.jsから画像をmultipart/form-dataでPOSTするメモ (axios利用)](https://qiita.com/n0bisuke/items/1d1cfc330997f93e2ee8)

## LINE BRAIN & LINE BRAIN COR API

LINE BRAINとは`企業がチャットボット・OCR・音声認識・音声合成・画像認識などの AI技術をより簡単に利用できる、各種サービスの総称`らしいです。 AIがどんどん民主化されて嬉しい限りです。

> 公式サイトから引用 https://www.linebrain.ai/

LINE BRAIN OCR APIはLINE BRAINのサービス群の一つというイメージですね。

https://ocrdemo.linebrain.ai/

> <img src="https://i.gyazo.com/db783fb19b8233a662ff0c70a930ca63.jpg" width="500px">

## 汚い字でも読み込んでくれた

実際にDEMOページで試してみたら、手書きの結構汚い字でもちゃんと読み込んでくれました。
GCPなどでもOCRはあると思いますが、その辺の精度の違いは僕は比較してないのでよく分かりません。

> <img src="https://i.gyazo.com/fae7673ee9f9ab800b109e16f3a3afe9.jpg" width="600px">
> instagram https://www.instagram.com/p/B57Yq7ijJg2/

## OCR APIはまだベータ版

2019/12/12時点ではまだベータ版で、ベータ版のエンドポイントは

```
https://ocr-devday19.linebrain.ai/v1/
```

となっています。URLから分かる通りLINE DEVDAY 2019に参加した人だけに公開されたっぽい雰囲気です。利用料金なども現時点では分かりません。(既にどこかで公開されてるかもしれないですが)

ドキュメント画面はこんな雰囲気です。ドキュメントのURLは非公開かもしれないので載せないでおきます。

> <img src="https://i.gyazo.com/1d4fc88b6fa8f73301ee6a096e0cc953.png" width="400px">

## DetectionとRecognition

大きく分けるとこの二つの機能になっているみたいで、

* Detection - 文字領域の検出のみを行います。
* Recognition - 文字認識のみを行います。もしくは、文字領域の検出と認識を順に行います。

## CURLで試す (ローカルファイル)

Recognitionの方を試してみました。
以下のようなコマンドで結果が返ってきます。

ここで書いてるサービスIDの`PMqTDgBsucfsyvi7pJEsbIxMIUeNQWDg`はドキュメントに書いてあるサンプル例なので、このまま書いても使えません。LINE DEV DAY 2019で登録した人はメールでサービスIDが届いてると思います。

```
curl -X POST https://ocr-devday19.linebrain.ai/v1/recognition \
                    -H 'X-ClovaOCR-Service-ID: PMqTDgBsucfsyvi7pJEsbIxMIUeNQWDg' \
                    -H "Content-Type: multipart/form-data" \
                    -F "image=@./image.png" \
                    -F "entrance=detection" \
                    -F "language=jp" \
                    -F "segments=false" \
```

## CURLから試すが画像URL指定がうまくいかなかった

ドキュメントにあるサンプルリクエストを見るとこんな感じで画像URL指定でも使えそうでした。

```bash
curl -X POST https://ocr-devday19.linebrain.ai/v1/recognition \
     -H 'X-ClovaOCR-Service-ID: PMqTDgBsucfsyvi7pJEsbIxMIUeNQWDg' \
     -H "Content-Type: application/json" \
     -d '{
           "imageURL":["https://xxxx/images/ocr_sample.jpg"],
           "entrance":"detection",
           "scaling":false,
           "segments":false
         }'
```

ただ、Gyazoに載せた画像URLを指定した場合に

```
errorConnection reset by peer
```

などのエラーが出たり、エラーが出た時のメッセージからどこに問題があるのかの判断がつきにくいとこが現時点ではありました。

取り急ぎの原因は不明で、時間があれば再調査しますが、とりあえずローカルファイルを投げつけてみます。

## Node.jsから扱ってみる

ということで実際のアプリケーションに組み込みやすいようにNode.jsから扱ってみます。

### 環境や準備など

こちらで書いた内容がそのまま使えます。

> [Node.jsから画像をmultipart/form-dataでPOSTするメモ (axios利用)](https://qiita.com/n0bisuke/items/1d1cfc330997f93e2ee8)

axiosの準備をしましょう。

## コード

```post.js
'use strict';

const fs = require('fs');
const axios = require('axios');
const FormData = require('form-data');

const OCR_SERVICE_URL = `https://ocr-devday19.linebrain.ai/v1/recognition`;
const OCR_SERVICE_ID = `PMqTDgBsucfsyvi7pJEsbIxMIUeNQWDg`; //サービスID
const IMAGE_PATH = `./public/image.png`; // 画像パス
const file = fs.createReadStream(IMAGE_PATH);

const form = new FormData();
form.append('image', file);
form.append('entrance', 'detection');

const config = {
    headers: {
        'X-ClovaOCR-Service-ID': OCR_SERVICE_ID,
        ...form.getHeaders(),
    }
}

axios.post(OCR_SERVICE_URL, form, config)
    .then(res => console.log(res.data)) //成功時
    .catch(err => console.log(err)); //失敗時
```

ちなみに、entranceをdetectionにしないとうまいこと文字が抽出されませんでした。

## 実行結果

```
$ node post.js
{
  words: [
    {
      boundingBox: [Array],
      text: '斎場御獄',
      confidence: 0.6916899085044861,
      lineBreak: false,
      segments: [Array]
    }
  ]
}
```

元画像はこちらですね。`斎場御獄`という文字が抽出されました。

> <img src="https://i.gyazo.com/fae7673ee9f9ab800b109e16f3a3afe9.jpg" width="600px">
> instagram https://www.instagram.com/p/B57Yq7ijJg2/

## 所感

使い勝手は割と直感的なAPIで分かりやすい気がしました。

他社のOCR系のAPIと比較してどうなのか、どこかの誰かが検証してくれると幸いです。

画像URLからOCR APIに投げつけたかった問題はまたどこかで...