日本語特化のAI OCR「YomiToku」と主なOCRソリューションを比較する

[YomiToku](https://github.com/kotaro-kinoshita/yomitoku)は、日本語に特化したAI OCRソフトウェアです。Pythonで作られており、 `pip` コマンドでインストールできます。日本の帳票にあるような複雑なレイアウトや、縦書きの解析も可能です。

今回はYomiTokuを使って、帳票を解析してみます。また、下記のようなOCRソリューションも使って、その結果の違いを確認します。
* YomiToku
* Tesseract
* PaddleOCR
* Google Cloud Vision API


## YomiTokuのセットアップ

YomiTokuは `pip` でインストールします。

```bash
pip install yomitoku
```

ONNX Runtimeの実行にGPUを利用する場合は、以下のコマンドになります。

```bash
pip install yomitoku[gpu]
```

### 注意点

pytorchはCUDAのバージョンに合わせて選択してください。デフォルトではCUDA12.4以上を想定してインストールされます。また、pytorch自身は2.5以上のバージョンが必要です。[Dockerfile](https://github.com/kotaro-kinoshita/yomitoku/blob/main/dockerfile)もあります。

## 今回の帳票

今回は[請求管理ロボ](https://www.robotpayment.co.jp/service/mikata/template/invoice/)にて公開されているテンプレートをベースにさせてもらっています。住所などの情報は[個人情報テストデータ生成ツール](https://testdata.userlocal.jp)を使って生成したダミーデータです。

![スクリーンショット 2025-02-21 17.07.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4009607/aac6483b-e4e6-4457-9788-bb03fd937e91.png)

一般的な帳票にあるような構成かと思います。

- ヘッダー
- リスト
- フッター

この帳票をYomiTokuで解析します。

## OCR処理を行う

### ファイルを配置する

解析対象とするファイルは、ExcelファイルではなくPDFファイルになります。ExcelからPDFとしてエクスポートしたものを、 `docs` フォルダ以下に保存しています。

### 解析を実行する

以下のコマンドで解析を実行します。

```bash
# HTMLファイルを出力
yomitoku ./docs -f html
# JSONファイルを出力
yomitoku ./docs -f json
# Markdownファイルを出力
yomitoku ./docs -f md
# CSVファイルを出力
yomitoku ./docs -f csv
```

コマンドを実行すると、最初にモデルをダウンロードします。これは自動的に行われ、初回のみです。

```bash
model.safetensors: 100% 102M/102M [00:02<00:00, 42.4MB/s]
model.safetensors: 100% 200M/200M [00:04<00:00, 42.7MB/s]
model.safetensors: 100% 172M/172M [00:04<00:00, 37.0MB/s]
model.safetensors: 100% 172M/172M [00:04<00:00, 41.2MB/s]
```

そして解析を実行し、 `results` ディレクトリに結果が出力されます。出力先フォルダは変更可能で、なければ自動で作成されます。

```bash
yomitoku.cli.main - INFO - Total Processing time: 4.81 sec
```

### 結果の確認

YomiTokuでの解析結果です。まずレイアウトファイルの内容になります。ヘッダーやフッターの情報、そしてリストの部分が正しく認識されているのがわかります。

#### Markdown

Markdownでの出力結果です。

```markdown
# 請 求 書

# 合名会社小田部石材商会 東京支社 御 中

〒 919\-5359 福井県福井市日之出1\-4\-4<br>営業部 担当者:北岡 泰典 様

下記の通りご請求申し上げます。

請求金額

¥2,855,600\-

|No\. :|123456\-123|
|-|-|
|請求日:|令和13年12月21日|

株式会社ナカヤマ<br>〒 456\-0029<br>愛知県春日井市如意申町<br>4\-1\-10 東城ビル 1F<br>☎ 0531\-50\-0057 0531\-50\-0058<br>sato\_415@example\.org

|No\.|商品名 / 品名|数 |単価|金 額|
|-|-|-|-|-|
|1|ノートパソコン|5 |120,000|600,000|
|2|スマートフォン|8台|80,000|640,000|
  :
|24|||||

備考欄:

|小 計\(税抜\)|¥2,596,000|
|-|-|
|消費税\(10%\)|¥259,600|
|合 計\(税込\)|¥2,855,600|

振込先: あおぞら 銀行 夕立 支店 普通口座 No 0123456 カ\) ナカヤマ

お支払い期限:令和13年12月31日<br>\(※お振込手数料は御社ご負担にてお願い致します\)
```

#### HTML

HTMLでの出力結果（一部）です。

```html
    <table border="1" style="border-collapse: collapse">
      <tr>
        <td rowspan="1" colspan="1">No. :</td>
        <td rowspan="1" colspan="1">123456-123</td>
      </tr>
      <tr>
        <td rowspan="1" colspan="1">請求日:</td>
        <td rowspan="1" colspan="1">令和13年12月21日</td>
      </tr>
    </table>
    <p>株式会社ナカヤマ<br/>〒 456-0029<br/>愛知県春日井市如意申町<br/>4-1-10 東城ビル 1F<br/>☎ 0531-50-0057 0531-50-0058<br/>sato_415@example.org</p>
    <table border="1" style="border-collapse: collapse">
      <tr>
        <td rowspan="1" colspan="1">No.</td>
        <td rowspan="1" colspan="1">商品名 / 品名</td>
        <td rowspan="1" colspan="1">数 </td>
        <td rowspan="1" colspan="1">単価</td>
        <td rowspan="1" colspan="1">金 額</td>
      </tr>
```

#### JSON

JSONでの出力結果です（一部）。 `tables` キー以下がリスト部分になります。

```json
{
    "figures": [
        {
            "box": [1310, 274, 1473, 430],
            "direction": "horizontal",
            "order": 7,
            "paragraphs": [
                {
                    "box": [1313, 280, 1470, 426],
                    "contents": "コロ尚\n山手式\n隠せ風\n証二軸",
                    "direction": "horizontal",
                    "order": 0,
                    "role": null
                }
            ]
        }
    ],
    "paragraphs": [
        {
            "box": [249, 168, 476, 216],
            "contents": "請 求 書",
            "direction": "horizontal",
            "order": 0,
            "role": "section_headings"
        },
        :
    ],
    "tables": [
        {
            "box": [186, 601, 1453, 1743],
            "cells": [
                {
                    "box": [189, 660, 245, 705],
                    "col": 1,
                    "col_span": 1,
                    "contents": "1",
                    "row": 2,
                    "row_span": 1
                },
                {
                    "box": [246, 660, 773, 705],
                    "col": 2,
                    "col_span": 1,
                    "contents": "ノートパソコン",
                    "row": 2,
                    "row_span": 1
                },
                {
                    "box": [773, 660, 1014, 705],
                    "col": 3,
                    "col_span": 1,
                    "contents": "5 ",
                    "row": 2,
                    "row_span": 1
                },
                {
                    "box": [1015, 660, 1205, 705],
                    "col": 4,
                    "col_span": 1,
                    "contents": "120,000",
                    "row": 2,
                    "row_span": 1
                },
                {
                    "box": [1205, 660, 1450, 705],
                    "col": 5,
                    "col_span": 1,
                    "contents": "600,000",
                    "row": 2,
                    "row_span": 1
                },
```

#### CSV

CSVでの出力結果です。

```csv
請 求 書
""
合名会社小田部石材商会 東京支社 御 中
""
"〒 919-5359 福井県福井市日之出1-4-4
営業部 担当者:北岡 泰典 様"
""
下記の通りご請求申し上げます。
""
請求金額
""
"¥2,855,600-"
""
No. :,123456-123
請求日:,令和13年12月21日
""
"株式会社ナカヤマ
〒 456-0029
愛知県春日井市如意申町
4-1-10 東城ビル 1F
☎ 0531-50-0057 0531-50-0058
sato_415@example.org"
""
No.,商品名 / 品名,数 ,単価,金 額
1,ノートパソコン,5 ,"120,000","600,000"
2,スマートフォン,8台,"80,000","640,000"
```

## 他のOCRソリューションで試す

同じファイルを他のOCRソリューションで解析してみます。

### Tesseract

[Tesseract](https://tesseract-ocr.github.io/)で解析を行うと、hocrファイルが出力されます。これはHTMLに似たフォーマットで、テキストが出力されます。タグが多数入るので、実際に利用する際にはテキストのみの抽出が必要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4009607/e700de77-4996-4086-aee9-0e0d5f3b5047.png)


最初の「請求書」が読み取れなかったようです。

```html
 <body>
  <div class='ocr_page' id='page_1' title='image "template_02.png"; bbox 0 0 2893 4092; ppageno 0'>
   <div class='ocr_carea' id='block_1_1' title="bbox 452 278 2528 389">
    <p class='ocr_par' id='par_1_1' lang='jpn' title="bbox 444 278 2528 388">
     <span class='ocr_line' id='line_1_1' title="bbox 452 278 2528 350; baseline -0.003 -18.023; x_size 63.75; x_descenders 13.5; x_ascenders 16.75">
      <span class='ocrx_word' id='word_1_1' title='bbox 452 302 500 343; x_wconf 36'>=</span>
      <span class='ocrx_word' id='word_1_2' title='bbox 482 278 518 350; x_wconf 28'>コ</span>
      <span class='ocrx_word' id='word_1_3' title='bbox 751 278 787 350; x_wconf 0'>生</span>
      <span class='ocrx_word' id='word_1_4' title='bbox 787 302 823 344; x_wconf 6'>ミ</span>
      <span class='ocrx_word' id='word_1_5' title='bbox 1989 297 2052 330; x_wconf 29'>No.</span>
      <span class='ocrx_word' id='word_1_6' title='bbox 2051 275 2075 347; x_wconf 29'>:</span>
      <span class='ocrx_word' id='word_1_7' title='bbox 2280 293 2528 327; x_wconf 92'>123456-123</span>
     </span>
     <span class='ocr_line' id='line_1_2' title="bbox 489 333 2524 389; baseline 0.007 -16.69; x_size 48.208954; x_descenders 10.208955; x_ascenders 12.666667">
      <span class='ocrx_word' id='word_1_8' title='bbox 489 334 514 372; x_wconf 44'>|</span>
      <span class='ocrx_word' id='word_1_9' title='bbox 762 346 800 372; x_wconf 31'>[</span>
      <span class='ocrx_word' id='word_1_10' title='bbox 786 333 814 389; x_wconf 4'>三</span>
      <span class='ocrx_word' id='word_1_11' title='bbox 804 333 824 389; x_wconf 83'>]</span>
      <span class='ocrx_word' id='word_1_12' title='bbox 1930 350 2051 388; x_wconf 96'>請求</span>
      <span class='ocrx_word' id='word_1_13' title='bbox 2075 361 2081 385; x_wconf 93'>日</span>
      <span class='ocrx_word' id='word_1_14' title='bbox 2078 345 2116 402; x_wconf 75'>:</span>
```

表部分は `<table />` タグにはなっていないので、情報を抽出する際には解析が必要になります。

```html
<span class='ocr_line' id='line_1_13' title="bbox 354 1089 2394 1131; baseline 0 -2; x_size 49.166664; x_descenders 11.190476; x_ascenders 9.5">
  <span class='ocrx_word' id='word_1_96' title='bbox 354 1097 418 1130; x_wconf 91'>No.</span>
  <span class='ocrx_word' id='word_1_97' title='bbox 497 1089 627 1131; x_wconf 91'>商品</span>
  <span class='ocrx_word' id='word_1_98' title='bbox 599 1085 640 1146; x_wconf 91'>名</span>
  <span class='ocrx_word' id='word_1_99' title='bbox 650 1091 692 1130; x_wconf 73'>ノ</span>
  <span class='ocrx_word' id='word_1_100' title='bbox 712 1089 795 1131; x_wconf 96'>品名</span>
  <span class='ocrx_word' id='word_1_101' title='bbox 2285 1090 2303 1130; x_wconf 89'>金</span>
  <span class='ocrx_word' id='word_1_102' title='bbox 2349 1090 2394 1131; x_wconf 89'>額</span>
  </span>
  <span class='ocr_line' id='line_1_14' title="bbox 387 1176 2473 1221; baseline -0.001 -5; x_size 44.018806; x_descenders 10.018808; x_ascenders 8.5053301">
  <span class='ocrx_word' id='word_1_103' title='bbox 387 1184 405 1216; x_wconf 94'>1</span>
  <span class='ocrx_word' id='word_1_104' title='bbox 445 1180 477 1215; x_wconf 94'>|</span>
  <span class='ocrx_word' id='word_1_105' title='bbox 454 1172 554 1229; x_wconf 92'>ノー</span>
  <span class='ocrx_word' id='word_1_106' title='bbox 569 1180 585 1214; x_wconf 92'>ト</span>
  <span class='ocrx_word' id='word_1_107' title='bbox 595 1176 610 1214; x_wconf 92'>パ</span>
  <span class='ocrx_word' id='word_1_108' title='bbox 616 1180 651 1215; x_wconf 93'>ソ</span>
  <span class='ocrx_word' id='word_1_109' title='bbox 657 1181 738 1214; x_wconf 96'>コン</span>
  <span class='ocrx_word' id='word_1_110' title='bbox 1673 1180 1714 1218; x_wconf 92'>台</span>
  <span class='ocrx_word' id='word_1_111' title='bbox 1878 1180 2042 1221; x_wconf 89'>120,000</span>
  <span class='ocrx_word' id='word_1_112' title='bbox 2306 1180 2473 1221; x_wconf 87'>600,000</span>
</span>
<span class='ocr_line' id='line_1_15' title="bbox 385 1255 2473 1308; baseline -0 -14; x_size 44.018806; x_descenders 10.018808; x_ascenders 8.5053301">
  <span class='ocrx_word' id='word_1_113' title='bbox 385 1261 406 1294; x_wconf 94'>2</span>
  <span class='ocrx_word' id='word_1_114' title='bbox 442 1260 475 1294; x_wconf 94'>|</span>
  <span class='ocrx_word' id='word_1_115' title='bbox 451 1253 554 1309; x_wconf 93'>スマ</span>
  <span class='ocrx_word' id='word_1_116' title='bbox 521 1253 587 1309; x_wconf 92'>ー</span>
  <span class='ocrx_word' id='word_1_117' title='bbox 582 1257 610 1294; x_wconf 92'>ト</span>
  <span class='ocrx_word' id='word_1_118' title='bbox 617 1260 690 1294; x_wconf 93'>フォ</span>
  <span class='ocrx_word' id='word_1_119' title='bbox 701 1260 731 1294; x_wconf 92'>ン</span>
  <span class='ocrx_word' id='word_1_120' title='bbox 1673 1258 1714 1296; x_wconf 92'>台</span>
  <span class='ocrx_word' id='word_1_121' title='bbox 1901 1255 2043 1308; x_wconf 89'>80,000</span>
  <span class='ocrx_word' id='word_1_122' title='bbox 2306 1259 2473 1300; x_wconf 90'>640,000</span>
</span>
```

### PaddleOCR

[PaddleOCR](https://paddlepaddle.github.io/PaddleOCR/latest/)は、Baiduの開発する日本語対応OCRエンジンです。結果ファイルを出力できます。この内容を見ると、 `御中` など分かれて認識されている部分が確認できます。

![template_02_result.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4009607/7cd3fa78-22b8-4ee8-8cd3-9807f8c261c5.jpeg)


結果は、認識されたテキストとその確立、認識された座標を取得できます。以下は、それをJSONにした結果です。テキストは問題なく解析されています。

```json
[
  {
    "coordinates": [[431, 290], [839, 290], [839, 379], [431, 379]],
    "text": "請求書",
    "confidence": 0.9986839294433594
  },
  {
    "coordinates": [[2277, 286], [2527, 286], [2527, 332], [2277, 332]],
    "text": "123456-123",
    "confidence": 0.9999499320983887
  },
  {
    "coordinates": [[1980, 298], [2062, 298], [2062, 332], [1980, 332]],
    "text": "No.",
    "confidence": 0.9999938607215881
  },
  {
    "coordinates": [[1924, 345], [2058, 345], [2058, 392], [1924, 392]],
    "text": "請求日",
    "confidence": 0.9983651638031006
  },
```

一部、一文が二つに分かれてしまった部分があります。

```json
  {
    "coordinates": [[349, 789], [792, 789], [792, 831], [349, 831]],
    "text": "下記の通りご請求申し",
    "confidence": 0.9995622634887695
  },
  {
    "coordinates": [[784, 789], [999, 789], [999, 831], [784, 831]],
    "text": "上げます。",
    "confidence": 0.9994457364082336
  },
  {
    "coordinates": [[1670, 789], [1808, 789], [1808, 831], [1670, 831]],
    "text": "80531",
    "confidence": 0.8503488302230835
  },
  {
    "coordinates": [[1812, 789], [1972, 789], [1972, 831], [1812, 831]],
    "text": "-50-0057",
    "confidence": 0.9998257160186768
  },
  {
    "coordinates": [[1998, 789], [2135, 789], [2135, 831], [1998, 831]],
    "text": "塩0531",
    "confidence": 0.8567706942558289
  },
  {
    "coordinates": [[2144, 793], [2204, 793], [2204, 827], [2144, 827]],
    "text": "50-",
    "confidence": 0.9983447194099426
  },
```

一覧部分でも、セル内のテキストが分かれて認識されてしまった場合があります。

```json
{
  "coordinates": [[448, 1253], [577, 1253], [577, 1300], [448, 1300]],
  "text": "スマー",
  "confidence": 0.9994642734527588
},
{
  "coordinates": [[560, 1253], [732, 1253], [732, 1300], [560, 1300]],
  "text": "トフォン",
  "confidence": 0.9854453802108765
}
```

## Google Cloud Vision API

[Google Cloud Vision API](https://cloud.google.com/vision?hl=ja)は、Googleが提供するOCR APIです。「請求書」がそれぞれ別な文字として認識されているので、情報抽出時には何らかの結合する必要がありそうです。以下は出力結果の一部です。

![スクリーンショット 2025-02-25 20.14.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4009607/664f6166-1062-4a8f-b7e5-23bf6234549e.png)


```json
{
  "fullTextAnnotation": {
    "pages": [
      {
        "blocks": [
          {
            "blockType": "TEXT",
            "boundingBox": { "vertices": [{"x": 439, "y": 303}, {"x": 831, "y": 303}, {"x": 831, "y": 372}, {"x": 439, "y": 372}] },
            "confidence": 0.9854585,
            "paragraphs": [
              {
                "boundingBox": { "vertices": [{"x": 439, "y": 303}, {"x": 831, "y": 303}, {"x": 831, "y": 372}, {"x": 439, "y": 372}] },
                "confidence": 0.9854585,
                "words": [
                  {
                    "boundingBox": { "vertices": [{"x": 439, "y": 303}, {"x": 674, "y": 303}, {"x": 674, "y": 372}, {"x": 439, "y": 372}] },
                    "confidence": 0.99250364,
                    "symbols": [
                      {
                        "boundingBox": { "vertices": [{"x": 439, "y": 303}, {"x": 521, "y": 303}, {"x": 521, "y": 372}, {"x": 439, "y": 372}] },
                        "confidence": 0.9915527,
                        "text": "請"
                      },
                      {
                        "boundingBox": { "vertices": [{"x": 594, "y": 303}, {"x": 674, "y": 303}, {"x": 674, "y": 372}, {"x": 594, "y": 372}] },
                        "confidence": 0.99345464,
                        "text": "求"
                      }
                    ]
                  },
                  {
                    "boundingBox": { "vertices": [{"x": 747, "y": 303}, {"x": 831, "y": 303}, {"x": 831, "y": 372}, {"x": 747, "y": 372}] },
                    "confidence": 0.97136813,
                    "symbols": [
                      {
                        "boundingBox": { "vertices": [{"x": 747, "y": 303}, {"x": 831, "y": 303}, {"x": 831, "y": 372}, {"x": 747, "y": 372}] },
                        "confidence": 0.97136813,
                        "property": { "detectedBreak": { "type": "LINE_BREAK" } },
                        "text": "書"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "blockType": "TEXT",
            "boundingBox": { "vertices": [{"x": 374, "y": 475}, {"x": 1480, "y": 475}, {"x": 1480, "y": 532}, {"x": 374, "y": 532}] },
            "confidence": 0.98113906,
            "paragraphs": [
              {
                "boundingBox": { "vertices": [{"x": 374, "y": 475}, {"x": 1480, "y": 475}, {"x": 1480, "y": 532}, {"x": 374, "y": 532}] },
                "confidence": 0.98113906,
                "words": [
                  {
                    "boundingBox": { "vertices": [{"x": 374, "y": 475}, {"x": 486, "y": 475}, {"x": 486, "y": 529}, {"x": 374, "y": 529}] },
                    "confidence": 0.98838997,
                    "property": { "detectedLanguages": [{ "confidence": 1, "languageCode": "ja" }] },
                    "symbols": [
                      {
                        "boundingBox": { "vertices": [{"x": 374, "y": 475}, {"x": 431, "y": 475}, {"x": 431, "y": 529}, {"x": 374, "y": 529}] },
                        "confidence": 0.98224795,
                        "text": "合"
                      },
                      {
                        "boundingBox": { "vertices": [{"x": 435, "y": 475}, {"x": 486, "y": 475}, {"x": 486, "y": 529}, {"x": 435, "y": 529}] },
                        "confidence": 0.994532,
                        "text": "名"
                      }
                    ]
                  },
                  {
                    "boundingBox": { "vertices": [{"x": 493, "y": 475}, {"x": 606, "y": 475}, {"x": 606, "y": 529}, {"x": 493, "y": 529}] },
                    "confidence": 0.99610496,
                    "property": { "detectedLanguages": [{ "confidence": 1, "languageCode": "ja" }] },
                    "symbols": [
                      {
                        "boundingBox": { "vertices": [{"x": 493, "y": 475}, {"x": 547, "y": 475}, {"x": 547, "y": 529}, {"x": 493, "y": 529}] },
                        "confidence": 0.99506485,
                        "text": "会"
                      },
                      {
                        "boundingBox": { "vertices": [{"x": 551, "y": 475}, {"x": 606, "y": 475}, {"x": 606, "y": 529}, {"x": 551, "y": 529}] },
                        "confidence": 0.997145,
                        "text": "社"
                      }
                    ]
                  }
```

リスト部分でも、セル中の文字が分かれてしまっている部分があります。

```json
{
  "boundingPoly": {
    "vertices": [
      { "x": 440, "y": 1176},
      { "x": 571, "y": 1175},
      { "x": 571, "y": 1214},
      { "x": 440, "y": 1215}
    ]
  },
  "description": "ノート"
},
{
  "boundingPoly": {
    "vertices": [
      { "x": 565, "y": 1175},
      { "x": 740, "y": 1174},
      { "x": 740, "y": 1214},
      { "x": 565, "y": 1215}
    ]
  },
  "description": "パソコン"
},
```

商品名と、数量と単価部分が分かれて出力されました。この場合、商品名と金額との付け合わせの実装が必要になるでしょう。

```json
{
  "boundingPoly": { "vertices": [{ "x": 1627, "y": 1182}, { "x": 1651, "y": 1182}, { "x": 1651, "y": 1217}, { "x": 1627, "y": 1217}] },
  "description": "5"
},
{
  "boundingPoly": { "vertices": [{ "x": 1670, "y": 1182}, { "x": 1715, "y": 1182}, { "x": 1715, "y": 1217}, { "x": 1670, "y": 1217}] },
  "description": "台"
},
{
  "boundingPoly": { "vertices": [{ "x": 1876, "y": 1182}, { "x": 2043, "y": 1182}, { "x": 2043, "y": 1216}, { "x": 1876, "y": 1216}] },
  "description": "120,000"
},
{
  "boundingPoly": { "vertices": [{ "x": 2306, "y": 1182}, { "x": 2474, "y": 1182}, { "x": 2474, "y": 1216}, { "x": 2306, "y": 1216}] },
  "description": "600,000"
},
{
  "boundingPoly": { "vertices": [{ "x": 1627, "y": 1257}, { "x": 1649, "y": 1257}, { "x": 1649, "y": 1295}, { "x": 1627, "y": 1295}] },
  "description": "8"
},
{
  "boundingPoly": { "vertices": [{ "x": 1671, "y": 1257}, { "x": 1715, "y": 1257}, { "x": 1715, "y": 1295}, { "x": 1671, "y": 1295}] },
  "description": "台"
}
```

## YomiTokuの特徴

YomiTokuの特徴は、以下の通りです。

### AIを活用

YomiTokuでは、以下の4種類のAIモデルを搭載しています。

- 文字位置の検知
- 文字列認識
- レイアウト解析
- 表の構造認識

いずれも日本語データセットで学習しています。

### 日本語、英語に対応

日本語の文書画像に特化して学習しており、日本の商習慣で使われる複雑な表であったり、縦書き文書にも対応しています。7,000文字を超える大規模な日本語文書でも利用できます。

### レイアウト解析・表の構造認識

段組や、帳票や書面の中で使われている表の構造認識ができ、レイアウトの意味的構造を正しく認識、情報を抜き出します。

### 多様な出力フォーマット

出力は以下の4フォーマットに対応しています。

- Markdown
- JSON
- HTML
- CSV

システム連携も容易なJSON、見やすいMarkdown、表計算ソフトでの利用に便利なCSVなど、用途に合わせて使い分けることができます。

### セキュリティ

クラウドサービスではないので、自社サーバー内に閉じた環境下で解析できます。請求データなど、機密情報を取り扱う上でも安心です。

### GPU利用

GPU環境下で高速に動作します。VRAMは8GB以内で動作しますので、ハイエンドなGPUでなくても利用できます。

## 注意点

### CPUでの利用について

YomiTokuはGPUでの利用を推奨していますが、CPU環境下でも実行は可能です。ただし、解析には数分かかるので注意してください。

### 手書き文字について

2025年2月現在のYomiTokuでは、活字のみサポートしています。手書き文字については、公式にはサポートしておりません。また、看板など紙以外にプリントされた情景OCRについては、最適化されていません。

### 画像サイズについて

低解像度画像では識別精度が低下します。画像の短辺を720px以上の画像で解析することを推奨します。

## ライセンス

YomiTokuのライセンスは[コモンズ証 \- 表示 \- 非営利 \- 継承 4\.0 国際 \- Creative Commons](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.ja)です。非商用での個人利用、研究目的においては、ご自由に利用できます。商用目的での利用に関しては、商用ライセンスが必要です。

## まとめ

今回は主なOCRエンジンと、YomiTokuの解析結果の違いについて解説しました。YomiTokuは日本語OCRに特化しており、テキストの認識精度はもちろん、縦書きや日本の商習慣にあった帳票の解析にも向いています。各種出力フォーマットを用意していますので、システム連携や業務効率化に役立つはずです。

[kotaro\-kinoshita/yomitoku: Yomitoku is an AI\-powered document image analysis package designed specifically for the Japanese language\.](https://github.com/kotaro-kinoshita/yomitoku?tab=readme-ov-file)