CLOVA OCRのInvoice OCR APIを使った請求書の読み取りを試す

2022.01.24

業務効率化の一環で、手作業が多いデータ入力の作業を短縮するためにOCRを利用しようと考えています。 今回はLINE CLOVAのプロダクトであるCLOVA OCRを使う機会があったのでご紹介しようと思います。

CLOVA OCRは、多言語に対応したテキスト検出・文字認識ができるAI-OCRサービスです。悪条件下での読み取り、専門用語の認識も可能であり、あらゆるスタイルの書類を正しくテキスト化することができます。

以下のような帳票を読み取り、データ化することが可能となっています。

この中で請求書に特化したInvoice OCRのAPIを利用できる検証環境を用意してもらったので、使用感などを確認していきます。

やってみる

書類や帳票の画像・PDFをCLOVA OCR APIへアップロードすると、読み取られた結果がJSONで返却されます。

読み取った結果をデータベースに保存するといった連携ができますね。

API呼び出しに関してですが、検証環境としてリクエストURLとAPIキーが払い出されていましたので、それを使ってHTTPリクエストを行います。

APIキーはリクエストヘッダーに含めます。

返却内容は、

[
  {
    extension: { imagesize: [Array] },
    result: {
      contactInfo: [Object], // 問合せ先情報
      generalInfo: [Object], // ⼀般情報(請求書発⾏⽇、件名、請求書番号など)
      items: [Array], // 購⼊品⽬の情報
      otherInfo: [Object], // その他情報(備考など)
      paymentInfos: [Array], // ⽀払情報
      recipientInfo: [Object], // 請求先情報
      senderInfo: [Object], // 請求元情報
      subTotals: [Array], // ⼩計情報
      totalPriceInfo: [Object] // 合計⾦額情報
    }
  }
]

上記のようになっています。

検証のアウトプットとして、請求先・購⼊品⽬・合計⾦額を出力してみました。

請求書1

上記の請求書をAPIを使って読み取って見たところ、

recipientInfo(請求先情報)

{
  address: [
    {
      confidence: 0.9942721213058168,
      coordinates: [Object],
      isConfident: false,
      value: '東京都品川区西品川1-1'
    }
  ],
  companyName: [
    {
      confidence: 0.9986679349173979,
      coordinates: [Object],
      isConfident: false,
      value: 'クローバ株式会社'
    }
  ],
  department: [
    {
      confidence: 0.9983450044037444,
      coordinates: [Object],
      isConfident: false,
      value: 'ITシステム部'
    }
  ],
  personName: [
    {
      confidence: 0.9934499993116264,
      coordinates: [Object],
      isConfident: false,
      value: 'ご担当者'
    }
  ],
  postalCode: [
    {
      confidence: 0.6331092245040958,
      coordinates: [Object],
      isConfident: false,
      value: '〒141-0033'
    }
  ]
}

totalPriceInfo(合計⾦額情報)

{
  taxAmount: [
    {
      confidence: 0.9999876020942865,
      coordinates: [Object],
      isConfident: true,
      value: 83000
    }
  ],
  totalPrice: [
    {
      confidence: 0.9999973058699265,
      coordinates: [Object],
      isConfident: true,
      value: 913000
    }
  ]
}

items

{
  count: [
    {
      confidence: 0.9999806880950928,
      coordinates: [Object],
      isConfident: true,
      value: 3000
    }
  ],
  name: [
    {
      confidence: 0.9999148258983945,
      coordinates: [Object],
      isConfident: true,
      value: 'LINE CLOVA サンプル(品番:49231)'
    }
  ],
  priceInfo: {
    taxAmount: [ [Object] ],
    taxExcludedUnitPrice: [ [Object] ],
    taxIncludedPrice: [ [Object] ],
    taxInfo: [ [Object] ]
  },
  quantityUnit: [
    {
      confidence: 0.9503827095031738,
      coordinates: [Object],
      isConfident: false,
      value: '個'
    }
  ]
},
{
  count: [
    {
      confidence: 0.9999573230743408,
      coordinates: [Object],
      isConfident: true,
      value: 1
    }
  ],
  name: [
    {
      confidence: 0.9999879200418105,
      coordinates: [Object],
      isConfident: true,
      value: '2021年11月度ご利用金額一式'
    }
  ],
  priceInfo: {
    taxAmount: [ [Object] ],
    taxExcludedUnitPrice: [ [Object] ],
    taxIncludedPrice: [ [Object] ],
    taxInfo: [ [Object] ]
  },
  quantityUnit: [
    {
      confidence: 0.8604850769042969,
      coordinates: [Object],
      isConfident: false,
      value: '式'
    }
  ]
},
{
  count: [
    {
      confidence: 0.9999665021896362,
      coordinates: [Object],
      isConfident: true,
      value: 1
    }
  ],
  name: [
    {
      confidence: 0.9999694098526742,
      coordinates: [Object],
      isConfident: true,
      value: '施設利用料'
    }
  ],
  priceInfo: {
    taxAmount: [ [Object] ],
    taxExcludedUnitPrice: [ [Object] ],
    taxIncludedPrice: [ [Object] ],
    taxInfo: [ [Object] ]
  },
  quantityUnit: [
    {
      confidence: 0.7254598736763,
      coordinates: [Object],
      isConfident: false,
      value: '日'
    }
  ]
}

 すごい精度で読み取ってくれていました。

テーブル表記の箇所も項目ごとに読み取れていることに感動。

プログラムで読み取った情報を整形した結果はこんな感じです。

請求書2(テーブルの線が薄い)

上記の請求書を読み取って整形したら、

このような結果になりました。プログラムは同じです。

品目のtaxが0円になっていますね。

itemのpriceInfoオブジェクトは、

{
  count: [
    {
      confidence: 0.9999990463256836,
      coordinates: [Object],
      isConfident: true,
      value: 1
    }
  ],
  name: [
    {
      confidence: 0.999996829032845,
      coordinates: [Object],
      isConfident: true,
      value: 'ノートパソコン'
    }
  ],
  priceInfo: {
    taxExcludedPrice: [ [Object] ],
    taxExcludedUnitPrice: [ [Object] ]
  }
}

上記のようにtaxExcludedの情報しか格納されていませんでした。

そのほかの品目名や個数は正しく読み取ってくれますね。

subTotalsのほうにはtaxの情報が格納されていましたので、こちらの合計金額は正しく表示できました。

{
  subTotalPrice: [
    {
      confidence: 0.9999919335035972,
      coordinates: [Object],
      isConfident: true,
      value: 201000
    }
  ],
  taxAmount: [
    {
      confidence: 0.9998310957170726,
      coordinates: [Object],
      isConfident: false,
      value: 20100
    }
  ],
  totalPrice: [
    {
      confidence: 0.9999980131784965,
      coordinates: [Object],
      isConfident: true,
      value: 221100
    }
  ]
}

請求書3(テーブルの線が薄い、品目名が長い)

請求書2と同じようにテーブルの線を薄くし、さらに品目名が長いものを入れたものをAPIで読み込んでみると、

品目の数、数字は正しく読み取ってくれていましたが、名前の読み取りがおかしくなっていました。

{
  count: [
    {
      confidence: 0.9999958276748657,
      coordinates: [Object],
      isConfident: true,
      value: 1
    }
  ],
  name: [
    {
      confidence: 0.9958351157247575,
      coordinates: [Object],
      isConfident: false,
      value: 'ノートパソコンLenoVO 「IdeaPad Duet 350i」 82AT00DN JP モニター 【Amazon.co.jp 限定】 LGモニターディスプレ'
    }
  ],
  priceInfo: {
    taxExcludedPrice: [ [Object] ],
    taxExcludedUnitPrice: [ [Object] ]
  }
},
{
  count: [
    {
      confidence: 0.9999947547912598,
      coordinates: [Object],
      isConfident: true,
      value: 1
    }
  ],
  name: [
    {
      confidence: 0.9860007473551412,
      coordinates: [Object],
      isConfident: false,
      value: 'イ 34WL500-B 34インチ/21:9 ウルトラワイド(2560X1080)/HDR/IPS 非光沢/FreeSync対応/HDMIX2/ブルーライト 低減、フリッカーセーフ機能'
    }
  ],
  priceInfo: {
    taxExcludedPrice: [ [Object] ],
    taxExcludedUnitPrice: [ [Object] ]
  }
}

jsonの中身は上記のようになっています。

テーブルの罫線が薄かったり、そもそもなかったりする場合は読み取り精度が落ちてしまうのだろうと思います。

請求書4(テーブルの線あり、品目名が長い)

請求書3の罫線ありバージョンならどうだろう?と思い試して見たところ、

今度は品目数も正しく読み取れなくなっていました。

品目名が長くて複数行にまたがってしまう場合も精度が落ちる傾向なのだろうと思います。

最後に

CLOVA OCRのInvoice OCR APIを使って請求書の読み取りを行ってみました。

読み取りの精度はすごかったですね。今回のようにAPIを使用することで他のシステムとの連携に使えたりするので、 書類や画像データの読み取り・取り込みにかかる作業時間を短縮する、確認作業も含む業務プロセスの効率化をはかりたいといった時には選択肢の一つになるかと思います。

精度に関してもどんどんと高まってくるでしょうし、実際に使ってみてフィードバックを上げることで貢献できたりします。

実際に試して見たいという方は、公式でオンラインの無料体験会を行なっているので参加してみましょう。 私も無料体験会経由で検証環境を払い出してもらいました。