【第6回】HeartCore RoboでOCRを使ってみよう - 基本編

#はじめに
HeartCore RoboにはOCR機能が搭載されております。OCRツールはTesseractで、別途インストールが必要になります。ダウンロード方法及びインストール方法については製品ダウンロード時に梱包されているセットアップガイドを参照下さい。

留意点：
Windows版Tesseractは不定期にバージョンアップされるので都度下記サイトで最新バージョンのチェックが必要になります。
https://digi.bib.uni-mannheim.de/tesseract/

# HeartCore RoboにおけるOCRについて

HeartCore RoboからTesseractのコントロール（起動・パラメータ指定）を行いOCRを実行します。OCR結果はHeartCore Roboのシステム変数に文字列として格納されるので、スクリプトによる修正・置換が可能です（例：値段についている￥マークを除く）。

OCR読取→データ修正→別システムへのデータエントリーの一連の流れをHeartCore Roboでコントロール出来るのが最大のメリットです。

# HeartCore RoboにおけるOCRの基本動作について

読み取り対象ファイル（PDF・TIFF等）を開いてデスクトップ画面に表示する必要があります。ファイル全体を一気にOCR実行するのではなく、四角形の範囲を指定したピンポイントOCR実行を行います。

ピンポイントOCRのメリットは、OCR不要な箇所を排除することでノイズを削減する事と、OCR対象に応じたパラメータ設定（例：日本語の箇所・金額の箇所によってOCRパラメータを変更）を行う事により、より高いOCR精度が期待出来ます。

ピンポイントOCR実行対象例：
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/2ad2dfc6-e203-1642-073f-23f401038ab6.png)
宛名、納品書番号、納品日、合計金額、明細行だけをOCR実行します。OCRが必要無い書類のテンプレート部分（納品書や「下記の通り納品いたしました」の文言）を外す事でOCRの読取り時間も短縮出来ます。

# HeartCore RoboからOCRを実行してみよう
以下にHeartCore RoboからOCRを実行する方法を記載します。本記事のサンプルは、実際に紙でプリントアウトしたものをスキャンして取込み、PDF形式で保存したファイルを使用しています。

事前準備：
OCR対象のファイル（PDF）を用意の上画面に開く（倍率は100％）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/1f04d767-11ec-1342-b05a-fd103018e611.png)

＊上記のサンプルはAcrobat ReaderでPDFファイルを開いています＊

1. スクリプト画面で Report “results.xml” とある行の冒頭でEnterを押して空白行を追加
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/1dbb5439-b5d5-386d-f35e-52010a37e1fa.png)

2. 空白部分を右クリック > コマンドを作成 > Click -File > Comparetoを選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/62ea794b-bf2e-0f17-871c-aaca52826193.png)

3. プロパティ画面が開くので比較メソッド > tocrを選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/af3eea9a-50e2-95ac-39ad-2e3f3a3f9d2d.png)

4. 比較領域にチェック
5. 紫色のアイコンをクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/21ff79dd-6a04-d72c-4898-df89197f12ed.png)

6. 領域指定画面が開くのでOCR対象範囲指定（下記の例では「御中」の左横部分） > 決定をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/53d0b8ce-601a-2e05-fd75-0912f14bd7d3.png)
決定アイコン：![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/8b57f6d1-14ed-cf4e-01f2-84ccd2c84e7d.png)

留意点：領域指定の際には下線や罫線を入れないようにします。下線や罫線がOCR対象に入ると、文字として認識される場合があります。

7. 比較領域の左上のXY座標(x:/y:)と幅高さ(w:/ h:)の値が取得されたのを確認
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/e288081f-bf51-3e01-5814-5101564d5726.png)

8. 比較（シミュレーション）を実行
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/e4de4154-ef2b-37ac-8cea-9fd1336edbd0.png)

9. 「以下のテキストが認識されました・・」の箇所でOCR結果を確認
10. OKをクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/6efd4818-0610-2daa-0572-ff10edf05539.png)

**この時点で期待するOCR結果は出ていません**

## OCRの結果が思わしくない場合の原因

1. OCR対象言語が指定されていない（デフォルトは英語）→今回の原因
2. 最適なOCRパラメータが設定されていない
3. 範囲指定が正しくない
4. 対象フォントが小さい・クリアで無い・歪んでいる
5. OCRフォントライブラリに無いフォントを対象としている
6. OCR対象文字数が少ない（3文字以上が望ましい）

# OCRのパラメータ調整を行ってみる

OCRには様々なパラメータが用意されています。HeartCore Roboのシュミレーター機能を使用しながら最適な結果が得られる設定を調整します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/2e5cc2b2-fc16-7129-b527-6eed6ee92bb2.png)

上記の宛名を読み込む例では、日本語用OCR設定を行っていないため、日本語部分の結果が思わしくありませんでした。下記が日本語をOCR実行する際の手順です。

1. プロパティ画面上の言語に”jpn”と入力(=日本語フォント指定)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/476b15e7-5aef-3757-3bee-913e9869c647.png)

2. 比較（）を実行
3. 「以下のテキストが認識されました・・」の箇所でOCR結果を確認
4. 今回は画面に表示されている日本語表記と同様の結果が取得されたのを確認
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/f08da465-fed8-4cd9-b27b-09235dd388de.png)

5. シミュレーション結果画面のOKをクリック
6. プロパティ画面のOKをクリック
7. OCR実行スクリプトが追加された事を確認
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/e8479134-4866-5b46-1576-b8fae564811c.png)

OCRコマンドの例：
>Compareto method="tocr" cmparea="x:77,y:360,w:402,h:33" language="jpn"

説明：
> Compareto method="tocr" cmparea="x:{OCR対象領域左上X座標},y:{OCR対象領域左上Y座標},w:{OCR対象領域幅},h:｛OCR対象領域高さ｝" language="｛言語｝"


*{言語}：Tesseractをインストールする際に追加指定した言語を3文字で指定します。日本語の場合は”jpn”を指定します。指定しない場合は英語の"eng"となります。*

# OCRの実行結果を取得してみる
OCRの実行結果はHeartCore Roboシステム変数に文字列として格納されます。シミュレーションだけではOCR結果が格納されないので、実際にロボットを実行する必要があります。

1. 追加されたスクリプトを実行
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/818ad07e-17d7-2212-c9e6-bd4a367c7895.png)

2. 実行が完了するとHeartCore Robo画面に戻るので、変数タブを選択
3. 実行変数タブ > _TOCR_TEXT > OCR結果が格納されているのを確認
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/71fd53c6-1d76-2dfe-a75f-95a69b406815.png)

> 変数の説明：
> {_TOCR_TEXT}
> 実行したOCR結果（読み取り結果）が文字列として格納されるシステム変数

4. _TOCR_TEXT変数上で右クリック > 変数名をクリップボードへコピーを選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/280d3026-eea0-b363-ac8c-65f9578acc5a.png)

5. スクリプト画面空白行にログ出力コマンドLog {}と入力
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/b55bf4b8-8c13-91e1-675f-6d8ae8a168a8.png)

6. 中括弧内{}にて右クリック > CTRL+Vを押して変数名（ _TOCR_TEXT）をコピー
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/a4a55ac5-081d-41f9-0f50-f7704cb7d2fa.png)

7. スクリプト実行
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/818ad07e-17d7-2212-c9e6-bd4a367c7895.png)

8. OCR実行結果がログに出力されているのを確認
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/1c3d0fb2-e48a-316f-9e33-136d10bc4861.png)


他の箇所もOCR実行してみて下さい。
下記の例では、納品書番号の記載箇所を対象としています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/9d5fca80-99b5-4012-2566-219fa9b46a4a.png)
↓
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/0ad13940-0dc7-f061-7f84-67c26c328c4f.png)

今回のOCR対象は数字のみのため、言語を日本語指定しなくとも期待したOCRの結果が得られていますが、数字をOCRした場合、数字の１をアルファベットの"I"かLの小文字”ｌ”として認識される場合があります。もし想定した結果が得られない場合は、OCRモードを「高精度」に変更したり、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/bb0d1607-64e8-eed9-7365-d148783a163d.png)

スケール倍率（フォントの拡大率：デフォルトは２）を高めた設定でシミュレーションを繰り返してみます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/2ac11050-d53c-4163-1f15-b872ac2f96ba.png)

実行の結果例：
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/9043b87b-3f6f-fced-a9de-cf389b2c6828.png)

#次回について

今回はOCR対象領域（デスクトップ上の座標と高さと幅）を絶対値で指定した上での実行でしたが、[次回](https://qiita.com/Go_Miyake/items/7f32a6388f8fd6c2350e)はHeartCore Roboの特徴である画像認識（イメージ検索）を応用して、「OCRの対象が画面上の何処にあっても実行できる」ように対象領域を相対的に指定して処理を行う方法をカバーします。