LINE Clova OCR APIを叩いてみる

# はじめに

[前回](https://qiita.com/bathtimefish/items/8f82630370941b7c765a)はテンプレートビルダのGUIで作成したテンプレートのテストまでをやってみました
今回はリリースしたテンプレートをAPI公開してAPIリクエストで認識を試してみようと思います

# テンプレートをリリースする

前回はテンプレートをテスト用にベータリリースしましたが、APIで利用するにはサービスリリースが必要です。サイドメニューの`リリース`をクリックしてリリースしたいテンプレートIDの動作欄にある`サービスリリース`ボタンをクリックします。リリースされると現在のリリース状態欄に`Service (ビルド ID: xxxxxx)`と表示されます

![スクリーンショット 2021-08-29 20.54.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/3323b9cb-1191-4c4c-2ff6-ee0b1e55295f.png)

# API Gatewayを申請する

APIはNEVER Cloud PlatformのAPI Gatewayサービスと連携しているのでまずAPI Gatewayの利用申請が必要です。NEVER Cloud Platformのサイドメニューから`Products & Service`をクリックして一覧から`API Gateway`をクリックします

![スクリーンショット 2021-08-29 21.00.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/ecfddc2d-5c9f-c8e2-e481-8fdf4a810c1b.png)

`商品利用の申請`をクリックします

![スクリーンショット 2021-08-29 21.03.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/c168c927-c0bb-c1e4-48e8-5a78774cb7ae.png)

`API Gatewayサービスの利用規約を読み、同意します。`にチェックを入れ`商品利用の申請`をクリックします

![スクリーンショット 2021-08-29 21.04.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/d960b66d-1a47-c8e8-b919-82dd08e4fe73.png)

申込みが完了します

![スクリーンショット 2021-08-29 21.06.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/f3262788-4d4d-6724-193e-ceba77b123c1.png)

# APIを設定する

Clova OCRのテンプレートビルダページにもどって`API設定`タブをクリックし`Custom`欄の`設定`をクリックします

![スクリーンショット 2021-08-29 21.07.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/965bddff-865a-fb99-dd34-30152f464a9e.png)

Secret Key欄の`作成`をクリックしてSecret Keyを生成しコピーしておきます。APIGW自動連携欄の`自動連携`をクリックします

![スクリーンショット 2021-08-29 21.11.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/74d5b6bc-efad-90a1-e95a-da46860c295a.png)

`確認`をクリックします

![スクリーンショット 2021-08-29 21.14.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/a5082027-21f8-7899-5e2f-9f57bd5a6efb.png)

自動連携が完了するとAPIGW Invoke URLが生成されるのでコピーします。このURLとSecret Keyを使用してAPIリクエストを行います

![スクリーンショット 2021-08-29 21.15.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/ddbac38f-4a49-70c2-dce6-fbcc894f4485.png)

# リクエストする

いよいよ画像をPOSTして認識結果を取得します。[ドキュメント](https://api.ncloud-docs.com/docs/en/ai-application-service-ocr-ocr)によるとPOSTリクエストできるContent-Typeは`multipart/form-data`と`application/json`がサポートされていて`application/json`のほうはBase64エンコードした画像が指定できるようです。ケースに応じて画像データの形式が選べるのは便利ですね。

今回は前回利用したテスト用画像をBase64エンコードしたものを使用してみます。Base64エンコードした画像の場合はContent-Type`application/json`でリクエストボディの`images[].format`に`jpeg`などの画像フォーマット、`images[].data`にエンコード文字列を指定します。以下のようなリクエストボディになります

```requestbody.json
{
    "version": "V2",
    "requestId": "test1",
    "timestamp": 0,
    "lang": "ja",
    "images": [
        {
            "format": "jpeg",
            "name": "test-voucher",
            "data": "/9j/4AAQSkZJRgABAQAASABIAAD/4QP0RXhpZgAATU0AKg..."
        }
    ]
}
```

`version`は`V1`と`V2`が選べますが、`V2`は検出位置座標の`boundingPoly`を返すので`V2`を指定しておきます。`requestId`は任意の文字列を指定、`timestamp`は0でいいようです。`lang`は`ja`、`images[].name`は任意の文字列を指定できます。`images[]`は配列で複数の画像を1度にリクエストできるようになっているので`images[].name`にリクエスト画像それぞれが一意に識別できる文字列を指定しておくとレスポンスデータ取得時に混乱するのを防げます。

その他`images[].templateIds`でテンプレートIDも任意設定できるようですが通常は省略して自動認識に任せて問題ないようです

リクエストヘッダには`Content-Type`:`application/json`と`X-OCR-SECRET`:`[Secret Key]`を設定します。今回は[Postman](https://www.postman.com/)でPOSTリクエストしてみました

![スクリーンショット 2021-08-29 21.34.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/8f5c7f34-0cb2-a11d-806f-c7ec63176d2c.png)

レスポンスデータは以下のようになりました

```response.json
{
    "version": "V2",
    "requestId": "test1",
    "timestamp": 1630240409895,
    "images": [
        {
            "uid": "931a01c691e847faae5cb7a4b0ccffa4",
            "name": "test-voucher",
            "inferResult": "SUCCESS",
            "message": "SUCCESS",
            "matchedTemplate": {
                "id": 10184,
                "name": "sample"
            },
            "validationResult": {
                "result": "NO_REQUESTED"
            },
            "title": {
                "name": "出金伝票",
                "boundingPoly": {
                    "vertices": [
                        {
                            "x": 553.0,
                            "y": 330.0
                        },
                        {
                            "x": 788.0,
                            "y": 330.0
                        },
                        {
                            "x": 788.0,
                            "y": 387.0
                        },
                        {
                            "x": 553.0,
                            "y": 387.0
                        }
                    ]
                },
                "inferText": "出金伝票",
                "inferConfidence": 0.9998,
                "subFields": [
                    {
                        "boundingPoly": {
                            "vertices": [
                                {
                                    "x": 553.0,
                                    "y": 330.0
                                },
                                {
                                    "x": 788.0,
                                    "y": 330.0
                                },
                                {
                                    "x": 788.0,
                                    "y": 387.0
                                },
                                {
                                    "x": 553.0,
                                    "y": 387.0
                                }
                            ]
                        },
                        "inferText": "出金伝票",
                        "inferConfidence": 0.9998,
                        "lineBreak": true
                    }
                ]
            },
            "fields": [
                {
                    "name": "コード",
                    "valueType": "ALL",
                    "boundingPoly": {
                        "vertices": [
                            {
                                "x": 622.0,
                                "y": 636.0
                            },
                            {
                                "x": 988.0,
                                "y": 636.0
                            },
                            {
                                "x": 988.0,
                                "y": 707.0
                            },
                            {
                                "x": 622.0,
                                "y": 707.0
                            }
                        ]
                    },
                    "inferText": "100 100123",
                    "inferConfidence": 0.9997,
                    "type": "NORMAL",
                    "subFields": [
                        {
                            "boundingPoly": {
                                "vertices": [
                                    {
                                        "x": 622.0,
                                        "y": 636.0
                                    },
                                    {
                                        "x": 731.0,
                                        "y": 636.0
                                    },
                                    {
                                        "x": 731.0,
                                        "y": 695.0
                                    },
                                    {
                                        "x": 622.0,
                                        "y": 695.0
                                    }
                                ]
                            },
                            "inferText": "100",
                            "inferConfidence": 1.0,
                            "lineBreak": false
                        },
                        {
                            "boundingPoly": {
                                "vertices": [
                                    {
                                        "x": 737.0,
                                        "y": 636.0
                                    },
                                    {
                                        "x": 988.0,
                                        "y": 636.0
                                    },
                                    {
                                        "x": 988.0,
                                        "y": 707.0
                                    },
                                    {
                                        "x": 737.0,
                                        "y": 707.0
                                    }
                                ]
                            },
                            "inferText": "100123",
                            "inferConfidence": 0.9994,
                            "lineBreak": false
                        }
                    ]
                },
                {
                    "name": "No",
                    "valueType": "ALL",
                    "boundingPoly": {
                        "vertices": [
                            {
                                "x": 1126.0,
                                "y": 399.0
                            },
                            {
                                "x": 1399.0,
                                "y": 399.0
                            },
                            {
                                "x": 1399.0,
                                "y": 470.0
                            },
                            {
                                "x": 1126.0,
                                "y": 470.0
                            }
                        ]
                    },
                    "inferText": "1234567",
                    "inferConfidence": 1.0,
                    "type": "NORMAL",
                    "subFields": [
                        {
                            "boundingPoly": {
                                "vertices": [
                                    {
                                        "x": 1126.0,
                                        "y": 399.0
                                    },
                                    {
                                        "x": 1399.0,
                                        "y": 399.0
                                    },
                                    {
                                        "x": 1399.0,
                                        "y": 470.0
                                    },
                                    {
                                        "x": 1126.0,
                                        "y": 470.0
                                    }
                                ]
                            },
                            "inferText": "1234567",
                            "inferConfidence": 1.0,
                            "lineBreak": true
                        }
                    ]
                },
                {
                    "name": "年",
                    "valueType": "ALL",
                    "boundingPoly": {
                        "vertices": [
                            {
                                "x": 620.0,
                                "y": 463.0
                            },
                            {
                                "x": 839.0,
                                "y": 467.0
                            },
                            {
                                "x": 838.0,
                                "y": 538.0
                            },
                            {
                                "x": 619.0,
                                "y": 534.0
                            }
                        ]
                    },
                    "inferText": "令和3年",
                    "inferConfidence": 0.9935,
                    "type": "NORMAL",
                    "subFields": [
                        {
                            "boundingPoly": {
                                "vertices": [
                                    {
                                        "x": 620.0,
                                        "y": 463.0
                                    },
                                    {
                                        "x": 839.0,
                                        "y": 467.0
                                    },
                                    {
                                        "x": 838.0,
                                        "y": 538.0
                                    },
                                    {
                                        "x": 619.0,
                                        "y": 534.0
                                    }
                                ]
                            },
                            "inferText": "令和3年",
                            "inferConfidence": 0.9935,
                            "lineBreak": false
                        }
                    ]
                },
                {
                    "name": "月",
                    "valueType": "ALL",
                    "boundingPoly": {
                        "vertices": [
                            {
                                "x": 938.0,
                                "y": 472.0
                            },
                            {
                                "x": 990.0,
                                "y": 472.0
                            },
                            {
                                "x": 990.0,
                                "y": 539.0
                            },
                            {
                                "x": 938.0,
                                "y": 539.0
                            }
                        ]
                    },
                    "inferText": "8",
                    "inferConfidence": 1.0,
                    "type": "NORMAL",
                    "subFields": [
                        {
                            "boundingPoly": {
                                "vertices": [
                                    {
                                        "x": 938.0,
                                        "y": 472.0
                                    },
                                    {
                                        "x": 990.0,
                                        "y": 472.0
                                    },
                                    {
                                        "x": 990.0,
                                        "y": 539.0
                                    },
                                    {
                                        "x": 938.0,
                                        "y": 539.0
                                    }
                                ]
                            },
                            "inferText": "8",
                            "inferConfidence": 1.0,
                            "lineBreak": false
                        }
                    ]
                },
                {
                    "name": "日",
                    "valueType": "ALL",
                    "boundingPoly": {
                        "vertices": [
                            {
                                "x": 1201.0,
                                "y": 480.0
                            },
                            {
                                "x": 1286.0,
                                "y": 480.0
                            },
                            {
                                "x": 1286.0,
                                "y": 551.0
                            },
                            {
                                "x": 1201.0,
                                "y": 551.0
                            }
                        ]
                    },
                    "inferText": "14",
                    "inferConfidence": 1.0,
                    "type": "NORMAL",
                    "subFields": [
                        {
                            "boundingPoly": {
                                "vertices": [
                                    {
                                        "x": 1201.0,
                                        "y": 480.0
                                    },
                                    {
                                        "x": 1286.0,
                                        "y": 480.0
                                    },
                                    {
                                        "x": 1286.0,
                                        "y": 551.0
                                    },
                                    {
                                        "x": 1201.0,
                                        "y": 551.0
                                    }
                                ]
                            },
                            "inferText": "14",
                            "inferConfidence": 1.0,
                            "lineBreak": false
                        }
                    ]
                },
                {
                    "name": "支払先",
                    "valueType": "ALL",
                    "boundingPoly": {
                        "vertices": [
                            {
                                "x": 1217.0,
                                "y": 629.0
                            },
                            {
                                "x": 1852.0,
                                "y": 637.0
                            },
                            {
                                "x": 1851.0,
                                "y": 734.0
                            },
                            {
                                "x": 1216.0,
                                "y": 725.0
                            }
                        ]
                    },
                    "inferText": "バスタイムフィッシュ",
                    "inferConfidence": 0.9918,
                    "type": "NORMAL",
                    "subFields": [
                        {
                            "boundingPoly": {
                                "vertices": [
                                    {
                                        "x": 1217.0,
                                        "y": 629.0
                                    },
                                    {
                                        "x": 1852.0,
                                        "y": 637.0
                                    },
                                    {
                                        "x": 1851.0,
                                        "y": 734.0
                                    },
                                    {
                                        "x": 1216.0,
                                        "y": 725.0
                                    }
                                ]
                            },
                            "inferText": "バスタイムフィッシュ",
                            "inferConfidence": 0.9918,
                            "lineBreak": true
                        }
                    ]
                },
                {
                    "name": "勘定科目1",
                    "valueType": "ALL",
                    "boundingPoly": {
                        "vertices": [
                            {
                                "x": 559.0,
                                "y": 865.0
                            },
                            {
                                "x": 747.0,
                                "y": 865.0
                            },
                            {
                                "x": 747.0,
                                "y": 948.0
                            },
                            {
                                "x": 559.0,
                                "y": 948.0
                            }
                        ]
                    },
                    "inferText": "備品",
                    "inferConfidence": 0.9972,
                    "type": "NORMAL",
                    "subFields": [
                        {
                            "boundingPoly": {
                                "vertices": [
                                    {
                                        "x": 559.0,
                                        "y": 865.0
                                    },
                                    {
                                        "x": 747.0,
                                        "y": 865.0
                                    },
                                    {
                                        "x": 747.0,
                                        "y": 948.0
                                    },
                                    {
                                        "x": 559.0,
                                        "y": 948.0
                                    }
                                ]
                            },
                            "inferText": "備品",
                            "inferConfidence": 0.9972,
                            "lineBreak": false
                        }
                    ]
                },
                {
                    "name": "摘要1",
                    "valueType": "ALL",
                    "boundingPoly": {
                        "vertices": [
                            {
                                "x": 952.0,
                                "y": 877.0
                            },
                            {
                                "x": 1258.0,
                                "y": 877.0
                            },
                            {
                                "x": 1258.0,
                                "y": 950.0
                            },
                            {
                                "x": 952.0,
                                "y": 950.0
                            }
                        ]
                    },
                    "inferText": "パソコン",
                    "inferConfidence": 0.9998,
                    "type": "NORMAL",
                    "subFields": [
                        {
                            "boundingPoly": {
                                "vertices": [
                                    {
                                        "x": 952.0,
                                        "y": 877.0
                                    },
                                    {
                                        "x": 1258.0,
                                        "y": 877.0
                                    },
                                    {
                                        "x": 1258.0,
                                        "y": 950.0
                                    },
                                    {
                                        "x": 952.0,
                                        "y": 950.0
                                    }
                                ]
                            },
                            "inferText": "パソコン",
                            "inferConfidence": 0.9998,
                            "lineBreak": false
                        }
                    ]
                },
                {
                    "name": "金額1",
                    "valueType": "ALL",
                    "boundingPoly": {
                        "vertices": [
                            {
                                "x": 1470.0,
                                "y": 883.0
                            },
                            {
                                "x": 1901.0,
                                "y": 883.0
                            },
                            {
                                "x": 1901.0,
                                "y": 956.0
                            },
                            {
                                "x": 1470.0,
                                "y": 956.0
                            }
                        ]
                    },
                    "inferText": "2 8 0 0 0 0",
                    "inferConfidence": 0.9787,
                    "type": "NORMAL",
                    "subFields": [
                        {
                            "boundingPoly": {
                                "vertices": [
                                    {
                                        "x": 1470.0,
                                        "y": 883.0
                                    },
                                    {
                                        "x": 1531.0,
                                        "y": 883.0
                                    },
                                    {
                                        "x": 1531.0,
                                        "y": 952.0
                                    },
                                    {
                                        "x": 1470.0,
                                        "y": 952.0
                                    }
                                ]
                            },
                            "inferText": "2",
                            "inferConfidence": 0.9915,
                            "lineBreak": false
                        },
                        {
                            "boundingPoly": {
                                "vertices": [
                                    {
                                        "x": 1539.0,
                                        "y": 883.0
                                    },
                                    {
                                        "x": 1600.0,
                                        "y": 883.0
                                    },
                                    {
                                        "x": 1600.0,
                                        "y": 956.0
                                    },
                                    {
                                        "x": 1539.0,
                                        "y": 956.0
                                    }
                                ]
                            },
                            "inferText": "8",
                            "inferConfidence": 1.0,
                            "lineBreak": false
                        },
                        {
                            "boundingPoly": {
                                "vertices": [
                                    {
                                        "x": 1626.0,
                                        "y": 891.0
                                    },
                                    {
                                        "x": 1675.0,
                                        "y": 891.0
                                    },
                                    {
                                        "x": 1675.0,
                                        "y": 944.0
                                    },
                                    {
                                        "x": 1626.0,
                                        "y": 944.0
                                    }
                                ]
                            },
                            "inferText": "0",
                            "inferConfidence": 0.9705,
                            "lineBreak": false
                        },
                        {
                            "boundingPoly": {
                                "vertices": [
                                    {
                                        "x": 1705.0,
                                        "y": 895.0
                                    },
                                    {
                                        "x": 1748.0,
                                        "y": 895.0
                                    },
                                    {
                                        "x": 1748.0,
                                        "y": 944.0
                                    },
                                    {
                                        "x": 1705.0,
                                        "y": 944.0
                                    }
                                ]
                            },
                            "inferText": "0",
                            "inferConfidence": 0.9714,
                            "lineBreak": false
                        },
                        {
                            "boundingPoly": {
                                "vertices": [
                                    {
                                        "x": 1776.0,
                                        "y": 897.0
                                    },
                                    {
                                        "x": 1822.0,
                                        "y": 897.0
                                    },
                                    {
                                        "x": 1822.0,
                                        "y": 944.0
                                    },
                                    {
                                        "x": 1776.0,
                                        "y": 944.0
                                    }
                                ]
                            },
                            "inferText": "0",
                            "inferConfidence": 0.9448,
                            "lineBreak": false
                        },
                        {
                            "boundingPoly": {
                                "vertices": [
                                    {
                                        "x": 1853.0,
                                        "y": 887.0
                                    },
                                    {
                                        "x": 1901.0,
                                        "y": 887.0
                                    },
                                    {
                                        "x": 1901.0,
                                        "y": 942.0
                                    },
                                    {
                                        "x": 1853.0,
                                        "y": 942.0
                                    }
                                ]
                            },
                            "inferText": "0",
                            "inferConfidence": 0.994,
                            "lineBreak": true
                        }
                    ]
                }
            ]
        }
    ]
}
```

各フィールドの`inferText`と推測信頼度の`inferConfidence`、画像上の検出位置座標の`boundingPoly`等が返ってきています。`金額1`フィールドの`subFields`には1ケタごとの数値が並んでいて別々の文字列としても検出されていることがわかります。前回のGUIでのテスト結果よりも詳細な情報が取得できました

# おわりに

Clova OCR APIのリクエストを試してみました。基本的に画像をアップロードすれば推測値が返ってくるというシンプルな構成ですが、アップロードの形式が複数選べるのは開発時に便利だと思います。前回と今回でClova OCRの現時点での機能はひととおり紹介できました

Clova OCRはクラウドOCRサービスの中でも無料プランがあり手軽に始められるサービスだと思います。OCR系の開発をご検討の方々のご参考になれば幸いです