はじめに
前回はテンプレートビルダのGUIで作成したテンプレートのテストまでをやってみました
今回はリリースしたテンプレートをAPI公開してAPIリクエストで認識を試してみようと思います
テンプレートをリリースする
前回はテンプレートをテスト用にベータリリースしましたが、APIで利用するにはサービスリリースが必要です。サイドメニューのリリース
をクリックしてリリースしたいテンプレートIDの動作欄にあるサービスリリース
ボタンをクリックします。リリースされると現在のリリース状態欄にService (ビルド ID: xxxxxx)
と表示されます
API Gatewayを申請する
APIはNEVER Cloud PlatformのAPI Gatewayサービスと連携しているのでまずAPI Gatewayの利用申請が必要です。NEVER Cloud PlatformのサイドメニューからProducts & Service
をクリックして一覧からAPI Gateway
をクリックします
商品利用の申請
をクリックします
API Gatewayサービスの利用規約を読み、同意します。
にチェックを入れ商品利用の申請
をクリックします
申込みが完了します
APIを設定する
Clova OCRのテンプレートビルダページにもどってAPI設定
タブをクリックしCustom
欄の設定
をクリックします
Secret Key欄の作成
をクリックしてSecret Keyを生成しコピーしておきます。APIGW自動連携欄の自動連携
をクリックします
確認
をクリックします
自動連携が完了するとAPIGW Invoke URLが生成されるのでコピーします。このURLとSecret Keyを使用してAPIリクエストを行います
リクエストする
いよいよ画像をPOSTして認識結果を取得します。ドキュメントによるとPOSTリクエストできるContent-Typeはmultipart/form-data
とapplication/json
がサポートされていてapplication/json
のほうはBase64エンコードした画像が指定できるようです。ケースに応じて画像データの形式が選べるのは便利ですね。
今回は前回利用したテスト用画像をBase64エンコードしたものを使用してみます。Base64エンコードした画像の場合はContent-Typeapplication/json
でリクエストボディのimages[].format
にjpeg
などの画像フォーマット、images[].data
にエンコード文字列を指定します。以下のようなリクエストボディになります
{
"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でPOSTリクエストしてみました
レスポンスデータは以下のようになりました
{
"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系の開発をご検討の方々のご参考になれば幸いです