【検証】Google Cloud Vision APIで高速文字認識(OCR)

#はじめに
Google Cloud Vision APIによる文字認識(OCR)は写真のファイルサイズを小さくすることで、スループットを改善できます。
[ベスト プラクティス | Cloud Vision API | Google Cloud](https://cloud.google.com/vision/docs/best-practices?hl=ja)には文字認識の推奨画像サイズは1024 x 768と記載されていますが、iPhoneのカメラで撮影した画像は推奨サイズよりも大きくなってしまいます。画像サイズを縮小することでどれだけスループットが改善されるのか気になるところです。

そこで、iPhoneで撮ったそのままの画像でOCRする場合と推奨サイズにリサイズしてOCRする場合、**応答時間はどれだけ短縮されるのか**、**文字認識精度は変わらないのか**を検証します。

---
#環境

Python 3.7.2
撮影：iPhone8

---
#検証に用いる画像
検証に用いるのはiPhone8で撮影した2018-2019YONEXスノーボードのカタログ画像です。
![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410068/a6f9c791-26c4-8cb2-d68b-4a268975db08.png)

出典：JSBA YEARBOOK 2019 http://www.srpi.co.jp/jsbayearbook2019/html5.html#page=1

---

#検証用プログラム
推奨サイズにリサイズしてOCRするプログラムです。OCRの出力結果と経過時間が表示されます。

```python
#coding:utf-8
import base64
import json
from requests import Request, Session
from io import BytesIO
from PIL import Image
import time

#PILで開いた画像をbase64形式に変換
def pil_image_to_base64(pil_image):
    buffered = BytesIO()
    pil_image.save(buffered, format="PNG")
    str_encode_file = base64.b64encode(buffered.getvalue()).decode("utf-8")
    return str_encode_file

#PILで開いた画像をCloud Vision APIに投げる
def recognize_image(pil_image):
        str_encode_file = pil_image_to_base64(pil_image)
        str_url = "https://vision.googleapis.com/v1/images:annotate?key="
        str_api_key = "Key"
        str_headers = {'Content-Type': 'application/json'}
        str_json_data = {
            'requests': [
                {
                    'image': {
                        'content': str_encode_file
                    },
                    'features': [
                        {
                            'type': "TEXT_DETECTION",
                            'maxResults': 10
                        }
                    ]
                }
            ]
        }

        obj_session = Session()
        obj_request = Request("POST",
                              str_url + str_api_key,
                              data=json.dumps(str_json_data),
                              headers=str_headers
                              )
        obj_prepped = obj_session.prepare_request(obj_request)
        obj_response = obj_session.send(obj_prepped,
                                        verify=True,
                                        timeout=60
                                        )

        if obj_response.status_code == 200:
            text = get_fullTextAnnotation(obj_response.text)
            return text
        else:
            return "error"

#返ってきたjsonデータの"fullTextAnnotation"部分のテキストを抽出
def get_fullTextAnnotation(json_data):
    text_dict = json.loads(json_data)
    try:
        text = text_dict["responses"][0]["fullTextAnnotation"]["text"]
        return text
    except:
        print(None)
        return None

if __name__ == '__main__':
    start = time.time()
    img_path = "./test.png"
    img = Image.open(img_path)
    width, height = img.size
    #推奨画像サイズにリサイズ
    coefficient = 1024 / width
    img_resize = img.resize((int(img.width*coefficient), int(img.height*coefficient)))
    print(recognize_image(img_resize))
    elapsed_time = time.time() - start
    print(elapsed_time)
```

---
#結果
##応答時間
| 元画像(4032x3024)      |       推奨サイズ(1024x780) |
|:-----------------:|:------------------:|
| 1回目：12.20秒           |              1回目：3.65秒 |
| 2回目：12.48秒           |         2回目：4.07秒    | 
| 3回目：10.74秒    |           3回目：3.57秒 |
| 4回目：11.23秒           |         4回目：3.48秒    | 
| 5回目：10.24秒    |           5回目：3.20秒 |
##文字認識精度
どちらも以下の結果になりました。ちゃんと文字認識できています。

「世界初、
全身カーボン。」
のキャッチコピーを掲げ、1995年にスノーボードに参入した
YONEX。生産の拠点を新潟の自社工場に置き、モノ作りに熱い情熱を持った熟練の技術
者達の徹底した製造·品質管理の元で設計に完壁さが求められるデリケートな素材「カーボ
ン」を自由自在にコントロールしている。MADE IN JAPANに拘り高品質で独自の、真似の
できない革新的なスノーボードを生み出し、トップライダー達がその技術を証明している。
REV®
SMOOTH
¥98,000
★サイズ:150,
153, 156, 159
ヨネックス史上最軽
量のスウィングウェイ
トを誇る新構造「ス
トンプテック3.0」を
ベースに、反発力と
衝撃吸収性に優れる
「ナノメトリックDR」
を採用。ハイエアと
高回転スピンをアシス
トするトップコンペティ
ションモデル。
¥88,000
★サイズ:
142,146, 150,
154, 158
新構造「ストンプテッ
ク3.0」をベースに、
強度·しなやかさ·
衝撃吸収性に優れる
「ナノメトリックXT」
パーク、
を採用。
バイプだけでなく、
様々なシーンで本領
を発揮するヨネックス
を代表するオールラ
ウンドモデル。

---

#まとめ
推奨サイズに縮小しても文字認識精度は変わらず、応答時間は約８秒短縮しました。
Google Cloud Vision APIは高速かつ高精度で文字認識できることが分かりました。
因みに**推奨サイズより縮小した場合、応答時間は短縮せず文字認識精度は低下しました**。

---

#参考文献
[PythonからGoogle Cloud Vision APIを使ってみた。](https://www.g104robo.com/entry/google-cloud-vision-api)
[iPhoneのカメラスペック(写真サイズ、解像度、画素数)まとめ](https://zinsoku.com/iphone-camera-spec/)