【kintone x OCR】～KEYWORD検索編～　kintoneのOCRプラグインを開発する②【GCP】

# 無償で試してみる
下記に「アカウント申請」という件名（本文なし）でメールを送付頂ければ、数分程度でアカウント情報を返信します。
ocr.lastonemile@gmail.com
* 利用規約に同意の上、ご利用ください。　https://tanoshimane.stores.jp/news/603313afc19c4527490eb72e
* kintoneというクラウドアプリ上に構築しており、そのゲストIDを発行します。
* 30日間又は100ページまで（kintoneの利用料含めて）無償で利用可能です。

詳細：https://qiita.com/Lastonemile/items/65b9102c868e09b3248e

# プラグインのダウンロード
kintone用OCRプラグイン及びテンプレートが、下記よりダウンロード（無償で購入）可能です。

利用（設定）方法

* **IEではご利用いただけません**（Chrome,edgeは動作確認済、その他ブラウザは未検証です）
* 初回利用時から1か月間無償でご利用いただけます。
* ご利用にあたり、ご利用者のドメイン情報を取得します（ドメイン毎に利用期間を管理しています）。
* 利用にあたり、別途Google Cloud Vision のAPIキーを取得頂く必要がございます。（取得代行も行っています）
Cloud Visionの詳細：https://cloud.google.com/vision/docs?hl=ja
APIキー取得方法：https://syncer.jp/cloud-vision-api
**APIキーの管理には十分ご注意ください**

# 最終目標
kintone上でこの↓画像（請求書）をOCR処理し、請求番号・支払期限・振込先・請求元・明細（品名・数量・・・のテーブル部分）の値を取得することを最終目標とします。
![請求書サンプル.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543387/13655cba-1ef7-40ba-748c-135bc5af3280.jpeg)

尚、説明は後回しで「まず試したい」という方は、[プラグイン（テンプレート）のダウンロード](#プラグインテンプレートのダウンロード)からkintone用のプラグインとテンプレートを試用（1か月間）頂けます。

### 今回（KEYWORD検索編）の目標
①でCloud VisionのOCR結果をKintone上で取得するプラグインを作成しました。
今回はその結果を利用して、必要な情報（請求番号・支払期限・振込先・請求元・明細）を取得していこうと思います。

早速ですが、取得する方法はいくつか考えつきます。（私の知識の範囲ですが）下記に列挙してみたいと思います。

①AI（機械学習）を利用して取得する。
②決まった文字列（KEYWORD）を利用して取得する。
③座標（ZONE）を利用して取得する。
④正規表現を利用して取得する。

先に記載しておきますが、①については今の私の頭では無理なので、不採用とします。（私見ですが、①の方法は構築難度もさることながら、学習データの準備や補正等、余程の大会社でなければ現実的には利用段階にはないと思います）

残りの②～④については、（後述しますが）それぞれ得手不得手があります。そこで最終的には、それぞれを補完するために②～④を組み合わせることで、精度を高めていきたいと思いますが、今回のKEYWORD検索編では「②決まった文字列（KEYWORD）を利用して取得する」方法にフォーカスしてご説明したいと思います。

### KEYWORD検索の定義
例として上の請求書の請求番号を取得したいとします。
![請求番号.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543387/7063e479-7520-750f-952c-37e081a4aa89.png)
当然、取得したい請求番号の値（今回であれば123456789）については、請求書が変わるたびに変化します。しかし、必ず「請求番号」という項目名（KEYWORD）の右側に値が記載されています。

このようにKEYWORDを手掛かりに取得する方法をKEYWORD検索と定義します。

ちなみに、次の記事で「座標（ZONE）を利用」する方法も紹介しますが、この「座標（ZONE）を利用」方法に対するKEYWORD検索のメリットはKEYWORDの位置が変わっても、文書上にKEYWORDが存在していれば、値を取得できるところにあります。

尚、今回も①に引き続きkintone上でCloud Visionを利用している想定で、Cloud Visionのresponseから値を取得する前提で話を進めていきます。
kintone上でのCloud Visionの利用(前回記事）：https://qiita.com/Lastonemile/items/55e6a159a4c2bcc9dab4


### 具体的な取得方法、その前に
Cloud Visionのresponseには、文字（description）だけでなく、座標含め様々な情報が記載されています。

```
//response 例（引用）
{
      "responses": [
        {
          "textAnnotations": [
            {
              "locale": "en",
              "description": "WAITING?",
              "boundingPoly": {
                "vertices": [
                  {
                    "x": 352,
                    "y": 828
                  },
                  {
                    "x": 2248,
                    "y": 911
                  },
                  {
                    "x": 2238,
                    "y": 1148
                  },
                  {
                    "x": 342,
                    "y": 1065
                  }
                ]
              }
            }
        ]
      }
   ]
}
            
```
そのため、今回は不要な部分を削除し、こんな感じ↓のわかりやすいjsonに書き換えます。以後はこのjson形式になっているresponseを扱う前提で話を進めていきたいと思います。

```
{"String":"description","x1":0,"x2":1,"x3":1,"x4":0,"y1":0,"y2":0,"y3":1,"y4":1}
```
＊座標は最小0,最大1で定義しました。（x1y1：左上・x2y2：右上・x3y3：右下・x4y4：左下になります）

### 具体的な取得方法
座標を利用することで、"「請求番号」というKEYWORDの右側"を指定できます。手順は下記のようになります。

①KEYWORD（今回は「請求番号」という文字列）の座標を取得する。
②その座標の右側にある文字列（複数）を取得する。
③②で取得した文字列（複数）のなかから、最も位置が近い文字列を取得する。

①については、単純にKEYWORDと一致する又はKEYWORDに最も近い文字列を検索し、その座標を取得します。

②を行うためには、まず"右側"を定義する必要があります。今回はKEYWORDのx2よりx1が大きく（右にあり）、KEYWORDのy2よりもy4が大きく（下にあり）、KEYWORDのy3よりもy1が小さい（上にある）文字列を"右側"と定義しました。＊言葉にすると分かりにくいですね。

```
for(let i = 0; i < list.length; i++){
   if(keyword.x2 < list[i].x1 && keyword.y2 < list[i].y4 &&  keyword.y3 > list[i].y1){
      result_list.push(list[i]);
   }
}
```
![右側図解.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543387/c755b6bd-7ed1-82a2-4e85-0ecd67832051.png)

例えば、今回の文書が（仮に）右肩上がりに傾いていた場合、「請求日」の「2020/1/1」も①の範囲内（「請求番号」の右側）に入る可能性があります。そのような場合の対応が③になります。
ちなみに、「最も近い」というのは、文書の左上を始点としてそこからの距離が最も近いものを「最も近い」と定義しました。

ここまで、"右側"の取得方法について説明しましたが、当然取得したい値の全てがKEYWORDの右側にあるわけではありません。方向で考えると右以外に下も考えられます（今回だと、「振込先」なんかは下になります）ので、"右側"と同様の考え方で下も定義しました。

```
for(let i = 0; i < list.length; i++){
   if( keyword.y3 < list[i].y1){
      result_list.push(list[i]);
   }
}
```
また、右と下の方向は定義しましたが、その中でも、取得したい値が1つの文字列か複数かでも取得方法が変わってきます。具体的には「請求番号」は1つの文字列ですが、「振込先」の値は複数の文字列（複数行）になっています。

そこで、複数の文字列を取得する場合には、「③②で取得した文字列（複数）のなかから、最も位置が近い文字列を取得」ではなく、「③②で取得した文字列（複数）の中から、指定する範囲まで取得」することとします。尚、この「指定する範囲」についても、KEYWORD（LIMIT KEYWORDと呼びます）を利用して指定します。

```
for(var i = 0; i < list.length; i++){
   if( keyword.y3 < list[i].y1 && limit_keyword.y1 > list[i].y3){
      result_list.push(list[i]);
   }
}
```
### KEYWORD検索での取得方法まとめ
書きながら、私もこんがらがってきたので、少しまとめます。

・KEYWORD検索での取得方法には、右、右複数、下1行、下複数の4パターンがあり、それぞれKEYWORDの座標をもとに指定する。
・対象が1つの文字列（右、下1行）の場合は、KEYWORDに最も近い文字列を取得する。
・対象が複数の文字列（右複数、下複数）の場合は、LIMIT KEYWORDを定め、その座標までの範囲の文字列を取得する。

# kintoneアカウントを持っていない方
ここまでの説明及び、以降の記事内容も網羅したOCRシステムが、メールアドレス登録のみでご利用いただけます。
OCRシステム　ユーザー登録: https://qiita.com/Lastonemile/items/65b9102c868e09b3248e


# kintoneアカウントを持っている方
### プラグイン（テンプレート）のダウンロード
ここまでの説明及び、以降の記事内容も網羅したkintone用OCRプラグイン及びテンプレートが、下記よりダウンロード（無償で購入）可能です。

利用方法：https://qiita.com/Lastonemile/items/c40cdd8543f14496c0c4

＊**IEではご利用いただけません**（Chrome,edgeは動作確認済、その他ブラウザは未検証です）
＊初回利用時から1か月間無償でご利用いただけます。
＊ご利用にあたり、ご利用者のドメイン情報を取得します（ドメイン毎に利用期間を管理しています）。
＊利用にあたり、別途Google Cloud Vision のAPIキーを取得頂く必要がございます。（取得代行も行っています）
Cloud Visionの詳細：https://cloud.google.com/vision/docs?hl=ja
＊利用時にCloud Visionの利用料金が発生する可能性があります。（2020/12/24現在 月間1000ユニットまで無料で利用可能です。）
Cloud Vision API料金：https://cloud.google.com/vision/pricing?hl=ja
APIキー取得方法：https://tanoshimane.stores.jp/news/602220196728be15433783e4
**APIキーの管理には十分ご注意ください**（自己責任でお願いします）


## 今後の課題
KEYWORD検索の方法は分かったけど、KEYWORD検索だけじゃ全ての値を取得できないよね？
と、感想をお持ちの方が多いのではないかと思います。

今回の最終目標でいえば、KEYWORD検索で「請求番号」「支払期限」「振込先」の値は取得出来そうですが、それ以外はKEYWORD検索だけでは難しそうです。

KEYWORD検索にはいくつかデメリットがあります。その中でも一番大きなものは、単純に「KEYWORDがない場合は、どうすればいいの？」であり、今回の例で考えると「請求元」がそれにあたります。

そこで、次回はKEYWORDがない場合に、どのように値を取得するか？を記載したいと思います。

## ここまでで出来たこと
![KEYWORD検索.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543387/336290a6-7821-aaaf-3e87-5a2b3ed0fa85.png)
＊KEYWORD検索で取得出来る値（請求番号・支払期限・振込先）が取得できるようになりました。

## 筆者の紹介
群馬県の渋川市・高崎市を中心に群馬県内でkintoneを利用したDX化支援を行っています。ご興味ある方はぜひご連絡ください。
https://ks-kiki.hp.peraichi.com/

## 関連記事
[kintone OCRプラグイン　Vision API arr.by LOM 利用方法](https://qiita.com/Lastonemile/items/a4b3888600cfa2bd37d2)
[kintone OCRプラグイン　文書テンプレート作成方法](https://qiita.com/Lastonemile/items/c40cdd8543f14496c0c4)
[kintoneのOCRプラグインを開発する①](https://qiita.com/Lastonemile/items/55e6a159a4c2bcc9dab4)