【Python】簡単OCR

# はじめに
PythonのOCRを調べると、Pyocrの記事がよく出てきます。しかし、世の中には色々な手法が存在します。
今回は、PyocrとeasyOCRの使い方を紹介していこうと思います。

PyocrとeasyOCRの違いをはじめに紹介します。
使用する状況によって使い分けることでより良い結果を得られます。
| ライブラリ | 特徴 |
|:-----------:|:------------:|
| Pyocr | 文章として見読み取ることに適しています。 |
| easyOCR | 画像内の単語を読み取ることに適しています。 |
### github
今回のコードはgithubに載せているのでわからなくなった場合は参考にしてください。

https://github.com/masa2122/Brief_AI_implementation_summary/tree/main/%E6%96%87%E5%AD%97%E8%AA%8D%E8%AD%98(OCR)

# Pyocr
PyocrはGoogleが開発したOCRエンジンを使用してOCRを行うライブラリです。

「python ocr」で調べると多くの記事が出てきます。

## 動作環境
Googlecolaboratoryで実行しています。

ローカルで作業する場合はご自身の環境にライブラリのインストールが必要です。
- Python 3.10
- opencv 4.7.0.72
- pyocr 0.8.3
### インストール
pyocrと日本語のocrエンジンをダウンロードします。
```
!pip install pyocr
!apt install tesseract-ocr libtesseract-dev tesseract-ocr-jpn
```
下記のコマンドを実行してjpnと表示されたらインストール成功です。
```
!tesseract --list-langs
```
## 初期設定
設定と文字を抽出する画像の選択を行います。
### 設定
ライブラリのインストールとpyocrが使えることを確認し、tesseractを選択します。
このプログラムは一回実行すれば良いものです。
```python
from PIL import Image
import pyocr
import cv2
from google.colab.patches import cv2_imshow

# pyocrが使えることを確認する
tools = pyocr.get_available_tools()
# tesseractのみダウンロードしたため0番目を指定
tool = tools[0]
print(tool.get_name())

# Tesseract (sh)と出力されればOK
```
### 画像を選択
画像をImage.openで読み込みます。

今回は、input関数でファイルまでのパスを入力していますが、img1_pathにそのまま代入しても大丈夫です。

画像はWikipediaの一部です。
```python:
img1_path = input('ファイルまでのパスを入力')
img1 = Image.open(img1_path)
img1
```
__出力結果__
![OCR横1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2418172/a0c5fdfe-64c8-38b6-c5e8-6c4995dc10a0.png)
## 実行
文字の読み取りと文字の位置の描画を行います。
### 文字の読み取り
読み取った画像から文字を読み取ります。

第一引数に対象の画像、langを日本語と英語に設定をします。
builderは方針です。方針の内容は[tana_kenの作業ログ](http://tanaken-log.blogspot.com/2012/08/imagemagick-tesseract.html)がまとめてくれていました。
詳しくは下記の表を参照
```python
txt1 = tool.image_to_string(
    img1,
    lang='jpn+eng',
    builder=pyocr.builders.TextBuilder(tesseract_layout=6)
)

print(txt1)
```
__出力結果__
かなりよく抽出できている気がします。
![スクリーンショット 2023-07-18 10.41.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2418172/d18682a3-beb2-7403-1c5e-97cd0cd30670.png)

__tesseract_layoutの設定一覧（翻訳済）__
```markdown
0 = オリエンテーションとスクリプト検出 (OSD) のみ。
1 = 自動ページ分割と OSD。
2 = 自動ページ分割、ただしOSDなし、またはOCRなし。
3 = 完全自動ページ分割、ただし OSD なし。(デフォルト）
4 = サイズの異なるテキストの単一列を想定。
5 = 垂直に整列されたテキストの単一の均一なブロックを想定する。
6 = 一様な単一のテキストブロックを想定する。
7 = 画像を単一のテキスト行として扱う。
8 = 画像を一つの単語として扱う。
9 = 画像を円の中の一つの単語として扱う。
10 = 画像を一文字として扱う。
```
### 文字の位置を表示
文字の読み取りと同じ設定でOCRにかけます。

OCRの結果は推定文字と座標が入っています。
この座標をもとに元の画像に長方形を描画していきます。
```Python
results = tool.image_to_string(
    img1,
    lang='jpn+eng',
    builder=pyocr.builders.WordBoxBuilder(tesseract_layout=6)
)

draw_rectangle = cv2.imread(img1_path)

for box in results:
    print(box)
    #  左上、右下の点
    cv2.rectangle(draw_rectangle, box.position[0], box.position[1], (255, 0, 0), 1)

# 画像の保存
cv2.imwrite('draw_rectangle.png', draw_rectangle)
# 保存済みの画像を表示
draw_rectangle = Image.open('draw_rectangle.png')
draw_rectangle
```
__出力結果__
こう見るとごちゃごちゃしていますね。
![スクリーンショット 2023-07-18 10.42.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2418172/21510d3a-eaa8-4927-2d84-d24ca25becbc.png)

# easyOCR
80以上の言語をサポートしOCRをすぐに使用できます。
ラテン語、中国語、アラビア語、デーヴァナーガリー文字、キリル文字などの言語を読み取ることができます。

読み取る言語は複数選べますが、それぞれの相性があります。
英語は基本的にどの分野とも相性がいいらしいです。
## 動作環境
Googlecolaboratoryで実行しています。

ローカルで作業する場合はご自身の環境にライブラリーのインストールが必要です。
- Python 3.10
- opencv 4.7.0.72
- easyocr 1.7.0
### インストール
easyocrをインストールします。
```
!pip install easyocr
```

## 初期設定
日本語の抽出をするための設定を行っていきます。
### 設定
ライブラリーのインストールとeasyocrの言語設定を行います。

言語設定は一度で設定すれば大丈夫です。

最後の行のpathには画像までのパスを入れてください
```python
import easyocr
import cv2
from google.colab.patches import cv2_imshow
reader = easyocr.Reader(['ja','en']) # 文字の選択一回だけでいい
path = "youer/path"
```

## 実行
Pyocrと同じ様に文字の読み取りと文字の位置の描画を行います。
githubのコードの順番と紹介する順番が前後しています。
気をつけてください。
### 文字の読み取り
読み取った画像から文字を読み取ります。
_detail_ の値を0にすることで文字のみを取り出せます。
```python
result2 = reader.readtext(path, detail=0) # 文章のみ
result2
```

__出力結果__
Pyocrの方が良く読み取れている気が、、
![スクリーンショット 2023-07-19 19.47.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2418172/06d8edcd-7247-f911-8378-202b61ce8104.png)

### 文字の位置を表示
文字の読み取りと同じ設定でOCRにかけます。

OCRの結果は推定文字と座標が入っています。
この座標をもとに元の画像に長方形を描画していきます。
```python
result = reader.readtext(path)

img = cv2.imread(path)
img_1 = img.copy()
# 文字ごとに枠を作成
for i in range(len(result)):
    cv2.rectangle(img_1, result[i][0][0], result[i][0][2], (0,255,0),3)
# goolecolaboratory
cv2_imshow(img_1)
```

__出力結果__
綺麗に文字の位置が検出できています。
![スクリーンショット 2023-07-19 19.48.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2418172/e8c98526-4200-363b-917d-206bf90cf30e.png)

# おわりに
最後までご覧いただきありがとうございます。

今回は２つのOCR方法を紹介しました。
OCRは論文を読めば読むほどイメージと違い難しいと感じ、面白い分野でした。

初学者のため情報に誤りがある可能せいがあります。
ご了承ください。

# 参考文献
## Pyocr
https://takaaki-hobby-blog.com/python/python_ocr/#:~:text=PyOCR(%E3%83%91%E3%82%A4%E3%82%AA%E3%83%BC%E3%82%B7%E3%83%BC%E3%82%A2%E3%83%BC%E3%83%AB),Pillow%E3%80%8D%E3%82%82%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82

https://tt-tsukumochi.com/archives/5275

https://kazu-oji.com/python-pyocr_base/#toc8

## easyocr

https://github.com/JaidedAI/EasyOCR

https://qiita.com/takoroy/items/806378e142c0e05d00cc