極楽とんぼのロボット製作記

情報工学系大学院生がロボットとその周辺技術や身の回りの出来事について紹介するブログ

PythonからGoogle Cloud Vision APIを使ってみた。

GoogleのCloud Vision API使ってみましたが思ったよりも良い精度でした。Pythonを使ったrequestの方法と出力結果のjsonデータを見るためのjson viewerを紹介します。

Google Cloud Vision API の使い方

API keyの取得

まずはCloud Vision APIを使うためのAPI keyを取得します。 以下にアクセスします。 console.cloud.google.com f:id:gokuraku104robot:20180728173321p:plain:w500

「vision」と検索してCloud Vision APIを選択します。 f:id:gokuraku104robot:20180728173357p:plain:w500

「有効」ボタンを押します。有効ボタンが押せない場合はGoogle Cloud Platformの無料トライアルの登録がまだなので、右上の「無料トライアルに登録」ボタンから登録します。 f:id:gokuraku104robot:20180728173649p:plain:w300

Cloud Vision APIを有効にできたら、「管理」を押します。 f:id:gokuraku104robot:20180728174018p:plain:w500

「認証情報」を押します。 f:id:gokuraku104robot:20180728174254p:plain:w500

「認証情報を作成」をクリックしてAPI keyを作成します。 f:id:gokuraku104robot:20180728174634p:plain:w500

API にrequestするプログラム

API keyを取得できたら、Cloud Vision APIにrequestするプログラムを作成します。 str_api_keyにAPI keyを入力してください。 Cloud Vision APIは画像をbase64形式にエンコードする必要があります(pil_image_to_base64(pil_image))。 エンコードした画像、API keyをrequestsでGoogle Cloud Platformに投げます。 認識に成功するとjsonデータが送られてきます。出力されたjsonデータはjson.loads(json_data)で辞書型として格納できます。

import base64
import json
from requests import Request, Session
from io import BytesIO
from PIL import Image

#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:
            with open('data.json', 'w') as outfile:
                json.dump(obj_response.json(), outfile)
                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__':
    image_path = "./test.png"
    pil_image = Image.open(image_path)
    print(recognize_image(pil_image))

f:id:gokuraku104robot:20180729112342p:plain:w300
入力した画像

出力として以下のようなjsonデータが出力されます。長過ぎるので途中を省略します。

{"responses": [{"textAnnotations": [{"locale": "ja", "description": .... "text": "Bellmart Kiosk\n\u9818\u53ce\u66f8\n\u30d9\u30eb\u30de\u30fc\u30c8\u516b\u91cd\u6d32\u5357\nTEL: 03-3281-6388\n2018\u5e747\u670825\u65e5(\u6c34) 14:59 No:0002\n4901777300446\n\u4f0a\u53f3\u885b\u9580\n#151\n\u5c0f\u8a08\n\u5185\u7a0e\u5bfe\u8c61\u984d\n\u5185\u7a0e\n\u5408\u8a08\n\u00a5151\n\u00a5151\n#11\n\u00a5151\n8\u00b700%\n8.00%\n\u4ea4\u901a\u7cfbIC\u652f\u6255\n\u00a5151\n#11)\n(\u6d88\u8cbb\u7a0e\u7b49\n250\n\u5229\u7528\u65e5\u6642 2018/07/25 14:59:47\n\u4ea4\u901a\u7cfbIC\u30ab\u30fc\u30c8\u3001\u652f\u6255\n\u4ea4\u901a\u7cfbIC\u30ab\u30fc\u30c8\u3001\u6b8b\u984d\n(\u30ab\u30fc\u30c8\u3001\u756a\u53f7: JE 5401)\n#151\n\u00a52\u3001716\n\u53d6\u5f15No7137\n1\u70b9\u8cb7\n"}}]}

このjsonデータ内のfullTextAnnotationのtext部分に全ての認識された文字列が格納されています。内容は以下のとおりです。

Bellmart Kiosk
領収書
ベルマート八重洲南
TEL: 03-3281-6388
2018年7月25日(水) 14:59 No:0002
4901777300446
伊右衛門
#151
小計
内税対象額
内税
合計
¥151
¥151
#11
¥151
8·00%
8.00%
交通系IC支払
¥151
#11)
(消費税等
250
利用日時 2018/07/25 14:59:47
交通系ICカート、支払
交通系ICカート、残額
(カート、番号: JE 5401)
#151
¥2、716
取引No7137
1点買

おすすめjson viewer

出力結果のjsonデータですが、非常に見づらいためjson viewerを使用することをおすすめします。 おすすめはjsoneditoronlineです。左側にjsonデータを入れて右矢印をクリックするとjsonを階層構造で確認することができます。辞書型でアクセスするときにも参考になります。 jsoneditoronline.org

f:id:gokuraku104robot:20180729113949p:plain:w500

参考サイト
凄すぎ!Google Cloud Vision APIをつかって簡単高精度にOCR – Arehamahoudarouka
機械学習×Webアプリ診断:Cloud Vision APIでCAPTCHAを認識する